def draw_Cartesian(self):#vertices): ob = bpy.context.scene.objects.active.location rgn = bpy.context.region rv3d = bpy.context.space_data.region_3d #bgl.glClear() bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(4) bgl.glBegin(bgl.GL_LINE_STRIP) v3d = Vector((0, 0, 0)) v2d = location_3d_to_region_2d(rgn, rv3d, v3d) bgl.glVertex2f(*v2d) bgl.glColor4f(100, 0.0, 0.0, 1) v3d = mathutils.Vector((ob.x,0,0)) v2d = location_3d_to_region_2d(rgn, rv3d, v3d) bgl.glVertex2f(*v2d) bgl.glColor4f(0, 100.0, 0.0, 1) v3d = mathutils.Vector((ob.x,ob.y,0)) v2d = location_3d_to_region_2d(rgn, rv3d, v3d) bgl.glVertex2f(*v2d) bgl.glColor4f(0, 0.0, 100.0, 1) v3d = mathutils.Vector((ob.x,ob.y,ob.z)) v2d = location_3d_to_region_2d(rgn, rv3d, v3d) bgl.glVertex2f(*v2d) bgl.glEnd() bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(1, 1, 1, 1) self.draw_value(Vector((ob.x/2,0,0)), str(round(ob.x, 2))) self.draw_value(Vector((ob.x, ob.y/2, 0)), str(round(ob.y, 2))) self.draw_value(Vector((ob.x, ob.y, ob.z/2)), str(round(ob.z, 2)))
def ready_tool(self, eventd, tool_fn): rgn = eventd['context'].region r3d = eventd['context'].space_data.region_3d mx,my = eventd['mouse'] if self.act_gvert: loc = self.act_gvert.position cx,cy = location_3d_to_region_2d(rgn, r3d, loc) elif self.act_gedge: loc = (self.act_gedge.gvert0.position + self.act_gedge.gvert3.position) / 2.0 cx,cy = location_3d_to_region_2d(rgn, r3d, loc) else: cx,cy = mx-100,my rad = math.sqrt((mx-cx)**2 + (my-cy)**2) self.action_center = (cx,cy) self.mode_start = (mx,my) self.action_radius = rad self.mode_radius = rad self.prev_pos = (mx,my) # spc = bpy.data.window_managers['WinMan'].windows[0].screen.areas[4].spaces[0] # r3d = spc.region_3d vrot = r3d.view_rotation self.tool_x = (vrot * Vector((1,0,0))).normalized() self.tool_y = (vrot * Vector((0,1,0))).normalized() self.tool_rot = 0.0 self.tool_fn = tool_fn self.tool_fn('init', eventd)
def display_line_between_two_points(region, rv3d, p1_3d, p2_3d): bgl.glEnable(bgl.GL_BLEND) p1_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, p1_3d) p2_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, p2_3d) if p1_2d is None: p1_2d = (0.0, 0.0) p2_2d = (0.0, 0.0) col_line_main = addon_settings_graph()['col_line_main'] col_line_shadow = addon_settings_graph()['col_line_shadow'] bgl.glColor4f(*col_line_shadow) bgl.glLineWidth(1.4) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f((p1_2d[0]-1),(p1_2d[1]-1)) bgl.glVertex2f((p2_2d[0]-1),(p2_2d[1]-1)) bgl.glEnd() bgl.glColor4f(*col_line_main) bgl.glLineWidth(1.4) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*p1_2d) bgl.glVertex2f(*p2_2d) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND)
def draw_curve_2d(curves, active_cur, context): region = context.region rv3d = context.region_data curve_settings = context.scene.mi_settings # coord = event.mouse_region_x, event.mouse_region_y for curve in curves: for cu_point in curve.curve_points: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.position) if point_pos_2d: p_col = col_man.cur_point_base if curve.closed is True: if curve.curve_points.index(cu_point) == 0: p_col = col_man.cur_point_closed_start elif curve.curve_points.index(cu_point) == len(curve.curve_points) - 1: p_col = col_man.cur_point_closed_end if cu_point.select: p_col = col_man.cur_point_selected if cu_point.point_id == curve.active_point and curve is active_cur: p_col = col_man.cur_point_active c_widget.draw_2d_point(point_pos_2d.x, point_pos_2d.y, 6, p_col) # Handlers if curve_settings.draw_handlers: #if curve.curve_points.index(cu_point) < len(curve.curve_points)-1: if cu_point.handle1: handle_1_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle1) if handle_1_pos_2d: c_widget.draw_2d_point(handle_1_pos_2d.x, handle_1_pos_2d.y, 3, col_man.cur_handle_1_base) #if curve.curve_points.index(cu_point) > 0: if cu_point.handle2: handle_2_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle2) if handle_2_pos_2d: c_widget.draw_2d_point(handle_2_pos_2d.x, handle_2_pos_2d.y, 3, col_man.cur_handle_2_base)
def draw_curve_points_2d(curve, context, curve_settings): region = context.region rv3d = context.region_data curve_settings = context.scene.mi_settings for cu_point in curve.curve_points: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.position) if point_pos_2d: p_col = col_man.cur_point_base if curve.closed is True: if curve.curve_points.index(cu_point) == 0: p_col = col_man.cur_point_closed_start elif curve.curve_points.index(cu_point) == len(curve.curve_points) - 1: p_col = col_man.cur_point_closed_end if cu_point.select: p_col = col_man.cur_point_selected if cu_point.point_id == curve.active_point: p_col = col_man.cur_point_active draw_point_2d(point_pos_2d, 6, p_col) # Handlers if curve_settings.draw_handlers: #if curve.curve_points.index(cu_point) < len(curve.curve_points)-1: if cu_point.handle1: handle_1_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle1) if handle_1_pos_2d: draw_point_2d(handle_1_pos_2d, 3, col_man.cur_handle_1_base) #if curve.curve_points.index(cu_point) > 0: if cu_point.handle2: handle_2_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle2) if handle_2_pos_2d: draw_point_2d(handle_2_pos_2d, 3, col_man.cur_handle_2_base)
def draw_curve_2d(curves, context): region = context.region rv3d = context.region_data curve_settings = context.scene.mi_curve_settings # coord = event.mouse_region_x, event.mouse_region_y for curve in curves: for cu_point in curve.curve_points: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.position) p_col = (0.5,0.8,1.0,1.0) if cu_point.select: p_col = (0.9,0.5,0.1,1.0) if cu_point.point_id == curve.active_point: p_col = (0.9,0.7,0.3,1.0) mi_draw_2d_point(point_pos_2d.x, point_pos_2d.y, 6, p_col) # Handlers if curve_settings.draw_handlers: #if curve.curve_points.index(cu_point) < len(curve.curve_points)-1: if cu_point.handle1: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle1) mi_draw_2d_point(point_pos_2d.x, point_pos_2d.y, 3, (0.0,0.5,1.0,0.7)) #if curve.curve_points.index(cu_point) > 0: if cu_point.handle2: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle2) mi_draw_2d_point(point_pos_2d.x, point_pos_2d.y, 3, (1.0,0.5,0.0,0.7))
def __find_uv(self, context): bm = bmesh.from_edit_mesh(context.object.data) topology_dict = [] first = True diff = 0 uvs = [] active_uv = bm.loops.layers.uv.active for fidx, f in enumerate(bm.faces): for vidx, v in enumerate(f.verts): if v.select: uvs.append(f.loops[vidx][active_uv].uv.copy()) topology_dict.append([fidx, vidx]) if first: v1 = v.link_loops[0].vert.co sv1 = view3d_utils.location_3d_to_region_2d( context.region, context.space_data.region_3d, v1) v2 = v.link_loops[0].link_loop_next.vert.co sv2 = view3d_utils.location_3d_to_region_2d( context.region, context.space_data.region_3d, v2) vres = sv2 - sv1 va = vres.angle(Vector((0.0, 1.0))) uv1 = v.link_loops[0][active_uv].uv uv2 = v.link_loops[0].link_loop_next[active_uv].uv uvres = uv2 - uv1 uva = uvres.angle(Vector((0.0,1.0))) diff = uva - va first = False return topology_dict, uvs
def draw(self,context, settings): ''' setings are the addon preferences for contour tools ''' debug = settings.debug #settings = context.user_preferences.addons['contour_tools'].preferences #this should be moved to only happen if the view changes :-/ I'ts only #a few hundred calcs even with a lot of lines. Waste not want not. if self.head.world_position: self.head.screen_from_world(context) if self.tail.world_position: self.tail.screen_from_world(context) if self.plane_tan.world_position: self.plane_tan.screen_from_world(context) #draw connecting line points = [(self.head.x,self.head.y),(self.tail.x,self.tail.y)] if settings.show_edges: contour_utilities.draw_polyline_from_points(context, points, (0,.2,1,1), settings.line_thick, "GL_LINE_STIPPLE") #draw the two handles contour_utilities.draw_points(context, points, self.head.color, settings.handle_size) #draw the current plane point and the handle to change plane orientation if self.plane_pt: point1 = location_3d_to_region_2d(context.region, context.space_data.region_3d, self.plane_pt) point2 = (self.plane_tan.x, self.plane_tan.y) if settings.show_edges: contour_utilities.draw_polyline_from_points(context, [point1,point2], (0,.2,1,1), settings.line_thick, "GL_LINE_STIPPLE") contour_utilities.draw_points(context, [point2], self.plane_tan.color, settings.handle_size) contour_utilities.draw_points(context, [point1], self.head.color, settings.handle_size) #draw the raw contour vertices if (self.verts and self.verts_simple == []) or (debug > 0 and settings.show_verts): contour_utilities.draw_3d_points(context, self.verts, (0,1,.2,1), settings.raw_vert_size) #draw the simplified contour vertices and edges (rings) if self.verts_simple: points = self.verts_simple.copy() if 0 in self.eds[-1]: points.append(self.verts_simple[0]) if settings.show_ring_edges: contour_utilities.draw_polyline_from_3dpoints(context, points, (0,1,.2,1), settings.line_thick,"GL_LINE_STIPPLE") contour_utilities.draw_3d_points(context, self.verts_simple, (0,.2,1,1), settings.vert_size) if debug: if settings.vert_inds: for i, point in enumerate(self.verts): loc = location_3d_to_region_2d(context.region, context.space_data.region_3d, point) blf.position(0, loc[0], loc[1], 0) blf.draw(0, str(i)) if settings.simple_vert_inds: for i, point in enumerate(self.verts_simple): loc = location_3d_to_region_2d(context.region, context.space_data.region_3d, point) blf.position(0, loc[0], loc[1], 0) blf.draw(0, str(i))
def modal(self, context, event): min_dist = 10 ob = context.active_object region = context.region region_3d = context.space_data.region_3d found = False dest_e = None if event.type == 'MOUSEMOVE': mouse_pos = mathutils.Vector((event.mouse_region_x, event.mouse_region_y)) print(mouse_pos) for elist in self.edges: for e in elist: v1 = e.verts[0] v2 = e.verts[1] world_v1 = ob.matrix_world * v1.co.copy() world_v2 = ob.matrix_world * v2.co.copy() screen_v1 = view3d_utils.location_3d_to_region_2d(region, region_3d, world_v1) screen_v2 = view3d_utils.location_3d_to_region_2d(region, region_3d, world_v2) dir = mathutils.Vector(screen_v1 - screen_v2) pdist = mathutils.Vector(mouse_pos - screen_v1) dist = pdist.cross(dir) / dir.length if dist < min_dist: min_dist = dist dest_e = e found = True if found: #handle the loop sel here for elist in self.edges: for e in elist: e.select = False e_set = [] loop_dir = self.get_loop_dir(self.is_loop, dest_e) walker(self.edge, loop_dir, e_set, dest_e) for e in e_set: e.select = True bpy.data.meshes[context.object.name].update() elif event.type == 'LEFTMOUSE': bpy.data.meshes[context.object.name].update() return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: bpy.data.meshes[context.object.name].update() return {'CANCELLED'} return {'RUNNING_MODAL'}
def get_fac_from_view_loc_plane(region, rv3d, rmin, centerloc, q): # writing the dots for circle at center of scene: radius = 1 ang = 0.0 circle = [(0.0 ,0.0 ,0.0)] while ang < 360.0: circle.append(((cos(radians(ang)) * radius), (sin(radians(ang)) * radius), (0.0))) ang += 10 circle.append(((cos(radians(0.0)) * radius), (sin(radians(0.0)) * radius), (0.0))) # rotating and translating the circle to user picked angle and place: circle = rotate_graphic(circle, q) circle = translate_graphic(circle, centerloc) rmax = 1 for i, co in enumerate(circle): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) circle[i] = co for i in range(1, 18): r = (circle[0] - circle[i]).length r1 = (circle[0] - circle[i + 18]).length #if (r + r1) > rmax and abs(r - r1) < min(r, r1)/5: rmax = (r+r1)/2 #if (r + r1) > rmax and abs(r - r1) < min(r, r1)/10: rmax = r + r1 if (r + r1) > rmax and (r + r1) / 2 < rmin: rmax = (r + r1) elif (r + r1) > rmax and (r + r1) / 2 >= rmin: rmax = (r + r1) * rmin / (((r + r1) / 2)- ((r + r1) / 2) - rmin) rmax = abs(rmax) circle[i] = co #np_print('rmin', rmin) #np_print('rmax', rmax) fac = (rmin * 2) / rmax return fac
def update(p3d, d): if d >= 1.0: return p3d p2d = location_3d_to_region_2d(region, r3d, p3d) p2d += dv * (1.0-d) hit = common_utilities.ray_cast_region2d_bvh(region, r3d, p2d, mesh_cache['bvh'],self.mx, settings)[1] if hit[2] == None: return p3d return mx * hit[0]
def draw_polyline_from_3dpoints(context, points_3d, color, thickness, LINE_TYPE): ''' a simple way to draw a line slow...becuase it must convert to screen every time but allows you to pan and zoom around args: points_3d: a list of tuples representing x,y SCREEN coordinate eg [(10,30),(11,31),...] color: tuple (r,g,b,a) thickness: integer? maybe a float LINE_TYPE: eg...bgl.GL_LINE_STIPPLE or ''' points = [location_3d_to_region_2d(context.region, context.space_data.region_3d, loc) for loc in points_3d] if LINE_TYPE == "GL_LINE_STIPPLE": bgl.glLineStipple(4, 0x5555) #play with this later bgl.glEnable(bgl.GL_LINE_STIPPLE) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(*color) bgl.glLineWidth(thickness) bgl.glBegin(bgl.GL_LINE_STRIP) for coord in points: bgl.glVertex2f(*coord) bgl.glEnd() if LINE_TYPE == "GL_LINE_STIPPLE": bgl.glDisable(bgl.GL_LINE_STIPPLE) bgl.glEnable(bgl.GL_BLEND) # back to uninterupted lines bgl.glLineWidth(1) return
def getscreencoords(self, vec, reg, rv3d): # calculate screencoords of given Vector vec.rotate(self.selobj.matrix_world) vec.rotate(self.selobj.matrix_world) vec = vec * self.selobj.matrix_world + self.selobj.matrix_world.to_translation() return location_3d_to_region_2d(reg, rv3d, vec)
def project(self, pos, align=False): # 0,0 means region's bottom left corner region = self.region rv3d = self.region_data xy = location_3d_to_region_2d(region, rv3d, pos.copy()) if align: xy = snap_pixel_vector(xy) return xy
def draw_3d_points_and_index(context, points, color, size): ''' draw a bunch of dots args: points: a list of tuples representing x,y SCREEN coordinate eg [(10,30),(11,31),...] color: tuple (r,g,b,a) size: integer? maybe a float ''' points_2d = [location_3d_to_region_2d(context.region, context.space_data.region_3d, loc) for loc in points] bgl.glColor4f(*color) bgl.glPointSize(size) bgl.glBegin(bgl.GL_POINTS) for coord in points_2d: #TODO: Debug this problem....perhaps loc_3d is returning points off of the screen. if coord: bgl.glVertex2f(*coord) else: continue bgl.glEnd() blf.size(0, 14, 72) for i, coord in enumerate(points_2d): blf.position(0,coord[0]+3, coord[1]+3, 0) blf.draw(0,str(i)) return
def __render(self, context): prefs = context.user_preferences.addons[__name__].preferences region, space = ShowObjectName.__get_region_space( context, 'VIEW_3D', 'WINDOW', 'VIEW_3D' ) if (region is None) or (space is None): return # オブジェクトの位置にオブジェクト名を表示 objs = [o for o in bpy.data.objects] # オブジェクトの位置座標(3D座標)をリージョン座標(2D座標)に変換 locs_on_screen = [ view3d_utils.location_3d_to_region_2d( region, space.region_3d, o.location ) for o in objs ] blf.shadow(0, 3, 0.1, 0.1, 0.1, 1.0) blf.shadow_offset(0, 1, -1) blf.enable(0, blf.SHADOW) for obj, loc in zip(objs, locs_on_screen): # 表示範囲外なら表示しない if loc is not None: ShowObjectName.__render_message( prefs.font_size_2, loc.x, loc.y, obj.name ) blf.disable(0, blf.SHADOW) # マウスカーソルの位置に向けて発したレイと交差するオブジェクト名を表示 blf.shadow(0, 3, 0.0, 1.0, 0.0, 0.5) blf.shadow_offset(0, 2, -2) blf.enable(0, blf.SHADOW) ShowObjectName.__render_message( prefs.font_size_1, prefs.left_top[0], region.height - prefs.left_top[1], "Intersect" ) blf.disable(0, blf.SHADOW) # ray_castが可能なオブジェクトモード時のみ表示 if context.mode == 'OBJECT': for i, o in enumerate(self.__intersected_objs): ShowObjectName.__render_message( int(prefs.font_size_1 * 0.8), prefs.left_top[0], (region.height - prefs.left_top[1] - int(prefs.font_size_1 * 1.3) - i * int(prefs.font_size_1 * 0.9)), o.name ) else: ShowObjectName.__render_message( int(prefs.font_size_1 * 0.8), prefs.left_top[0], (region.height - prefs.left_top[1] - int(prefs.font_size_1 * 1.3)), "Objectモード以外では利用できません" )
def calculate_projection(self, area): """Calculates 2D projection for given 3D view. """ if self._debug: print("calculating 2D projection") if area.type != 'VIEW_3D': raise Exception("wrong area type, no 3d view info for projection") if not self._is_3d: return region = space = None for region in area.regions: if region.type == 'WINDOW': break space = area.spaces[0] for sample in self._samples[self._proj_index + 1: ]: sample._proj = view3d_utils.location_3d_to_region_2d(region, space.region_3d, sample._loc * self._proj_scale) self._proj_index = len(self._samples) - 1 self._is_2d = True
def input_poll(self, context, event): if not PerformTimeOperator.input_poll(self, context, event): return False if self._target_path.arclength_3d < 0.001: return False target = self._target_path.target target_bone = self._target_path.target_bone if target_bone: bmode = self._target_path.props.bone_mode if bmode == 'head': target_3d = target.matrix_world * target_bone.head elif bmode == 'tail': target_3d = target.matrix_world * target_bone.tail elif bmode == "middle": target_3d = target.matrix_world * target_bone.tail.lerp(target_bone.head, 0.5) else: target_3d = target.matrix_world[3].to_3d() target_2d = view3d_utils.location_3d_to_region_2d(context.region, \ context.space_data.region_3d, \ target_3d) dist = (Vector((event.mouse_region_x, event.mouse_region_y)) - target_2d).length if dist < self.props.selection_radius: return True return False
def __stroke_init(self, context, _): sc = context.scene self.__initial_mco = self.current_mco # get influenced UV obj = context.active_object world_mat = obj.matrix_world bm = bmesh.from_edit_mesh(obj.data) uv_layer = bm.loops.layers.uv.verify() _, region, space = common.get_space('VIEW_3D', 'WINDOW', 'VIEW_3D') self.__loop_info = [] for f in bm.faces: if not f.select: continue for i, l in enumerate(f.loops): loc_2d = view3d_utils.location_3d_to_region_2d( region, space.region_3d, compat.matmul(world_mat, l.vert.co)) diff = loc_2d - self.__initial_mco if diff.length < sc.muv_uv_sculpt_radius: info = { "face_idx": f.index, "loop_idx": i, "initial_vco": l.vert.co.copy(), "initial_vco_2d": loc_2d, "initial_uv": l[uv_layer].uv.copy(), "strength": _get_strength( diff.length, sc.muv_uv_sculpt_radius, sc.muv_uv_sculpt_strength) } self.__loop_info.append(info)
def Point_to_Ray(self, xyz:Point, min_dist=0, max_dist_offset=0): xy = location_3d_to_region_2d(self.actions.region, self.actions.r3d, xyz) if not xy: return None o = self.Point2D_to_Origin(xy) #return Ray.from_segment(o, xyz) d = self.Point2D_to_Vec(xy) dist = (o - xyz).length return Ray(o, d, min_dist=min_dist, max_dist=dist+max_dist_offset)
def draw_surf_2d(surfs, active_surf, context): region = context.region rv3d = context.region_data curve_settings = context.scene.mi_curve_settings # coord = event.mouse_region_x, event.mouse_region_y for surf in surfs: # draw loops center if surf.main_loop_center: surf_center_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, surf.main_loop_center) if surf_center_2d: if surf is active_surf: mi_draw_2d_point(surf_center_2d.x, surf_center_2d.y, 6, (0.7,0.75,0.95,1.0)) else: mi_draw_2d_point(surf_center_2d.x, surf_center_2d.y, 6, (0.5,0.5,0.8,1.0)) # draw curves points for curve in surf.all_curves: for cu_point in curve.curve_points: point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.position) if point_pos_2d: p_col = col_man.cur_point_base if curve.closed is True: if curve.curve_points.index(cu_point) == 0: p_col = col_man.cur_point_closed_start elif curve.curve_points.index(cu_point) == len(curve.curve_points) - 1: p_col = col_man.cur_point_closed_end if cu_point.select: p_col = col_man.cur_point_selected if active_surf and cu_point.point_id == curve.active_point and curve is active_surf.active_curve: p_col = col_man.cur_point_active mi_draw_2d_point(point_pos_2d.x, point_pos_2d.y, 6, p_col) # Handlers if curve_settings.draw_handlers: #if curve.curve_points.index(cu_point) < len(curve.curve_points)-1: if cu_point.handle1: handle_1_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle1) if handle_1_pos_2d: mi_draw_2d_point(handle_1_pos_2d.x, handle_1_pos_2d.y, 3, col_man.cur_handle_1_base) #if curve.curve_points.index(cu_point) > 0: if cu_point.handle2: handle_2_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, cu_point.handle2) if handle_2_pos_2d: mi_draw_2d_point(handle_2_pos_2d.x, handle_2_pos_2d.y, 3, col_man.cur_handle_2_base)
def mi_extrude_draw_2d(self, context): if self.center: rv3d = context.region_data region = context.region point_pos_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, self.center) p_col = col_man.dre_point_base c_widget.draw_2d_point(point_pos_2d.x, point_pos_2d.y, 6, p_col)
def dibuja_callback(self, context): font_id = 0 bm = bmesh.from_edit_mesh(bpy.context.object.data) for v in bm.verts: cord = location_3d_to_region_2d(context.region, context.space_data.region_3d, self.matr * v.co) blf.position(font_id, cord[0], cord[1], 0) blf.size(font_id, self.tsize, 72) blf.draw(font_id, str(v.index))
def mi_extrude_draw_2d(self, context): active_obj = context.scene.objects.active region = context.region rv3d = context.region_data point_pos_2d = view3d_utils.location_3d_to_region_2d( region, rv3d, self.extrude_points[-1].position) p_col = col_man.dre_point_base mi_draw_2d_point(point_pos_2d.x, point_pos_2d.y, 6, p_col)
def project(self, pos, align=False, coords='REGION'): region = self.region rv3d = self.region_data xy = location_3d_to_region_2d(region, rv3d, Vector(pos)) if align: xy = snap_pixel_vector(xy) return self.convert_ui_coord(xy, 'REGION', coords)
def execute(self, context): mem = View3DModeMemory() sc = context.scene try: if sc.tex_image == "None": raise TPError({'WARNING'}, "You must select texture.") for area in bpy.context.screen.areas: if area.type == 'VIEW_3D': break else: raise TPError( {'WARNING'}, "Could not find any 'VIEW_3D' areas.") for region in area.regions: if region.type == 'WINDOW': break else: raise TPError( {'WARNING'}, "Could not find any 'WINDOW' regions.") for space in area.spaces: if space.type == 'VIEW_3D': break else: raise TPError( {'WARNING'}, "Could not find any 'VIEW_3D' spaces.") # get faces to be texture projected obj = bpy.context.active_object world_mat = obj.matrix_world sel_faces = get_selected_faces(obj) # transform 3d space to screen region for f in sel_faces: for v in f.vertices: f.loc.append(view3d_utils.location_3d_to_region_2d( region, space.region_3d, world_mat * obj.data.vertices[v].co )) # transform screen region to canvas for f in sel_faces: for l in f.loc: f.loc_on_canvas.append(region_to_canvas( region, l, get_canvas(bpy.context, sc.tex_magnitude))) # project texture to object mem.change_mode('OBJECT') uv = obj.data.uv_layers[obj.data.uv_layers.active.name] tex = obj.data.uv_textures[obj.data.uv_textures.active.name] for f in sel_faces: tex.data[f.face_index].image = bpy.data.images[sc.tex_image] for l, i in zip(f.loc_on_canvas, f.indices): uv.data[i].uv = l.to_2d() except TPError as e: e.report(self) return {'CANCELLED'} return {'FINISHED'}
def draw_callback_abc(self, context): font_id = 0 scene = context.scene region = context.region rv3d = context.region_data obj_matrix_world = self.obj.matrix_world a_3d = obj_matrix_world * self.obj.data.vertices[self.snap_points[self.index].a].co b_3d = obj_matrix_world * self.obj.data.vertices[self.snap_points[self.index].b].co c_3d = obj_matrix_world * self.obj.data.vertices[self.snap_points[self.index].c].co a_2d = tuple(map(ceil, view3d_utils.location_3d_to_region_2d(region, rv3d, a_3d))) b_2d = tuple(map(ceil, view3d_utils.location_3d_to_region_2d(region, rv3d, b_3d))) c_2d = tuple(map(ceil, view3d_utils.location_3d_to_region_2d(region, rv3d, c_3d))) bgl.glColor3f(0.0, 0.0, 0.0) bgl.glPointSize(8) bgl.glBegin(bgl.GL_POINTS) for x, y in (a_2d, b_2d, c_2d): bgl.glVertex2i(x, y) bgl.glEnd() bgl.glPointSize(4) bgl.glColor3f(0.9, 0.1, 0.1) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2i(a_2d[0], a_2d[1]) bgl.glEnd() bgl.glColor3f(0.1, 0.9, 0.1) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2i(b_2d[0], b_2d[1]) bgl.glEnd() bgl.glColor3f(0.3, 0.3, 0.9) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2i(c_2d[0], c_2d[1]) bgl.glEnd() # restore opengl defaults bgl.glPointSize(1) bgl.glLineWidth(1) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def points3d_points2d(self, context, points): """ convert 3d points to 2d region pts and draw """ pts = [] region, rv3d = self.view3d_find(context) if region is not None: pts = [location_3d_to_region_2d(region, rv3d, p) for p in points] return pts
def draw_value(self, v3d, value): #ob = bpy.context.scene.objects.active.location rgn = bpy.context.region rv3d = bpy.context.space_data.region_3d #v3d = mathutils.Vector((ob.x, ob.y, ob.z/2)) v2d = location_3d_to_region_2d(rgn, rv3d, v3d) blf.size(0, 30, 72) blf.position(0,*v2d, 0) blf.draw(0, value)
def hover_geom(self,eventd): mx,my = eventd['mouse'] self.help_box.hover(mx, my) self.hov_gvert = None rgn = eventd['context'].region r3d = eventd['context'].space_data.region_3d mx,my = eventd['mouse'] for gv in self.polystrips.extension_geometry + self.polystrips.gverts: if gv.is_inner(): continue c0 = location_3d_to_region_2d(rgn, r3d, gv.corner0) c1 = location_3d_to_region_2d(rgn, r3d, gv.corner1) c2 = location_3d_to_region_2d(rgn, r3d, gv.corner2) c3 = location_3d_to_region_2d(rgn, r3d, gv.corner3) inside = point_inside_loop2d([c0,c1,c2,c3],Vector((mx,my))) if inside: self.hov_gvert = gv break print('found hover gv')
def display_geowidget(region, rv3d, fac, ro_hor, q, helploc, n, qdef, geowidget_base, geowidget_top, geowidget_rest): geowidget_cross = [(0.0, 2.1, 0.0), (0.0, 0.9, 0.0), (-2.1, 0.0, 0.0), (-0.9, 0.0, 0.0)] # drawing of geowidget - cross part: for i, co in enumerate(geowidget_cross): co = Vector(co) co = co * fac geowidget_cross[i] = co geowidget_cross = rotate_graphic(geowidget_cross, ro_hor) geowidget_cross = rotate_graphic(geowidget_cross, q) geowidget_cross = translate_graphic(geowidget_cross, helploc) col_gw_line_cross = addon_settings_graph('col_gw_line_cross') col_gw_line_base_free = addon_settings_graph('col_gw_line_base_free') col_gw_line_base_lock_x = addon_settings_graph('col_gw_line_base_lock_x') col_gw_line_base_lock_y = addon_settings_graph('col_gw_line_base_lock_y') col_gw_line_base_lock_z = addon_settings_graph('col_gw_line_base_lock_z') col_gw_line_base_lock_arb = addon_settings_graph( 'col_gw_line_base_lock_arb') col_gw_line_all = addon_settings_graph('col_gw_line_all') col_gw_fill_base_x = addon_settings_graph('col_gw_fill_base_x') col_gw_fill_base_y = addon_settings_graph('col_gw_fill_base_y') col_gw_fill_base_z = addon_settings_graph('col_gw_fill_base_z') col_gw_fill_base_arb = addon_settings_graph('col_gw_fill_base_arb') bgl.glColor4f(*col_gw_line_cross) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(geowidget_cross): if i in range( 0, 2 ): # range is always - first as is, second one one higher than last #np_print(i) co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) geowidget_cross[i] = co bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(geowidget_cross): if i in range( 2, 4 ): # range is always - first as is, second one one higher than last #np_print(i) co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) geowidget_cross[i] = co bgl.glEnd() # drawing of geowidget - base part: for i, co in enumerate(geowidget_base): co = Vector(co) co = co * fac geowidget_base[i] = co geowidget_base = rotate_graphic(geowidget_base, ro_hor) geowidget_base = rotate_graphic(geowidget_base, q) geowidget_base = translate_graphic(geowidget_base, helploc) n = n.to_tuple() n = list(n) for i, co in enumerate(n): n[i] = abs(round(co, 4)) np_print('n for color', n) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(*col_gw_line_base_free) bgl.glLineWidth(1) if qdef != None: if n[0] == 0.0 and n[1] == 0.0 and n[2] == 1.0: bgl.glColor4f(*col_gw_line_base_lock_z) elif n[0] == 1.0 and n[1] == 0.0 and n[2] == 0.0: bgl.glColor4f(*col_gw_line_base_lock_x) elif n[0] == 0.0 and n[1] == 1.0 and n[2] == 0.0: bgl.glColor4f(*col_gw_line_base_lock_y) else: bgl.glColor4f(*col_gw_line_base_lock_arb) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(geowidget_base): #np_print(i) co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) geowidget_base[i] = co bgl.glVertex2f(*geowidget_base[0]) bgl.glEnd() bgl.glColor4f(*col_gw_fill_base_arb) if n[0] == 0.0 and n[1] == 0.0 and n[2] == 1.0: bgl.glColor4f(*col_gw_fill_base_z) np_print('go_Z') elif n[0] == 1.0 and n[1] == 0.0 and n[2] == 0.0: bgl.glColor4f(*col_gw_fill_base_x) np_print('go_X') elif n[0] == 0.0 and n[1] == 1.0 and n[2] == 0.0: bgl.glColor4f(*col_gw_fill_base_y) np_print('go_Y') bgl.glBegin(bgl.GL_TRIANGLE_FAN) for co in geowidget_base: bgl.glVertex2f(*co) bgl.glEnd() # drawing of geowidget - top part: if geowidget_top != None: for i, co in enumerate(geowidget_top): co = Vector(co) co = co * fac geowidget_top[i] = co geowidget_top = rotate_graphic(geowidget_top, ro_hor) geowidget_top = rotate_graphic(geowidget_top, q) geowidget_top = translate_graphic(geowidget_top, helploc) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(*col_gw_line_all) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(geowidget_top): #np_print(i) co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) geowidget_top[i] = co bgl.glVertex2f(*geowidget_top[0]) bgl.glEnd() # drawing of geowidget - rest part: if geowidget_rest != None: for i, co in enumerate(geowidget_rest): co = Vector(co) co = co * fac geowidget_rest[i] = co geowidget_rest = rotate_graphic(geowidget_rest, ro_hor) geowidget_rest = rotate_graphic(geowidget_rest, q) geowidget_rest = translate_graphic(geowidget_rest, helploc) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(*col_gw_line_all) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(geowidget_rest): #np_print(i) co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) geowidget_rest[i] = co bgl.glVertex2f(*geowidget_rest[0]) bgl.glEnd()
def quad_from_vertex(bm, vert_sel, context, event): ob = context.active_object me = ob.data region = context.region region_3d = context.space_data.region_3d # find linked edges that are open (<2 faces connected) edges = [edge for edge in vert_sel.link_edges if len(edge.link_faces) < 2] if len(edges) < 2: return # determine which edges to use, based on mouse cursor position min_dist = False mouse_pos = mathutils.Vector([event.mouse_region_x, event.mouse_region_y]) for a, b in itertools.combinations(edges, 2): other_verts = [vert for edge in [a, b] for vert in edge.verts \ if not vert.select] mid_other = (other_verts[0].co.copy() + other_verts[1].co.copy()) \ / 2 new_pos = 2 * (mid_other - vert_sel.co.copy()) + vert_sel.co.copy() world_pos = ob.matrix_world @ new_pos screen_pos = view3d_utils.location_3d_to_region_2d(region, region_3d, world_pos) dist = (mouse_pos - screen_pos).length if not min_dist or dist < min_dist[0]: min_dist = (dist, (a, b), other_verts, new_pos) # create vertex at location mirrored in the line, connecting the open edges edges = min_dist[1] other_verts = min_dist[2] new_pos = min_dist[3] vert_new = bm.verts.new(new_pos) # normal detection flip_align = True normal_edge = edges[0] if not normal_edge.link_faces: normal_edge = edges[1] if not normal_edge.link_faces: # no connected faces, so no need to flip the face normal flip_align = False if flip_align: # there is a face to which the normal can be aligned ref_verts = [v for v in normal_edge.link_faces[0].verts] if other_verts[0] in ref_verts: va_1 = other_verts[0] va_2 = vert_sel else: va_1 = vert_sel va_2 = other_verts[1] if (va_1 == ref_verts[0] and va_2 == ref_verts[-1]) or \ (va_2 == ref_verts[0] and va_1 == ref_verts[-1]): # reference verts are at start and end of the list -> shift list ref_verts = ref_verts[1:] + [ref_verts[0]] if ref_verts.index(va_1) > ref_verts.index(va_2): # connected face has same normal direction, so don't flip flip_align = False # material index detection ref_faces = vert_sel.link_faces if not ref_faces: mat_index = False smooth = False else: mat_index = ref_faces[0].material_index smooth = ref_faces[0].smooth # create face between all 4 vertices involved verts = [other_verts[0], vert_sel, other_verts[1], vert_new] if flip_align: verts.reverse() face = bm.faces.new(verts) if mat_index: face.material_index = mat_index face.smooth = smooth # change selection vert_new.select = True vert_sel.select = False # adjust uv-map if __name__ != '__main__': addon_prefs = context.preferences.addons[__name__].preferences if addon_prefs.adjustuv: for (key, uv_layer) in bm.loops.layers.uv.items(): uv_others = {} uv_sel = None uv_new = None # get original uv coordinates for i in range(2): for loop in other_verts[i].link_loops: if loop.face.index > -1: uv_others[loop.vert.index] = loop[uv_layer].uv break if len(uv_others) == 2: mid_other = (list(uv_others.values())[0] + list(uv_others.values())[1]) / 2 for loop in vert_sel.link_loops: if loop.face.index > -1: uv_sel = loop[uv_layer].uv break if uv_sel: uv_new = 2 * (mid_other - uv_sel) + uv_sel # set uv coordinates for new loops if uv_new: for loop in face.loops: if loop.vert.index == -1: x, y = uv_new elif loop.vert.index in uv_others: x, y = uv_others[loop.vert.index] else: x, y = uv_sel loop[uv_layer].uv = (x, y) # toggle mode, to force correct drawing bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='EDIT')
def point_keymap(self, context, event): status = {'RUNNING_MODAL'} region = context.region rv3d = context.region_data if event.type in self.nav_list: # allow navigation status = {'PASS_THROUGH'} if event.type == 'MOUSEMOVE': hov_status = self._window.test_hover(self._mouse_loc) if event.type == 'N': status = {'PASS_THROUGH'} if event.type == 'G' and event.value == 'PRESS': sel_pos = self._points_container.get_selected() if event.alt: if len(sel_pos) > 0: sel_cos = self._points_container.get_selected_cos() avg_loc = average_vecs(sel_cos) self.target_emp.location = avg_loc point_normals(self, sel_pos) else: if len(sel_pos) > 0: sel_cos = self._points_container.get_selected_cos() cache_norms = [] for ind in sel_pos: po = self._points_container.points[ind] norms = [] for l_norm in po.loop_normals: norms.append(l_norm) cache_norms.append(norms) point_normals(self, sel_pos) self._window.set_status('VIEW TRANSLATION') region = bpy.context.region rv3d = bpy.context.region_data rco = view3d_utils.location_3d_to_region_2d( region, rv3d, self.target_emp.location) self._changing_po_cache.insert(0, self._mouse_loc) self._changing_po_cache.insert( 1, self.target_emp.location.copy()) self._changing_po_cache.insert(2, cache_norms) self._changing_po_cache.insert(3, rco) self.point_mode = False self.point_move = True keymap_refresh_target_move(self) if event.type == 'Z' and event.value == 'PRESS': self._x_ray_mode = not self._x_ray_mode self._window.boolean_toggle_id(51) # test selection of points/roots and hovering of buttons if event.type == 'LEFTMOUSE' and event.value == 'PRESS' and event.ctrl != True: hov_status = self._window.test_hover(self._mouse_loc) if hov_status == 'EDGE': self.resizing = True self._window.start_resize(self._mouse_loc) elif hov_status == 'PANEL_HEADER' or hov_status == 'SUBPANEL_HEADER': self.pre_moving = True self.pre_moving_no_coll = False self._window.start_move(self._mouse_loc) elif hov_status == 'PANEL' or hov_status == 'SUBPANEL': self.pre_moving = True self.pre_moving_no_coll = True self._window.start_move(self._mouse_loc) elif hov_status != None: self.pre_item_click = True self._stored_mouse = [self._mouse_loc[0], self._mouse_loc[1]] status = {'RUNNING_MODAL'} return status
def modal(self, context, event): context.area.tag_redraw() user_preferences = context.user_preferences addon_prefs = user_preferences.addons[__package__].preferences lin_def_settings = context.scene.mi_ldeformer_settings region = context.region rv3d = context.region_data m_coords = event.mouse_region_x, event.mouse_region_y active_obj = context.scene.objects.active # bm = bmesh.from_edit_mesh(active_obj.data) # update check if lin_def_settings.manual_update is True: if event.type == 'U': if event.value == 'PRESS': self.do_update = True else: self.do_update = False else: self.do_update = True # tooltip tooltip_text = None if lin_def_settings.manual_update is True and self.tool_mode not in { 'IDLE', 'MOVE_POINT' }: tooltip_text = "Press U key to udate!" else: tooltip_text = "I:Invert, Z:Z-Constraint, X:X-Constraint, S:Scale, Shift-S:ScaleForward, G:Move, R:Rotate, B:Bend, Shift-B:BendSpiral, T:Tape, Shift-T:Twist, Ctrl+Z:Undo, Ctrl+Shift+Z:Redo" context.area.header_text_set(tooltip_text) keys_pass = mi_inputs.get_input_pass(mi_inputs.pass_keys, addon_prefs.key_inputs, event) # key pressed if self.tool_mode == 'IDLE' and event.value == 'PRESS' and keys_pass is False: if event.type in {'LEFTMOUSE', 'SELECTMOUSE'}: if self.lw_tool: # pick linear widget point picked_point = l_widget.pick_lw_point( context, m_coords, self.lw_tool) if picked_point: self.deform_mouse_pos = Vector(m_coords) self.active_lw_point = picked_point self.tool_mode = 'MOVE_POINT' else: picked_point = ut_base.get_mouse_on_plane( context, self.start_work_center, None, m_coords) if picked_point: self.lw_tool = l_widget.MI_Linear_Widget() self.lw_tool.start_point = l_widget.MI_LW_Point( picked_point.copy()) self.lw_tool.middle_point = l_widget.MI_LW_Point( picked_point.copy()) self.lw_tool.end_point = l_widget.MI_LW_Point( picked_point) self.active_lw_point = self.lw_tool.end_point self.tool_mode = 'MOVE_POINT' elif event.type in {'S', 'G', 'R', 'B', 'T'}: # set tool type if event.type == 'S': if event.shift: self.tool_mode = 'SCALE_FRONT' else: self.tool_mode = 'SCALE_ALL' elif event.type == 'R': self.tool_mode = 'ROTATE_ALL' elif event.type == 'G': self.tool_mode = 'MOVE_ALL' elif event.type == 'B': if event.shift: self.tool_mode = 'BEND_SPIRAL' else: self.tool_mode = 'BEND_ALL' elif event.type == 'T': if event.shift: self.tool_mode = 'TWIST' else: self.tool_mode = 'TAPE' # get tool verts if self.tool_mode in {'SCALE_FRONT', 'TAPE'}: # do not clamp for SCALE_FRONT mode self.apply_tool_verts = l_widget.get_tool_verts_curv( self.lw_tool, self.pointsCurv, active_obj, False, True) else: self.apply_tool_verts = l_widget.get_tool_verts_curv( self.lw_tool, self.pointsCurv, active_obj, True, True) # set some settings for tools if self.tool_mode in {'SCALE_ALL', 'SCALE_FRONT', 'TAPE'}: self.deform_mouse_pos = Vector(m_coords) elif self.tool_mode == 'MOVE_ALL': mouse_pos_3d = ut_base.get_mouse_on_plane( context, self.lw_tool.start_point.position, None, m_coords) self.deform_vec_pos = mouse_pos_3d # 3d location elif self.tool_mode in { 'ROTATE_ALL', 'TWIST', 'BEND_ALL', 'BEND_SPIRAL' }: start_2d = view3d_utils.location_3d_to_region_2d( region, rv3d, self.lw_tool.start_point.position) self.deform_vec_pos = ( Vector(m_coords) - start_2d).normalized() # 2d direction self.deform_mouse_pos = 0.0 # we will use it as angle counter if self.tool_mode in {'BEND_SPIRAL', 'BEND_ALL'}: self.bend_scale_len = (Vector(m_coords) - start_2d).length #return {'RUNNING_MODAL'} elif event.type in {'Z', 'X'} and self.lw_tool: if event.type == 'Z' and event.ctrl: if event.shift: redo_history(self.h_undo, self.h_redo, active_obj) else: undo_history(self.h_undo, self.h_redo, active_obj) else: pre_verts = [p for p in self.pointsCurv] if event.type == 'X': if self.lw_tool_axis: if self.lw_tool_axis == 'X': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'X_Left', 1.0) self.lw_tool_axis = 'X_Left' elif self.lw_tool_axis == 'X_Left': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'X_Right', 1.0) ## revert direction #stp = self.lw_tool.start_point.position.copy() #self.lw_tool.start_point.position = self.lw_tool.end_point.position #self.lw_tool.end_point.position = stp self.lw_tool_axis = 'X_Right' elif self.lw_tool_axis == 'X_Right': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'X', 1.0) self.lw_tool_axis = 'X' else: l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'X', 1.0) self.lw_tool_axis = 'X' else: l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'X', 1.0) self.lw_tool_axis = 'X' else: if self.lw_tool_axis: if self.lw_tool_axis == 'Z': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'Z_Top', 1.0) self.lw_tool_axis = 'Z_Top' elif self.lw_tool_axis == 'Z_Top': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'Z_Bottom', 1.0) ## revert direction #stp = self.lw_tool.start_point.position.copy() #self.lw_tool.start_point.position = self.lw_tool.end_point.position #self.lw_tool.end_point.position = stp self.lw_tool_axis = 'Z_Bottom' elif self.lw_tool_axis == 'Z_Bottom': l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'Z', 1.0) self.lw_tool_axis = 'Z' else: l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'Z', 1.0) self.lw_tool_axis = 'Z' else: l_widget.setup_lw_tool(rv3d, self.lw_tool, active_obj, pre_verts, 'Z', 1.0) self.lw_tool_axis = 'Z' elif event.type == 'I' and self.lw_tool: start_copy = self.lw_tool.start_point.position.copy() self.lw_tool.start_point.position = self.lw_tool.end_point.position self.lw_tool.end_point.position = start_copy # TOOL WORK! if self.tool_mode == 'MOVE_POINT': if event.value == 'RELEASE': self.tool_mode = 'IDLE' return {'RUNNING_MODAL'} else: # move points new_point_pos = ut_base.get_mouse_on_plane( context, self.active_lw_point.position, None, m_coords) if self.active_lw_point.position == self.lw_tool.start_point.position or self.active_lw_point.position == self.lw_tool.end_point.position: self.active_lw_point.position = new_point_pos l_widget.update_middle_point(self.lw_tool) elif self.active_lw_point.position == self.lw_tool.middle_point.position: self.lw_tool.start_point.position += new_point_pos - self.active_lw_point.position self.lw_tool.end_point.position += new_point_pos - self.active_lw_point.position self.lw_tool.middle_point.position = new_point_pos return {'RUNNING_MODAL'} elif self.tool_mode in {'SCALE_ALL', 'SCALE_FRONT', 'TAPE'}: if event.value == 'RELEASE' and event.type in { 'LEFTMOUSE', 'SELECTMOUSE' }: # add to undo history self.h_redo.clear() pre_work_verts = [p for p in self.pointsCurv] add_history(pre_work_verts, self.h_undo) self.tool_mode = 'IDLE' elif self.do_update: # move points start_point_2d = view3d_utils.location_3d_to_region_2d( region, rv3d, self.lw_tool.start_point.position) if start_point_2d: tool_dist = (start_point_2d - self.deform_mouse_pos).length now_dist = (start_point_2d - Vector(m_coords)).length apply_value = (now_dist - tool_dist) / tool_dist if apply_value != 0.0: tool_orig = active_obj.matrix_world.inverted( ) * self.lw_tool.start_point.position tool_end = active_obj.matrix_world.inverted( ) * self.lw_tool.end_point.position tool_vec = tool_end - tool_orig tool_dir = (tool_end - tool_orig).normalized() for vert_data in self.apply_tool_verts: scale_vec = None scale_value = vert_data[1] if self.tool_mode == 'SCALE_ALL': scale_vec = (vert_data[2].resized(3) - tool_orig) elif self.tool_mode == 'SCALE_FRONT': scale_vec = (tool_end - tool_orig) else: # TAPE scale_vec = vert_data[2].resized(3) - ( tool_orig + (tool_dir * vert_data[1] * (tool_vec).length)) scale_value = min(1.0, vert_data[1]) out = vert_data[2].resized(3) + ( scale_vec * (scale_value * apply_value)) out.resize_4d() vert_data[0].co = out #bm.normal_update() # bmesh.update_edit_mesh(active_obj.data) self.do_update = False return {'RUNNING_MODAL'} elif self.tool_mode == 'MOVE_ALL': if event.value == 'RELEASE' and event.type in { 'LEFTMOUSE', 'SELECTMOUSE' }: # add to undo history self.h_redo.clear() pre_work_verts = [p for p in self.pointsCurv] add_history(pre_work_verts, self.h_undo) self.tool_mode = 'IDLE' elif self.do_update: mouse_pos_3d = ut_base.get_mouse_on_plane( context, self.lw_tool.start_point.position, None, m_coords) mouse_pos_3d = active_obj.matrix_world.inverted( ) * mouse_pos_3d start_pos = active_obj.matrix_world.inverted( ) * self.lw_tool.start_point.position orig_pos = active_obj.matrix_world.inverted( ) * self.deform_vec_pos orig_vec = orig_pos - start_pos move_vec = (mouse_pos_3d - start_pos) - orig_vec for vert_data in self.apply_tool_verts: move_value = vert_data[1] vert_data[0].co.xyz = vert_data[2] + (move_vec * move_value) #bm.normal_update() # bmesh.update_edit_mesh(active_obj.data) self.do_update = False return {'RUNNING_MODAL'} elif self.tool_mode in { 'ROTATE_ALL', 'TWIST', 'BEND_ALL', 'BEND_SPIRAL' }: if event.value == 'RELEASE' and event.type in { 'LEFTMOUSE', 'SELECTMOUSE' }: # add to undo history self.h_redo.clear() pre_work_verts = [p for p in self.pointsCurv] add_history(pre_work_verts, self.h_undo) self.tool_mode = 'IDLE' elif self.do_update: m_coords = Vector( m_coords) # convert into vector for operations start_2d = view3d_utils.location_3d_to_region_2d( region, rv3d, self.lw_tool.start_point.position) new_vec_dir = (m_coords - start_2d).normalized() rot_angle = new_vec_dir.angle(self.deform_vec_pos) start_3d = self.lw_tool.start_point.position end_3d = self.lw_tool.end_point.position if rot_angle != 0.0: # check for left or right direction to rotate vec_check_1 = Vector((new_vec_dir[0], new_vec_dir[1], 0)) vec_check_2 = Vector( (new_vec_dir[0] - self.deform_vec_pos[0], new_vec_dir[1] - self.deform_vec_pos[1], 0)) checker_side_dir = vec_check_1.cross( vec_check_2).normalized()[2] if checker_side_dir > 0.0: rot_angle = -rot_angle start_pos = self.lw_tool.start_point.position rot_dir = None if self.tool_mode == 'ROTATE_FRONT' or self.tool_mode == 'TWIST': # ROTATE_FRONT code rot_dir = (end_3d - start_3d).normalized() else: rot_dir = (rv3d.view_rotation * Vector( (0.0, 0.0, -1.0))).normalized() rot_angle += self.deform_mouse_pos # add rot angle bend_side_dir = None faloff_len = None spiral_value = 0.0 # only for BEND_SPIRAL bend_scale_value = 1.0 # only for BEND_ALL if self.tool_mode == 'BEND_ALL' or self.tool_mode == 'BEND_SPIRAL': bend_side_dir = (((end_3d - start_3d).normalized() ).cross(rot_dir)).normalized() faloff_len = end_3d - start_3d if self.tool_mode == 'BEND_SPIRAL': val_scale = None if rot_angle > 0.0: val_scale = (1.0 - ((m_coords - start_2d).length / self.bend_scale_len)) else: val_scale = (((m_coords - start_2d).length / self.bend_scale_len)) spiral_value = 1.0 - (faloff_len.length * val_scale) else: val_scale = (((m_coords - start_2d).length / self.bend_scale_len)) bend_scale_value = ((val_scale)) do_bend = False if self.tool_mode == 'BEND_ALL' or self.tool_mode == 'BEND_SPIRAL': do_bend = True for vert_data in self.apply_tool_verts: apply_value = vert_data[1] final_apply_value = rot_angle * apply_value # do rotation if final_apply_value != 0.0: rot_mat = Matrix.Rotation(final_apply_value, 3, rot_dir) vert = vert_data[0] if do_bend: vert_temp = (active_obj.matrix_world * vert_data[2].resized(3)) - ( (faloff_len) * apply_value) back_offset = ( ((faloff_len).length / (final_apply_value)) + spiral_value) * ( apply_value * bend_scale_value) vert_temp += bend_side_dir * back_offset vert.co.xyz = vert_temp.xyz else: # set original position vert.co[0] = vert_data[2][0] vert.co[1] = vert_data[2][1] vert.co[2] = vert_data[2][2] # ROTATE VERTS! if do_bend: vert.co.xyz = rot_mat * ( (vert.co.xyz) - start_pos) + start_pos back_offset = ( (faloff_len).length / (final_apply_value)) * (apply_value * bend_scale_value) vert.co.xyz = active_obj.matrix_world.inverted( ) * (vert.co.xyz - (bend_side_dir * back_offset)) else: vert.co.xyz = active_obj.matrix_world.inverted( ) * (rot_mat * ((active_obj.matrix_world * vert.co.xyz) - start_pos) + start_pos) self.deform_vec_pos = new_vec_dir self.deform_mouse_pos = rot_angle # set new angle rotation for next step #bm.normal_update() # bmesh.update_edit_mesh(active_obj.data) self.do_update = False return {'RUNNING_MODAL'} else: if event.value == 'RELEASE' and event.type in { 'LEFTMOUSE', 'SELECTMOUSE' }: self.tool_mode = 'IDLE' return {'RUNNING_MODAL'} # get keys if keys_pass is True: # allow navigation return {'PASS_THROUGH'} elif event.type in {'RIGHTMOUSE', 'ESC'}: context.space_data.show_manipulator = self.manipulator # bpy.types.SpaceView3D.draw_handler_remove(self.lin_deform_handle_3d, 'WINDOW') bpy.types.SpaceView3D.draw_handler_remove( self.lin_deform_handle_2d, 'WINDOW') context.area.header_text_set() return {'FINISHED'} return {'RUNNING_MODAL'}
def __stroke_apply(self, context, _): sc = context.scene obj = context.active_object world_mat = obj.matrix_world bm = bmesh.from_edit_mesh(obj.data) uv_layer = bm.loops.layers.uv.verify() mco = self.current_mco if sc.muv_uv_sculpt_tools == 'GRAB': for info in self.__loop_info: diff_uv = (mco - self.__initial_mco) * info["strength"] l = bm.faces[info["face_idx"]].loops[info["loop_idx"]] l[uv_layer].uv = info["initial_uv"] + diff_uv / 100.0 elif sc.muv_uv_sculpt_tools == 'PINCH': _, region, space = common.get_space_legacy('VIEW_3D', 'WINDOW', 'VIEW_3D') loop_info = [] for f in bm.faces: if not f.select: continue for i, l in enumerate(f.loops): loc_2d = view3d_utils.location_3d_to_region_2d( region, space.region_3d, world_mat * l.vert.co) diff = loc_2d - self.__initial_mco if diff.length < sc.muv_uv_sculpt_radius: info = { "face_idx": f.index, "loop_idx": i, "initial_vco": l.vert.co.copy(), "initial_vco_2d": loc_2d, "initial_uv": l[uv_layer].uv.copy(), "strength": impl.get_strength(diff.length, sc.muv_uv_sculpt_radius, sc.muv_uv_sculpt_strength) } loop_info.append(info) # mouse coordinate to UV coordinate ray_vec = view3d_utils.region_2d_to_vector_3d( region, space.region_3d, mco) ray_vec.normalize() ray_orig = view3d_utils.region_2d_to_origin_3d( region, space.region_3d, mco) ray_tgt = ray_orig + ray_vec * 1000000.0 mwi = world_mat.inverted() ray_orig_obj = mwi * ray_orig ray_tgt_obj = mwi * ray_tgt ray_dir_obj = ray_tgt_obj - ray_orig_obj ray_dir_obj.normalize() tree = BVHTree.FromBMesh(bm) loc, _, fidx, _ = tree.ray_cast(ray_orig_obj, ray_dir_obj) if not loc: return loops = [l for l in bm.faces[fidx].loops] uvs = [ Vector((l[uv_layer].uv.x, l[uv_layer].uv.y, 0.0)) for l in loops ] target_uv = barycentric_transform(loc, loops[0].vert.co, loops[1].vert.co, loops[2].vert.co, uvs[0], uvs[1], uvs[2]) target_uv = Vector((target_uv.x, target_uv.y)) # move to target UV coordinate for info in loop_info: l = bm.faces[info["face_idx"]].loops[info["loop_idx"]] if sc.muv_uv_sculpt_pinch_invert: diff_uv = (l[uv_layer].uv - target_uv) * info["strength"] else: diff_uv = (target_uv - l[uv_layer].uv) * info["strength"] l[uv_layer].uv = l[uv_layer].uv + diff_uv / 10.0 elif sc.muv_uv_sculpt_tools == 'RELAX': _, region, space = common.get_space_legacy('VIEW_3D', 'WINDOW', 'VIEW_3D') # get vertex and loop relation vert_db = {} for f in bm.faces: for l in f.loops: if l.vert in vert_db: vert_db[l.vert]["loops"].append(l) else: vert_db[l.vert] = {"loops": [l]} # get relaxation information for k in vert_db.keys(): d = vert_db[k] d["uv_sum"] = Vector((0.0, 0.0)) d["uv_count"] = 0 for l in d["loops"]: ln = l.link_loop_next lp = l.link_loop_prev d["uv_sum"] = d["uv_sum"] + ln[uv_layer].uv d["uv_sum"] = d["uv_sum"] + lp[uv_layer].uv d["uv_count"] = d["uv_count"] + 2 d["uv_p"] = d["uv_sum"] / d["uv_count"] d["uv_b"] = d["uv_p"] - d["loops"][0][uv_layer].uv for k in vert_db.keys(): d = vert_db[k] d["uv_sum_b"] = Vector((0.0, 0.0)) for l in d["loops"]: ln = l.link_loop_next lp = l.link_loop_prev dn = vert_db[ln.vert] dp = vert_db[lp.vert] d["uv_sum_b"] = d["uv_sum_b"] + dn["uv_b"] + dp["uv_b"] # apply for f in bm.faces: if not f.select: continue for i, l in enumerate(f.loops): loc_2d = view3d_utils.location_3d_to_region_2d( region, space.region_3d, world_mat * l.vert.co) diff = loc_2d - self.__initial_mco if diff.length >= sc.muv_uv_sculpt_radius: continue db = vert_db[l.vert] strength = impl.get_strength(diff.length, sc.muv_uv_sculpt_radius, sc.muv_uv_sculpt_strength) base = (1.0 - strength) * l[uv_layer].uv if sc.muv_uv_sculpt_relax_method == 'HC': t = 0.5 * (db["uv_b"] + db["uv_sum_b"] / d["uv_count"]) diff = strength * (db["uv_p"] - t) target_uv = base + diff elif sc.muv_uv_sculpt_relax_method == 'LAPLACIAN': diff = strength * db["uv_p"] target_uv = base + diff else: continue l[uv_layer].uv = target_uv bmesh.update_edit_mesh(obj.data)
def loc_3d_to_2d(region, region_3d, loc, ratio_w, ratio_h): x, y = location_3d_to_region_2d(region, region_3d, loc) return x * ratio_w, y * ratio_h
def quad_from_edge(bm, edge_sel, context, event): ob = context.active_object region = context.region region_3d = context.space_data.region_3d # find linked edges that are open (<2 faces connected) and not part of # the face the selected edge belongs to all_edges = [[edge for edge in edge_sel.verts[i].link_edges if \ len(edge.link_faces) < 2 and edge != edge_sel and \ sum([face in edge_sel.link_faces for face in edge.link_faces]) == 0] \ for i in range(2)] if not all_edges[0] or not all_edges[1]: return # determine which edges to use, based on mouse cursor position mouse_pos = mathutils.Vector([event.mouse_region_x, event.mouse_region_y]) optimal_edges = [] for edges in all_edges: min_dist = False for edge in edges: vert = [vert for vert in edge.verts if not vert.select][0] world_pos = ob.matrix_world @ vert.co.copy() screen_pos = view3d_utils.location_3d_to_region_2d(region, region_3d, world_pos) dist = (mouse_pos - screen_pos).length if not min_dist or dist < min_dist[0]: min_dist = (dist, edge, vert) optimal_edges.append(min_dist) # determine the vertices, which make up the quad v1 = edge_sel.verts[0] v2 = edge_sel.verts[1] edge_1 = optimal_edges[0][1] edge_2 = optimal_edges[1][1] v3 = optimal_edges[0][2] v4 = optimal_edges[1][2] # normal detection flip_align = True normal_edge = edge_1 if not normal_edge.link_faces: normal_edge = edge_2 if not normal_edge.link_faces: normal_edge = edge_sel if not normal_edge.link_faces: # no connected faces, so no need to flip the face normal flip_align = False if flip_align: # there is a face to which the normal can be aligned ref_verts = [v for v in normal_edge.link_faces[0].verts] if v3 in ref_verts: va_1 = v3 va_2 = v1 elif normal_edge == edge_sel: va_1 = v1 va_2 = v2 else: va_1 = v2 va_2 = v4 if (va_1 == ref_verts[0] and va_2 == ref_verts[-1]) or \ (va_2 == ref_verts[0] and va_1 == ref_verts[-1]): # reference verts are at start and end of the list -> shift list ref_verts = ref_verts[1:] + [ref_verts[0]] if ref_verts.index(va_1) > ref_verts.index(va_2): # connected face has same normal direction, so don't flip flip_align = False # material index detection ref_faces = edge_sel.link_faces if not ref_faces: ref_faces = edge_sel.verts[0].link_faces if not ref_faces: ref_faces = edge_sel.verts[1].link_faces if not ref_faces: mat_index = False smooth = False else: mat_index = ref_faces[0].material_index smooth = ref_faces[0].smooth # create quad try: if v3 == v4: # triangle (usually at end of quad-strip verts = [v3, v1, v2] else: # normal face creation verts = [v3, v1, v2, v4] if flip_align: verts.reverse() face = bm.faces.new(verts) if mat_index: face.material_index = mat_index face.smooth = smooth except: # face already exists return # change selection edge_sel.select = False for vert in edge_sel.verts: vert.select = False for edge in face.edges: if edge.index < 0: edge.select = True v3.select = True v4.select = True # adjust uv-map if __name__ != '__main__': addon_prefs = context.preferences.addons[__name__].preferences if addon_prefs.adjustuv: for (key, uv_layer) in bm.loops.layers.uv.items(): uv_ori = {} for vert in [v1, v2, v3, v4]: for loop in vert.link_loops: if loop.face.index > -1: uv_ori[loop.vert.index] = loop[uv_layer].uv if len(uv_ori) == 4 or len(uv_ori) == 3: for loop in face.loops: if loop.vert.index in uv_ori: loop[uv_layer].uv = uv_ori[loop.vert.index] # toggle mode, to force correct drawing bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='EDIT')
def main(self, context): oa = bpy.context.active_object obj = bpy.context.object me = obj.data bm = bmesh.from_edit_mesh(me) vert = [v for v in bm.verts if (v.select == True and v.hide == False)] contador = 0 for area in bpy.context.screen.areas: if area.type == 'VIEW_3D': override = bpy.context.copy() # ubicar la camara en posicion bpy.ops.view3d.snap_cursor_to_selected() viewport = area.regions[4] for v in vert: # coo in 3d space co_3d = oa.matrix_world * v.co # coo in the 3d view area (2d) co_2d = view3d_utils.location_3d_to_region_2d(viewport, area.spaces[0].region_3d, co_3d) # coo in the blender window co_2d_w = (co_2d[0] + viewport.x, co_2d[1] + viewport.y) # coo in the system screen co_2d_s = (co_2d_w[0] + bpy.context.window.x, co_2d_w[1] + bpy.context.window.y) if contador == 0: x1 = co_2d[0] y1 = co_2d[1] contador += 1 if contador == 1: x2 = co_2d[0] y2 = co_2d[1] break # mover cursor del sistema operativo a donde el v1 #depth_location = vert[1].co + Vector((0.1,0.1,0.1)) #v3 = view3d_utils.region_2d_to_location_3d(viewport, area.spaces[0].region_3d, co_2d, depth_location) v3 = view3d_utils.region_2d_to_vector_3d(viewport, area.spaces[0].region_3d, co_2d) v3 = v3 + vert[1].co normal = mathutils.geometry.normal(vert[0].co, vert[1].co, v3) bpy.ops.mesh.select_all(action='SELECT') #bpy.ops.mesh.bisect(plane_co=vert[0].co, plane_no=normal) bpy.ops.mesh.bisect( plane_co=vert[1].co, plane_no=normal, use_fill=False, clear_inner=False, clear_outer=False, threshold=0.0001, xstart=x1, xend=x2, ystart=y1, yend=y2, cursor=1002) bmesh.update_edit_mesh(me, True)
def DRAW_DisplayCage(self, context): flag = NP020PS.flag flag = 'DISPLAY' cage3d = NP020PS.cage3d cross3d = NP020PS.cross3d c3d = NP020PS.c3d region = context.region rv3d = context.region_data cage2d = copy.deepcopy(cage3d) cross2d = copy.deepcopy(cross3d) for co in cage3d.items(): #np_print(co[0]) cage2d[co[0]] = view3d_utils.location_3d_to_region_2d( region, rv3d, co[1]) for co in cross3d.items(): cross2d[co[0]] = view3d_utils.location_3d_to_region_2d( region, rv3d, co[1]) c2d = view3d_utils.location_3d_to_region_2d(region, rv3d, c3d) points = copy.deepcopy(cage2d) points.update(cross2d) # DRAWING START: bgl.glEnable(bgl.GL_BLEND) if flag == 'DISPLAY': instruct = 'select a handle' keys_aff = 'LMB - confirm, CTRL - force proportional, SHIFT - force central, TAB - apply scale / rotation' keys_nav = '' keys_neg = 'ESC - quit' if self.flag_con: mark_col = (1.0, 0.5, 0.0, 1.0) else: mark_col = (0.3, 0.6, 1.0, 1.0) # ON-SCREEN INSTRUCTIONS: display_instructions(region, rv3d, instruct, keys_aff, keys_nav, keys_neg) sensor = 60 self.mode = None co2d = mathutils.Vector(self.co2d) distmin = mathutils.Vector(co2d - c2d).length # Hover markers - detection for co in points.items(): dist = mathutils.Vector(co2d - co[1]).length if dist < distmin: distmin = dist if distmin < sensor: self.mode = co[0] self.hoverco = co[1] # Drawing the graphical representation of scale cage, calculated from selection's bound box: if self.mode == None: bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glLineWidth(1.4) else: bgl.glColor4f(1.0, 1.0, 1.0, 0.5) bgl.glLineWidth(1.0) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[0]) bgl.glVertex2f(*cage2d[1]) bgl.glVertex2f(*cage2d[2]) bgl.glVertex2f(*cage2d[3]) bgl.glVertex2f(*cage2d[0]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[4]) bgl.glVertex2f(*cage2d[5]) bgl.glVertex2f(*cage2d[6]) bgl.glVertex2f(*cage2d[7]) bgl.glVertex2f(*cage2d[4]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[0]) bgl.glVertex2f(*cage2d[4]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[1]) bgl.glVertex2f(*cage2d[5]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[2]) bgl.glVertex2f(*cage2d[6]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cage2d[3]) bgl.glVertex2f(*cage2d[7]) bgl.glEnd() bgl.glColor4f(1.0, 1.0, 1.0, 0.5) bgl.glLineWidth(1.0) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cross2d['xmin']) bgl.glVertex2f(*cross2d['xmax']) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cross2d['ymin']) bgl.glVertex2f(*cross2d['ymax']) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*cross2d['zmin']) bgl.glVertex2f(*cross2d['zmax']) bgl.glEnd() #bgl.glDepthRange(0,0) bgl.glColor4f(0.35, 0.65, 1.0, 1.0) bgl.glPointSize(9) bgl.glBegin(bgl.GL_POINTS) for [a, b] in cross2d.values(): bgl.glVertex2f(a, b) bgl.glEnd() bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glPointSize(11) bgl.glBegin(bgl.GL_POINTS) for co in cage2d.items(): if len(str(co[0])) == 1: bgl.glVertex2f(*co[1]) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) markers = {} markers[0] = (points[0], points[10], points[40], points[0], points[30], points[40], points[0], points[10], points[30]) markers[1] = (points[1], points[10], points[15], points[1], points[12], points[15], points[1], points[10], points[12]) markers[2] = (points[2], points[12], points[26], points[2], points[23], points[26], points[2], points[12], points[23]) markers[3] = (points[3], points[30], points[37], points[3], points[23], points[37], points[3], points[30], points[23]) markers[4] = (points[4], points[45], points[47], points[4], points[40], points[47], points[4], points[40], points[45]) markers[5] = (points[5], points[45], points[56], points[5], points[15], points[56], points[5], points[15], points[45]) markers[6] = (points[6], points[26], points[67], points[6], points[56], points[67], points[6], points[26], points[56]) markers[7] = (points[7], points[37], points[67], points[7], points[47], points[67], points[7], points[37], points[47]) markers['xmin'] = (points[0], points[3], points[7], points[4], points[0]) markers['xmax'] = (points[1], points[2], points[6], points[5], points[1]) markers['ymin'] = (points[0], points[1], points[5], points[4], points[0]) markers['ymax'] = (points[2], points[3], points[7], points[6], points[2]) markers['zmin'] = (points[0], points[1], points[2], points[3], points[0]) markers['zmax'] = (points[4], points[5], points[6], points[7], points[4]) pivot = {} if self.flag_cenpivot: pivot[0] = c2d pivot[1] = c2d pivot[2] = c2d pivot[3] = c2d pivot[4] = c2d pivot[5] = c2d pivot[6] = c2d pivot[7] = c2d pivot['xmin'] = c2d pivot['xmax'] = c2d pivot['ymin'] = c2d pivot['ymax'] = c2d pivot['zmin'] = c2d pivot['zmax'] = c2d else: pivot[0] = points[6] pivot[1] = points[7] pivot[2] = points[4] pivot[3] = points[5] pivot[4] = points[2] pivot[5] = points[3] pivot[6] = points[0] pivot[7] = points[1] pivot['xmin'] = points['xmax'] pivot['xmax'] = points['xmin'] pivot['ymin'] = points['ymax'] pivot['ymax'] = points['ymin'] pivot['zmin'] = points['zmax'] pivot['zmax'] = points['zmin'] np_print('self.mode = ', self.mode) fields = False field_contours = False pivots = True pivot_lines = True if fields: # Hover markers - fields bgl.glColor4f(0.65, 0.85, 1.0, 0.35) for mark in markers.items(): if mark[0] == self.mode: #if type(mark[0]) is not str: #bgl.glColor4f(1.0, 1.0, 1.0, 0.3) bgl.glBegin(bgl.GL_TRIANGLE_FAN) for x, y in mark[1]: bgl.glVertex2f(x, y) bgl.glEnd() if field_contours: # Hover markers - contours bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glLineWidth(1.2) for mark in markers.items(): if mark[0] == self.mode: if type(mark[0]) is not str: #bgl.glColor4f(0.3, 0.6, 1.0, 0.5) bgl.glColor4f(1.0, 1.0, 1.0, 0.75) bgl.glLineWidth(1.0) bgl.glBegin(bgl.GL_LINE_STRIP) for x, y in mark[1]: bgl.glVertex2f(x, y) bgl.glEnd() # Hover markers - pivot bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glColor4f(*mark_col) bgl.glPointSize(12) for p in pivot.items(): if p[0] == self.mode: if pivots: bgl.glBegin(bgl.GL_POINTS) #np_print(p[1]) bgl.glVertex2f(*p[1]) bgl.glEnd() if pivot_lines: bgl.glLineWidth(1.0) #bgl.glEnable(bgl.GL_LINE_STIPPLE) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*points[self.mode]) bgl.glVertex2f(*p[1]) bgl.glEnd() #bgl.glDisable(bgl.GL_LINE_STIPPLE) if self.flag_cenpivot: bgl.glColor4f(1.0, 0.5, 0.0, 1.0) bgl.glPointSize(12) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*c2d) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) # Hover markers - points bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glPointSize(16) for mark in markers.items(): if mark[0] == self.mode: if type(mark[0]) is not str: bgl.glColor4f(*mark_col) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(18) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*points[self.mode]) bgl.glEnd() bgl.glColor4f(*mark_col) bgl.glPointSize(12) if type(mark[0]) is not str: bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(14) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*points[self.mode]) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) if self.flag_force: flash_size = 7 flash = [[0, 0], [2, 2], [1, 2], [2, 4], [0, 2], [1, 2], [0, 0]] for co in flash: co[0] = round( (co[0] * flash_size), 0) + self.co2d[0] + flash_size * 2 co[1] = round( (co[1] * flash_size), 0) + self.co2d[1] - flash_size * 2 bgl.glColor4f(0.95, 0.95, 0.0, 1.0) bgl.glBegin(bgl.GL_TRIANGLE_FAN) for i, co in enumerate(flash): if i in range(0, 3): bgl.glVertex2f(*co) bgl.glEnd() bgl.glBegin(bgl.GL_TRIANGLE_FAN) for i, co in enumerate(flash): if i in range(3, 6): bgl.glVertex2f(*co) bgl.glEnd() bgl.glColor4f(1.0, 0.7, 0.0, 1.0) bgl.glBegin(bgl.GL_LINE_STRIP) for co in flash: bgl.glVertex2f(*co) bgl.glEnd() # Restore opengl defaults bgl.glDisable(bgl.GL_POINTS) bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def DRAW_Overlay(self, context): np_print('DRAW_Overlay_START', ';', 'NP020FB.flag = ', NP020FB.flag) ''' addon_prefs = context.user_preferences.addons[__package__].preferences badge = addon_prefs.npfb_badge badge_size = addon_prefs.npfb_badge_size dist_scale = addon_prefs.npfb_dist_scale ''' flag = NP020FB.flag helper = NP020FB.helper matrix = helper.matrix_world.to_3x3() region = bpy.context.region rv3d = bpy.context.region_data rw = region.width rh = region.height qdef = NP020FB.qdef ndef = NP020FB.ndef ro_hor_def = NP020FB.ro_hor_def constrain = NP020FB.constrain np_print('rw, rh', rw, rh) rmin = int(min(rw, rh) / 50) if rmin == 0: rmin = 1 co2d = view3d_utils.location_3d_to_region_2d(region, rv3d, helper.location) if qdef != None and constrain == False: q = qdef n = ndef pointloc = helper.location ro_hor = ro_hor_def elif qdef != None and constrain == True: q = qdef n = ndef pointloc = get_ro_normal_from_vertical(region, rv3d, co2d)[2] ro_hor = ro_hor_def else: q = get_ro_normal_from_vertical(region, rv3d, co2d)[1] n = get_ro_normal_from_vertical(region, rv3d, co2d)[0] pointloc = get_ro_normal_from_vertical(region, rv3d, co2d)[2] ro_hor, isohipse = get_ro_x_from_iso(region, rv3d, co2d, helper.location) if pointloc == Vector((0.0, 0.0, 0.0)): pointloc = helper.location np_print('n / q', n, q) NP020FB.q = q NP020FB.n = n NP020FB.pointloc = pointloc NP020FB.ro_hor = ro_hor np_print('co2d, n, q', co2d, n, q) # Acquiring factor for graphics scaling in order to be space - independent fac = get_fac_from_view_loc_plane(region, rv3d, rmin, helper.location, q) NP020FB.fac = fac symbol = [[18, 37], [21, 37], [23, 33], [26, 33]] badge_mode = 'RUN' if qdef != None: matrix.rotate(ro_hor) matrix.rotate(qdef) NP020FB.matrix = matrix if flag == 'RUNTRANS0': instruct = 'choose plane / place corner point' keys_aff = 'LMB - select, CTRL - snap, ENT - lock plane' keys_nav = '' keys_neg = 'ESC, RMB - quit' box = [ helper.location, helper.location, helper.location, helper.location, helper.location, helper.location, helper.location, helper.location ] message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None elif flag == 'RUNTRANS1': instruct = 'define the width of the box' keys_aff = 'LMB - select, CTRL - snap, NUMPAD - value' keys_nav = '' keys_neg = 'ESC, RMB - quit' p0 = NP020FB.p0 box = [ p0, helper.location, helper.location, p0, p0, helper.location, helper.location, p0 ] message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None elif flag == 'RUNTRANS2': instruct = 'define the length of the box' keys_aff = 'LMB - select, CTRL - snap, NUMPAD - value' keys_nav = '' keys_neg = 'ESC, RMB - quit' p0 = NP020FB.p0 p1 = NP020FB.p1 box = [ p0, p1, helper.location, p0 + (helper.location - p1), p0, p1, helper.location, p0 + (helper.location - p1) ] message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None elif flag == 'RUNTRANS3': instruct = 'define the height of the box' keys_aff = 'LMB - select, CTRL - snap, NUMPAD - value' keys_nav = '' keys_neg = 'ESC, RMB - quit' p0 = NP020FB.p0 p1 = NP020FB.p1 p2 = NP020FB.p2 p3 = p0 + (p2 - p1) h = helper.location - p2 box = [p0, p1, p2, p3, p0 + h, p1 + h, p2 + h, p3 + h] message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None NP020FB.box = box # ON-SCREEN INSTRUCTIONS: display_instructions(region, rv3d, instruct, keys_aff, keys_nav, keys_neg) # drawing of box: box_2d = [] for co in box: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) box_2d.append(co) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i in range(0, 4): bgl.glVertex2f(*box_2d[i]) bgl.glVertex2f(*box_2d[0]) bgl.glVertex2f(*box_2d[4]) bgl.glVertex2f(*box_2d[7]) bgl.glVertex2f(*box_2d[3]) bgl.glVertex2f(*box_2d[7]) bgl.glVertex2f(*box_2d[6]) bgl.glVertex2f(*box_2d[2]) bgl.glVertex2f(*box_2d[6]) bgl.glVertex2f(*box_2d[5]) bgl.glVertex2f(*box_2d[1]) bgl.glVertex2f(*box_2d[5]) bgl.glVertex2f(*box_2d[4]) bgl.glEnd() bgl.glColor4f(1.0, 1.0, 1.0, 0.25) bgl.glBegin(bgl.GL_TRIANGLE_FAN) boxfaces = ((0, 1, 2, 3), (0, 1, 5, 4), (1, 2, 6, 5), (2, 3, 7, 6), (3, 0, 4, 7), (4, 5, 6, 7)) for face in boxfaces: bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*box_2d[face[0]]) bgl.glVertex2f(*box_2d[face[1]]) bgl.glVertex2f(*box_2d[face[2]]) bgl.glVertex2f(*box_2d[face[3]]) bgl.glEnd() # Drawing the small badge near the cursor with the basic instructions: display_cursor_badge(co2d, symbol, badge_mode, message_main, message_aux, aux_num, aux_str) # writing the dots for boxwidget widget at center of scene: geowidget_base = [(0.0, 0.0, 0.0), (5.0, 0.0, 0.0), (5.0, -3.0, 0.0), (0.0, -3.0, 0.0)] geowidget_top = [(0.0, 0.0, 4.0), (5.0, 0.0, 4.0), (5.0, -3.0, 4.0), (0.0, -3.0, 4.0)] geowidget_rest = [(0.0, 0.0, 0.0), (0.0, 0.0, 4.0), (5.0, 0.0, 4.0), (5.0, 0.0, 0.0), (5.0, -3.0, 0.0), (5.0, -3.0, 4.0), (0.0, -3.0, 4.0), (0.0, -3.0, 0.0)] # ON-SCREEN DISPLAY OF GEOWIDGET: display_geowidget(region, rv3d, fac, ro_hor, q, helper.location, n, qdef, geowidget_base, geowidget_top, geowidget_rest) # ON-SCREEN DISTANCES AND OTHERS: ''' if addon_prefs.npfb_suffix == 'None': suffix = None elif addon_prefs.npfb_suffix == 'km': suffix = ' km' elif addon_prefs.npfb_suffix == 'm': suffix = ' m' elif addon_prefs.npfb_suffix == 'cm': suffix = ' cm' elif addon_prefs.npfb_suffix == 'mm': suffix = ' mm' elif addon_prefs.npfb_suffix == 'nm': suffix = ' nm' elif addon_prefs.npfb_suffix == "'": suffix = "'" elif addon_prefs.npfb_suffix == '"': suffix = '"' elif addon_prefs.npfb_suffix == 'thou': suffix = ' thou' ''' # ON-SCREEN DISTANCES: display_distance_between_two_points(region, rv3d, box[0], box[1]) display_distance_between_two_points(region, rv3d, box[1], box[2]) display_distance_between_two_points(region, rv3d, box[2], box[6]) #ENDING: bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def location3d_to_location2d(location): return location_3d_to_region_2d(bpy.context.region, bpy.context.region_data, location)
def DRAW_Overlay(self, context): np_print('DRAW_Overlay_START',';','NP020PL.flag = ', NP020PL.flag) flag = NP020PL.flag helper = NP020PL.helper region = bpy.context.region rv3d = bpy.context.region_data rw = region.width rh = region.height co2d = view3d_utils.location_3d_to_region_2d(region, rv3d, helper.location) frompoints = NP020PL.frompoints topoints = NP020PL.topoints col_line_main = (1.0, 1.0, 1.0, 1.0) col_line_shadow = (0.1, 0.1, 0.1, 0.25) #greys: mark_col_A = (0.25, 0.25, 0.25, 1.0) mark_col_B = (0.5, 0.5, 0.5, 1.0) mark_col_C = (0.75, 0.75, 0.75, 1.0) #marins mark_col_A = (0.25, 0.35, 0.4, 1.0) mark_col_B = (0.5, 0.6, 0.65, 1.0) mark_col_C = (0.67, 0.77, 0.82, 1.0) # writing the dots for recwidget widget at center of scene: r = 12 angstep = 20 psize = 25 pofsetx = 15 pofsety = 15 fsize = 20 fofsetx = -8 fofsety = -7 widget_circle = construct_circle_2d(r, angstep) if flag == 'RUNTRANSF0': instruct = 'place start for point a' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap' keys_neg = 'RMB, ESC - quit' frompoints[0] = helper.location elif flag == 'RUNTRANST0': instruct = 'place target for point a' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap, MMB - lock axis, NUMPAD - value' keys_neg = 'RMB, ESC - quit' topoints[0] = helper.location elif flag == 'RUNTRANSF1': instruct = 'place start for point b' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap, MMB - lock axis, NUMPAD - value, RMB - align A (translate)' keys_neg = 'ESC - quit' frompoints[1] = helper.location elif flag == 'RUNTRANST1': instruct = 'place target for point b' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap, MMB - lock axis, NUMPAD - value, RMB - align A (translate)' keys_neg = 'ESC - quit' topoints[1] = helper.location elif flag == 'RUNTRANSF2': instruct = 'place start for point c' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap, MMB - lock axis, NUMPAD - value, RMB - align AB (translate, rotate)' keys_neg = 'ESC - quit' frompoints[2] = helper.location elif flag == 'RUNTRANST2': instruct = 'place target for point c' keys_aff = 'LMB - select, CTRL - snap, ENT - change snap, MMB - lock axis, NUMPAD - value, RMB - align AB (translate, rotate)' keys_neg = 'ESC - quit' topoints[2] = helper.location # ON-SCREEN INSTRUCTIONS: keys_nav = '' display_instructions(region, rv3d, instruct, keys_aff, keys_nav, keys_neg) # LINE: for i, frompoint in enumerate(frompoints): topoint = topoints[i] if frompoint != None and topoint != None: bgl.glColor4f(*col_line_shadow) bgl.glLineWidth(1.4) bgl.glBegin(bgl.GL_LINE_STRIP) frompoint = view3d_utils.location_3d_to_region_2d(region, rv3d, frompoint) topoint = view3d_utils.location_3d_to_region_2d(region, rv3d, topoint) bgl.glVertex2f((frompoint[0] - 1), (frompoint[1] - 1)) bgl.glVertex2f((topoint[0] - 1), (topoint[1] - 1)) bgl.glEnd() bgl.glColor4f(*col_line_main) bgl.glLineWidth(1.4) bgl.glBegin(bgl.GL_LINE_STRIP) bgl.glVertex2f(*frompoint) bgl.glVertex2f(*topoint) bgl.glEnd() # drawing of markers: i = 0 for point in frompoints: if point != None: point = view3d_utils.location_3d_to_region_2d(region, rv3d, point) point[0] = point[0] + pofsetx point[1] = point[1] + pofsety widget = [] for co in widget_circle: c = [0.0, 0.0] c[0] = co[0] + point[0] + pofsetx c[1] = co[1] + point[1] + pofsety widget.append(c) bgl.glEnable(bgl.GL_BLEND) if i == 0: bgl.glColor4f(*mark_col_A) mark = "A" elif i == 1: bgl.glColor4f(*mark_col_B) mark = "B" elif i == 2: bgl.glColor4f(*mark_col_C) mark = "C" ''' bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for co in widget: bgl.glVertex2f(*co) bgl.glVertex2f(*widget[len(widget) - 1]) bgl.glEnd() bgl.glBegin(bgl.GL_TRIANGLE_FAN) for co in widget: bgl.glVertex2f(*co) bgl.glEnd() ''' font_id = 0 bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(psize) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*point) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) bgl.glColor4f(1.0, 1.0, 1.0, 0.75) blf.size(font_id, fsize, 72) blf.position(font_id, point[0] + fofsetx, point[1] + fofsety, 0) blf.draw(font_id, mark) i = i + 1 i = 0 for point in topoints: if point != None: point = view3d_utils.location_3d_to_region_2d(region, rv3d, point) point[0] = point[0] + pofsetx point[1] = point[1] + pofsety widget = [] for co in widget_circle: c = [0.0, 0.0] c[0] = co[0] + point[0] + pofsetx c[1] = co[1] + point[1] + pofsety widget.append(c) bgl.glEnable(bgl.GL_BLEND) if i == 0: bgl.glColor4f(*mark_col_A) mark = "A'" elif i == 1: bgl.glColor4f(*mark_col_B) mark = "B'" elif i == 2: bgl.glColor4f(*mark_col_C) mark = "C'" ''' bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for co in widget: bgl.glVertex2f(*co) bgl.glVertex2f(*widget[len(widget) - 1]) bgl.glEnd() bgl.glBegin(bgl.GL_TRIANGLE_FAN) for co in widget: bgl.glVertex2f(*co) bgl.glEnd() ''' font_id = 0 bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(psize) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*point) bgl.glEnd() bgl.glDisable(bgl.GL_POINT_SMOOTH) bgl.glColor4f(1.0, 1.0, 1.0, 0.75) blf.size(font_id, fsize, 72) blf.position(font_id, point[0] + fofsetx, point[1] + fofsety, 0) blf.draw(font_id, mark) i = i + 1 #ENDING: bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def vertex_3d_to_2d(self, context, v3d): rv3d = context.space_data.region_3d region = context.region return location_3d_to_region_2d(region, rv3d, v3d)
def DRAW_RunTranslate(self, context): # np_print('04_DRAW_RunTranslate_START',';','flag = ', Storage.flag) flag = NP020PM.flag sel = bpy.context.selected_objects lensel = len(sel) helper = NP020PM.helper if flag == 'TAKE': takeloc = helper.location placeloc = helper.location main = 'select "take" point' keys_aff = 'LMB - select, CTRL - snap' keys_nav = '' keys_neg = 'ESC, RMB - quit' badge_mode = 'RUN' message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None elif flag == 'PLACE': takeloc = NP020PM.takeloc placeloc = helper.location main = 'select "place" point' keys_aff = 'LMB - select, CTRL - snap, MMB - lock axis, NUMPAD - value' keys_nav = '' keys_neg = 'ESC, RMB - quit' badge_mode = 'RUN' message_main = 'CTRL+SNAP' message_aux = None aux_num = None aux_str = None # constrain loc so viewport values are the right one if NP020PM.constrain: placeloc = constrain_pos2d(context, placeloc) takeloc = constrain_pos2d(context, takeloc) # ON-SCREEN INSTRUCTIONS: region = bpy.context.region rv3d = bpy.context.region_data instruct = main display_instructions(region, rv3d, instruct, keys_aff, keys_nav, keys_neg) co2d = view3d_utils.location_3d_to_region_2d(region, rv3d, helper.location) symbol = [[19, 34], [18, 35], [19, 36], [18, 35], [26, 35], [25, 34], [26, 35], [25, 37], [26, 35], [22, 35], [22, 39], [21, 38], [22, 39], [23, 38], [22, 39], [22, 31], [21, 32], [22, 31], [23, 32]] display_cursor_badge(co2d, symbol, badge_mode, message_main, message_aux, aux_num, aux_str) display_line_between_two_points(region, rv3d, takeloc, placeloc) display_distance_between_two_points(region, rv3d, takeloc, placeloc) # draw extenal tool adds NP020PM.draw_callback(context)
def location_to_region(worldcoords): out = view3d_utils.location_3d_to_region_2d( bpy.context.region, bpy.context.space_data.region_3d, worldcoords) return out
def vertices_3d_to_2d(self, context): for index, vertex_3d in enumerate(self._vertices): rv3d = self._view_context.region_3d region = self._view_context.region self._vertices_2d[index] = location_3d_to_region_2d( region, rv3d, vertex_3d)
def get_2d_vertex(context, vertex_3d): region = context.region rv3d = context.space_data.region_3d return location_3d_to_region_2d(region, rv3d, vertex_3d)
def DRAW_Overlay(self, context): print('DRAW_Overlay_START', ';', 'NP020RM.flag = ', NP020RM.flag) flag = NP020RM.flag helper = NP020RM.helper angstep = NP020RM.angstep region = bpy.context.region rv3d = bpy.context.region_data rw = region.width rh = region.height if NP020RM.centerloc == None: centerloc = helper.location else: centerloc = NP020RM.centerloc qdef = NP020RM.qdef ndef = NP020RM.ndef alpha_0 = NP020RM.alpha_0 alpha_1 = NP020RM.alpha_1 print('rw, rh', rw, rh) rmin = int(min(rw, rh) / 10) if rmin == 0: rmin = 1 co2d = self.co2d if flag in ('RUNTRANSCENTER', 'RUNTRANSSTART'): co2d = view3d_utils.location_3d_to_region_2d(region, rv3d, helper.location) if qdef == None: q = get_ro_normal_from_vertical(region, rv3d, co2d)[1] n = get_ro_normal_from_vertical(region, rv3d, co2d)[0] else: q = qdef n = ndef NP020RM.q = q NP020RM.n = n #co2d_exp = (event.mouse_region_x, event.mouse_region_y) #n_exp = get_ro_normal_from_vertical(region, rv3d, co2d_exp)[0] #print ('co2d, n, q, n_exp', co2d, n, q) # writing the dots for circle at center of scene: radius = 1 ang = 0.0 circle = [(0.0, 0.0, 0.0)] while ang < 360.0: circle.append(((cos(radians(ang)) * radius), (sin(radians(ang)) * radius), (0.0))) ang += 10 circle.append( ((cos(radians(0.0)) * radius), (sin(radians(0.0)) * radius), (0.0))) # rotating and translating the circle to user picked angle and place: circle = rotate_graphic(circle, q) circle = translate_graphic(circle, centerloc) rmax = 1 for i, co in enumerate(circle): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) circle[i] = co for i in range(1, 18): r = (circle[0] - circle[i]).length r1 = (circle[0] - circle[i + 18]).length #if (r + r1) > rmax and abs(r - r1) < min(r, r1)/5: rmax = (r+r1)/2 #if (r + r1) > rmax and abs(r - r1) < min(r, r1)/10: rmax = r + r1 if (r + r1) > rmax and (r + r1) / 2 < rmin: rmax = (r + r1) elif (r + r1) > rmax and (r + r1) / 2 >= rmin: rmax = (r + r1) * rmin / (((r + r1) / 2) - ((r + r1) / 2) - rmin) rmax = abs(rmax) circle[i] = co print('rmin', rmin) print('rmax', rmax) if flag not in ('RUNTRANSSTART', 'RUNROTEND'): fac = (rmin * 2) / rmax NP020RM.fac = fac else: fac = NP020RM.fac radius = 1 * fac ang = 0.0 circle = [(0.0, 0.0, 0.0)] while ang < 360.0: circle.append(((cos(radians(ang)) * radius), (sin(radians(ang)) * radius), (0.0))) ang += 10 circle.append( ((cos(radians(0.0)) * radius), (sin(radians(0.0)) * radius), (0.0))) if flag == 'RUNTRANSCENTER': instruct = 'place center point' keys_aff = 'LMB / ENT / NUMPAD ENT - confirm, CTRL - snap' keys_nav = '' keys_neg = 'ESC - quit' r1 = 1 r2 = 1.5 walpha = construct_roto_widget(alpha_0, alpha_1, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_L = construct_roto_widget(90, 0, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_D = construct_roto_widget(0, 90, fac, r1, r2, angstep) elif flag == 'BGLPLANE': instruct = 'choose rotation plane' keys_aff = 'LMB / ENT / NUMPAD ENT - confirm' keys_nav = 'MMB / SCROLL - navigate' keys_neg = 'ESC - quit' ro_hor, isohipse = get_ro_x_from_iso(region, rv3d, co2d, centerloc) NP020RM.ro_hor = copy.deepcopy(ro_hor) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 0.0, 0.0, 1.0) bgl.glLineWidth(2) bgl.glBegin(bgl.GL_LINE_STRIP) for co in isohipse: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(4) bgl.glBegin(bgl.GL_POINTS) for co in isohipse: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() r1 = 1 r2 = 1.5 walpha = construct_roto_widget(alpha_0, alpha_1, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_L = construct_roto_widget(90, 0, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_D = construct_roto_widget(0, 90, fac, r1, r2, angstep) circle = rotate_graphic(circle, ro_hor) walpha = rotate_graphic(walpha, ro_hor) wbeta_L = rotate_graphic(wbeta_L, ro_hor) wbeta_D = rotate_graphic(wbeta_D, ro_hor) circle = rotate_graphic(circle, q) walpha = rotate_graphic(walpha, q) wbeta_L = rotate_graphic(wbeta_L, q) wbeta_D = rotate_graphic(wbeta_D, q) elif flag == 'RUNTRANSSTART': instruct = 'place start point' keys_aff = 'LMB / ENT / NUMPAD ENT - confirm, CTRL - snap' keys_nav = '' keys_neg = 'ESC - quit' hloc = helper.location #print('hloc', hloc) hlocb = hloc + n #print('hlocb', hlocb) #print('centerloc, n', centerloc, n) proj_start = mathutils.geometry.intersect_line_plane( helper.location, (helper.location + n), centerloc, n) NP020RM.proj_start = proj_start if proj_start == centerloc: proj = centerloc + Vector((0.0, 0.0, 0.001)) #print ('proj_start' , proj_start) alpha_0, isohipse = get_angle_from_iso_planar(centerloc, n, proj_start) alpha_1 = alpha_0 NP020RM.alpha_0 = alpha_0 NP020RM.alpha_1 = alpha_1 print('alpha_0', alpha_0) ro_hor = NP020RM.ro_hor bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 0.0, 0.0, 1.0) bgl.glLineWidth(2) bgl.glBegin(bgl.GL_LINE_STRIP) for co in isohipse: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(4) bgl.glBegin(bgl.GL_POINTS) for co in isohipse: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() r1 = 1 r2 = 1.5 walpha = construct_roto_widget(alpha_0, alpha_1, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_L = construct_roto_widget(alpha_1, 0, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_D = construct_roto_widget(0, alpha_0, fac, r1, r2, angstep) circle = rotate_graphic(circle, ro_hor) walpha = rotate_graphic(walpha, ro_hor) wbeta_L = rotate_graphic(wbeta_L, ro_hor) wbeta_D = rotate_graphic(wbeta_D, ro_hor) circle = rotate_graphic(circle, q) walpha = rotate_graphic(walpha, q) wbeta_L = rotate_graphic(wbeta_L, q) wbeta_D = rotate_graphic(wbeta_D, q) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.5, 0.5, 1.0, 1.0) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) points = (helper.location, proj_start, centerloc) for co in points: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() co = view3d_utils.location_3d_to_region_2d(region, rv3d, proj_start) bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(14) bgl.glEnable(bgl.GL_BLEND) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*co) bgl.glEnd() elif flag == 'RUNROTEND': instruct = 'place end point' keys_aff = 'LMB / ENT / NUMPAD ENT - confirm, CTRL - snap' keys_nav = '' keys_neg = 'ESC - quit' for k, v in bpy.context.active_operator.properties.items(): print(k, v) alpha_0 = NP020RM.alpha_0_def hloc = helper.location startloc = NP020RM.startloc endloc = helper.location proj_start = NP020RM.proj_start #print('hloc', hloc) hlocb = hloc + n #print('hlocb', hlocb) #print('centerloc, n', centerloc, n) proj_end = mathutils.geometry.intersect_line_plane( helper.location, (helper.location + n), centerloc, n) if proj_end == centerloc: proj_end = centerloc + Vector((0.0, 0.0, 0.001)) #print ('proj_end' , proj_end) alpha = get_angle_vector_from_vector(centerloc, proj_start, proj_end) alpha_1 = alpha_0 + alpha print('alpha_0', alpha_0) ro_hor = NP020RM.ro_hor rot_helper_0 = NP020RM.rot_helper_0 print('rot_helper_0 =', rot_helper_0) rot_helper_1 = helper.rotation_euler print('rot_helper_1 =', rot_helper_1) alpha_real = get_eul_z_angle_difffff_in_rotated_system( rot_helper_0, rot_helper_1, ndef) print('alpha_real =', alpha_real) delta = (abs(alpha_real) - (360 * int(abs(alpha_real) / 360))) if alpha_real >= 0: if alpha_0 + delta < 360: alpha_1 = alpha_0 + delta else: alpha_1 = delta - (360 - alpha_0) else: if delta < alpha_0: alpha_1 = alpha_0 alpha_0 = alpha_1 - delta else: alpha_1 = alpha_0 alpha_0 = 360 - (delta - alpha_0) if alpha_1 == alpha_0: alpha_1 = alpha_0 + 0.001 r1 = 1 r2 = 1.5 walpha = construct_roto_widget(alpha_0, alpha_1, fac, r1, r2, angstep) r1 = 1.5 r2 = 2 wbeta_L = construct_roto_widget(alpha_1, alpha_0, fac, r1, r2, angstep) ''' r1 = 1.5 r2 = 2 wbeta_D = construct_roto_widget(0, alpha_0, fac, r1, r2, angstep) ''' circle = rotate_graphic(circle, ro_hor) walpha = rotate_graphic(walpha, ro_hor) wbeta_L = rotate_graphic(wbeta_L, ro_hor) #wbeta_D = rotate_graphic(wbeta_D, ro_hor) circle = rotate_graphic(circle, q) walpha = rotate_graphic(walpha, q) wbeta_L = rotate_graphic(wbeta_L, q) #wbeta_D = rotate_graphic(wbeta_D, q) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.5, 0.5, 1.0, 1.0) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) points = (helper.location, proj_end, centerloc, proj_start) for co in points: co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) bgl.glEnd() co = view3d_utils.location_3d_to_region_2d(region, rv3d, proj_end) bgl.glColor4f(1.0, 1.0, 1.0, 1.0) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glPointSize(14) bgl.glEnable(bgl.GL_BLEND) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(*co) bgl.glEnd() # NUMERICAL ANGLE: bgl.glColor4f(0.0, 0.0, 0.0, 1.0) font_id = 0 blf.size(font_id, 20, 72) ang_pos = view3d_utils.location_3d_to_region_2d( region, rv3d, centerloc) blf.position(font_id, ang_pos[0] + 2, ang_pos[1] - 2, 0) blf.draw(font_id, str(round(alpha_real, 2))) bgl.glColor4f(1.0, 1.0, 1.0, 1.0) blf.position(font_id, ang_pos[0], ang_pos[1], 0) blf.draw(font_id, str(round(alpha_real, 2))) # DRAWING START: bgl.glEnable(bgl.GL_BLEND) # ON-SCREEN INSTRUCTIONS: display_instructions(region, rv3d, instruct, keys_aff, keys_nav, keys_neg) print('centerloc', centerloc) circle = translate_graphic(circle, centerloc) walpha = translate_graphic(walpha, centerloc) wbeta_L = translate_graphic(wbeta_L, centerloc) if flag is not 'RUNROTEND': wbeta_D = translate_graphic(wbeta_D, centerloc) print('rv3d', rv3d) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, 0.6) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(circle): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) circle[i] = co bgl.glEnd() print('centerloc', centerloc) # drawing of walpha contours: bgl.glColor4f(1.0, 1.0, 1.0, 0.6) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(walpha): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) walpha[i] = co bgl.glEnd() #print ('walpha', walpha) bgl.glColor4f(0.0, 0.0, 0.0, 0.5) # drawing of walpha fields: print('alpha_0, alpha_1 =', alpha_0, alpha_1) if alpha_1 >= alpha_0: alpha = alpha_1 - alpha_0 else: alpha = alpha_1 + (360 - alpha_0) sides = int(alpha / NP020RM.angstep) + 1 bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*walpha[0]) bgl.glVertex2f(*walpha[1]) bgl.glVertex2f(*walpha[2]) bgl.glVertex2f(*walpha[(sides * 2) + 1]) bgl.glEnd() for i in range(1, sides): bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*walpha[((sides * 2) + 2) - i]) bgl.glVertex2f(*walpha[i + 1]) bgl.glVertex2f(*walpha[2 + i]) bgl.glVertex2f(*walpha[((sides * 2) + 2) - (i + 1)]) bgl.glEnd() # drawing of wbeta_L contours: bgl.glColor4f(1.0, 1.0, 1.0, 0.6) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(wbeta_L): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) wbeta_L[i] = co bgl.glEnd() #print ('wbeta_L', wbeta_L) bgl.glColor4f(0.65, 0.85, 1.0, 0.35) # drawing of wbeta_L fields: if flag == 'RUNROTEND': if alpha_0 >= alpha_1: alpha = alpha_0 - alpha_1 else: alpha = alpha_0 + (360 - alpha_1) else: alpha = 360 - alpha_1 sides = int(alpha / NP020RM.angstep) + 1 bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*wbeta_L[0]) bgl.glVertex2f(*wbeta_L[1]) bgl.glVertex2f(*wbeta_L[2]) bgl.glVertex2f(*wbeta_L[(sides * 2) + 1]) bgl.glEnd() for i in range(1, sides): bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*wbeta_L[((sides * 2) + 2) - i]) bgl.glVertex2f(*wbeta_L[i + 1]) bgl.glVertex2f(*wbeta_L[2 + i]) bgl.glVertex2f(*wbeta_L[((sides * 2) + 2) - (i + 1)]) bgl.glEnd() if flag is not 'RUNROTEND': # drawing of wbeta_D contours: bgl.glColor4f(1.0, 1.0, 1.0, 0.6) bgl.glLineWidth(1) bgl.glBegin(bgl.GL_LINE_STRIP) for i, co in enumerate(wbeta_D): co = view3d_utils.location_3d_to_region_2d(region, rv3d, co) bgl.glVertex2f(*co) wbeta_D[i] = co bgl.glEnd() #print ('wbeta_D', wbeta_D) bgl.glColor4f(0.35, 0.6, 0.75, 0.35) # drawing of wbeta_D fields: alpha = alpha_0 sides = int(alpha / NP020RM.angstep) + 1 bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*wbeta_D[0]) bgl.glVertex2f(*wbeta_D[1]) bgl.glVertex2f(*wbeta_D[2]) bgl.glVertex2f(*wbeta_D[(sides * 2) + 1]) bgl.glEnd() for i in range(1, sides): bgl.glBegin(bgl.GL_TRIANGLE_FAN) bgl.glVertex2f(*wbeta_D[((sides * 2) + 2) - i]) bgl.glVertex2f(*wbeta_D[i + 1]) bgl.glVertex2f(*wbeta_D[2 + i]) bgl.glVertex2f(*wbeta_D[((sides * 2) + 2) - (i + 1)]) bgl.glEnd() #ENDING bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def modal(self, context, event): context.area.tag_redraw() myobj = context.selected_objects[self.objIndex] annotation = myobj.AnnotationGenerator[0].annotations[self.idx] center = annotation.gizLoc region = bpy.context.region rv3d = bpy.context.space_data.region_3d center = view3d_utils.location_3d_to_region_2d(region, rv3d, center) #For some reason the value returned by view3d utils is 100px off in the y axis center += Vector((0, 100)) vecLast = Vector((self.init_mouse_x, self.init_mouse_y)) vecLast -= center delta = 0 # Set Tweak Flags if event.ctrl: tweak_snap = True else: tweak_snap = False if event.shift: tweak_precise = True else: tweak_precise = False if event.type == 'MOUSEMOVE': sensitivity = 1 vecDelta = Vector((event.mouse_x, event.mouse_y)) vecDelta -= center delta += vecDelta.angle_signed(vecLast) * sensitivity delta = math.degrees(delta) if tweak_snap: delta = 5 * round(delta / 5) if self.constrainAxis[0]: annotation.annotationRotation[0] = self.init_x - math.radians( delta) axisText = 'X: ' if self.constrainAxis[1]: annotation.annotationRotation[1] = self.init_y + math.radians( delta) axisText = 'Y: ' if self.constrainAxis[2]: annotation.annotationRotation[2] = self.init_z - math.radians( delta) axisText = 'Z: ' vecLast = vecDelta context.area.header_text_set("Rotate " + axisText + "%.4f" % delta + "\u00b0") elif event.type == 'LEFTMOUSE': #Setting hide_viewport is a stupid hack to force Gizmos to update after operator completes context.area.header_text_set(None) bpy.context.window.cursor_modal_restore() return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: #Setting hide_viewport is a stupid hack to force Gizmos to update after operator completes context.area.header_text_set(None) bpy.context.window.cursor_modal_restore() annotation.annotationRotation[0] = self.init_x annotation.annotationRotation[1] = self.init_y annotation.annotationRotation[2] = self.init_z return {'CANCELLED'} return {'RUNNING_MODAL'}
def modal(self, context, event): #print(context.active_operator) context.area.tag_redraw() context.area.header_text_set("Shift+A: NewLoops, A: NewLoop, LeftClick: CreatePoint, Ctrl+Z: Undo, C: CreateTriangle, Ctrl+LeftClick: CreateTriangle2, Shift+Tab: SurfaceSnap") preferences = context.preferences addon_prefs = preferences.addons[__package__].preferences mi_settings = context.scene.mi_settings m_coords = event.mouse_region_x, event.mouse_region_y active_obj = context.active_object bm = bmesh.from_edit_mesh(active_obj.data) region = context.region rv3d = context.region_data # check nearest id to index # this is to get loop direction if not self.all_loops_ids[-1].loop_ids and len(self.all_loops_ids) > 1: m_coords_vec = Vector(m_coords) first_id = self.all_loops_ids[-2].loop_ids[0] last_id = self.all_loops_ids[-2].loop_ids[-1] test_verts = ut_base.get_verts_from_ids([first_id, last_id], self.id_layer, bm) pos_3d_1 = active_obj.matrix_world @ test_verts[0].co pos_2d_1 = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_3d_1) pos_3d_2 = active_obj.matrix_world @ test_verts[1].co pos_2d_2 = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_3d_2) if pos_2d_1 and pos_2d_2: dist_1 = (m_coords_vec - pos_2d_1).length dist_2 = (m_coords_vec - pos_2d_2).length if dist_1 < dist_2: self.id_to_index = (first_id, pos_2d_1) self.all_loops_ids[-1].revert_prev_loops = False else: self.id_to_index = (last_id, pos_2d_2) self.all_loops_ids[-1].revert_prev_loops = True elif not pos_2d_1: self.id_to_index = (last_id, pos_2d_2) self.all_loops_ids[-1].revert_prev_loops = True elif not pos_2d_2: self.id_to_index = (first_id, pos_2d_1) self.all_loops_ids[-1].revert_prev_loops = False else: self.id_to_index = None keys_pass = mi_inputs.get_input_pass(mi_inputs.pass_keys, addon_prefs.key_inputs, event) # Make Picking if self.tool_mode == 'IDLE' and event.value == 'PRESS' and keys_pass is False: if event.type in {'LEFTMOUSE', 'SELECTMOUSE'}: # get position new_point_pos = None if mi_settings.surface_snap is True and self.picked_meshes: best_obj, hit_normal, hit_position = ut_base.get_mouse_raycast(context, self.picked_meshes, m_coords) if hit_position: new_point_pos = active_obj.matrix_world.inverted() @ hit_position else: #cursor_loc = context.space_data.cursor_location cursor_loc = bpy.context.scene.cursor.location new_point_pos = ut_base.get_mouse_on_plane(context, cursor_loc, None, m_coords) new_point_pos = active_obj.matrix_world.inverted() @ new_point_pos # create vert/edge/face if new_point_pos: loop_obj = self.all_loops_ids[-1] new_face_verts = [] # create a new vert new_vert = bm.verts.new((new_point_pos[0], new_point_pos[1], new_point_pos[2])) new_vert[self.id_layer] = self.id_value loop_obj.loop_ids.append(self.id_value) self.id_value += 1 bm.verts.index_update() bm.verts.ensure_lookup_table() # create a new face new_face_verts.append(new_vert) temp_ids = [] if len(self.all_loops_ids) > 1: prev_loop_ids = self.all_loops_ids[-2].loop_ids if len(loop_obj.loop_ids) > 1: if self.all_loops_ids[-1].revert_prev_loops is True: prev_loop_ids = prev_loop_ids.copy() prev_loop_ids.reverse() temp_ids.append(loop_obj.loop_ids[-2]) prev_len = len(prev_loop_ids) - 1 temp_ids.append(prev_loop_ids[self.previous_loop_id]) if self.previous_loop_id < prev_len and event.ctrl is False: temp_ids.append(prev_loop_ids[self.previous_loop_id + 1]) other_verts = ut_base.get_verts_from_ids(temp_ids, self.id_layer, bm) new_face_verts += other_verts new_face = bm.faces.new( new_face_verts ) bmesh.ops.recalc_face_normals(bm, faces=[new_face]) if self.previous_loop_id < prev_len and event.ctrl is False: self.previous_loop_id += 1 bm.faces.index_update() bm.faces.ensure_lookup_table() else: if self.all_loops_ids[-1].revert_prev_loops is True: prev_loop_ids = prev_loop_ids.copy() prev_loop_ids.reverse() temp_ids.append(prev_loop_ids[0]) other_verts = ut_base.get_verts_from_ids(temp_ids, self.id_layer, bm) new_face_verts += other_verts new_edge = bm.edges.new(new_face_verts) self.previous_loop_id = 0 bm.edges.index_update() bm.edges.ensure_lookup_table() else: if len(loop_obj.loop_ids) > 1: temp_ids.append(loop_obj.loop_ids[-2]) other_verts = ut_base.get_verts_from_ids(temp_ids, self.id_layer, bm) new_face_verts += other_verts new_edge = bm.edges.new(new_face_verts) bm.edges.index_update() bm.edges.ensure_lookup_table() self.tool_mode = 'MOVE_POINT' bm.normal_update() bmesh.update_edit_mesh(active_obj.data) # Create Curve elif event.type == 'C': loop_obj = self.all_loops_ids[-1] new_face_verts = [] # create a new face temp_ids = [] if len(self.all_loops_ids) > 1 and self.all_loops_ids[-1].loop_ids: prev_loop_ids = self.all_loops_ids[-2].loop_ids if self.all_loops_ids[-1].revert_prev_loops is True: prev_loop_ids = prev_loop_ids.copy() prev_loop_ids.reverse() prev_len = len(prev_loop_ids) - 1 if self.previous_loop_id < prev_len: temp_ids.append(loop_obj.loop_ids[-1]) temp_ids.append(prev_loop_ids[self.previous_loop_id]) temp_ids.append(prev_loop_ids[self.previous_loop_id + 1]) other_verts = ut_base.get_verts_from_ids(temp_ids, self.id_layer, bm) new_face_verts += other_verts new_face = bm.faces.new( new_face_verts ) bmesh.ops.recalc_face_normals(bm, faces=[new_face]) if self.previous_loop_id < prev_len and event.ctrl is False: self.previous_loop_id += 1 bm.faces.index_update() bm.faces.ensure_lookup_table() bm.normal_update() bmesh.update_edit_mesh(active_obj.data) # Create Curve elif event.type == 'A': # all new loops if event.shift: self.all_loops_ids.clear() self.all_loops_ids.append(MI_PL_LoopObject(False)) # add another empty loop self.previous_loop_id = 0 self.id_to_index = None # new loop else: last_ids = self.all_loops_ids[-1].loop_ids if len(last_ids) > 1: self.all_loops_ids.append(MI_PL_LoopObject(False)) # add another empty loop self.previous_loop_id = 0 self.id_to_index = None elif event.type in {'Z'} and event.ctrl is True: if self.all_loops_ids: # remove previous loop object if len(self.all_loops_ids) > 1 and not self.all_loops_ids[-1].loop_ids: self.all_loops_ids.remove(self.all_loops_ids[-1]) if self.all_loops_ids[-1].loop_ids: # remove last vert last_vert = ut_base.get_verts_from_ids([self.all_loops_ids[-1].loop_ids[-1]], self.id_layer, bm)[0] self.all_loops_ids[-1].loop_ids.remove(self.all_loops_ids[-1].loop_ids[-1]) bmesh.ops.delete(bm, geom=[last_vert], context='VERTS') bmesh.update_edit_mesh(active_obj.data) # set new previous index if len(self.all_loops_ids) > 1 and self.all_loops_ids[-1].loop_ids: new_last_vert = ut_base.get_verts_from_ids([self.all_loops_ids[-1].loop_ids[-1]], self.id_layer, bm)[0] linked_edges = new_last_vert.link_edges new_prev_loop_id = 0 prev_loop_ids = self.all_loops_ids[-2].loop_ids if self.all_loops_ids[-1].revert_prev_loops is True: prev_loop_ids = prev_loop_ids.copy() prev_loop_ids.reverse() for edge in linked_edges: for vert in edge.verts: if vert[self.id_layer] in prev_loop_ids: if vert[self.id_layer] > new_prev_loop_id: new_prev_loop_id = prev_loop_ids.index(vert[self.id_layer]) self.previous_loop_id = new_prev_loop_id #else: #self.previous_loop_id = 0 else: self.previous_loop_id = 0 elif event.type in {'TAB'} and event.shift: if mi_settings.surface_snap is True: mi_settings.surface_snap = False else: mi_settings.surface_snap = True if not self.picked_meshes: # get meshes for snapping meshes_array = ut_base.get_obj_dup_meshes(mi_settings.snap_objects, mi_settings.convert_instances, context) if meshes_array: self.picked_meshes = meshes_array # TOOL WORK if self.tool_mode == 'MOVE_POINT': if event.type in {'LEFTMOUSE', 'SELECTMOUSE'} and event.value == 'RELEASE': self.tool_mode = 'IDLE' last_vert = ut_base.get_verts_from_ids([self.all_loops_ids[-1].loop_ids[-1]], self.id_layer, bm)[0] if mi_settings.surface_snap is True and self.picked_meshes: best_obj, hit_normal, hit_position = ut_base.get_mouse_raycast(context, self.picked_meshes, m_coords) if hit_position: last_vert.co = active_obj.matrix_world.inverted() @ hit_position bm.normal_update() bmesh.update_edit_mesh(active_obj.data) return {'RUNNING_MODAL'} else: last_vert = ut_base.get_verts_from_ids([self.all_loops_ids[-1].loop_ids[-1]], self.id_layer, bm)[0] new_point_pos = ut_base.get_mouse_on_plane(context, active_obj.matrix_world @ last_vert.co, None, m_coords) if new_point_pos: last_vert.co = active_obj.matrix_world.inverted() @ new_point_pos bmesh.update_edit_mesh(active_obj.data) return {'RUNNING_MODAL'} else: if event.value == 'RELEASE' and event.type in {'LEFTMOUSE', 'SELECTMOUSE'}: self.tool_mode = 'IDLE' return {'RUNNING_MODAL'} # get keys if keys_pass is True: # allow navigation return {'PASS_THROUGH'} elif event.type in {'RIGHTMOUSE', 'ESC'}: #bpy.types.SpaceView3D.draw_handler_remove(self.mi_pl_3d, 'WINDOW') bpy.types.SpaceView3D.draw_handler_remove(self.mi_pl_2d, 'WINDOW') finish_work(self, context, bm) context.area.header_text_set(None) return {'FINISHED'} return {'RUNNING_MODAL'}
def refresh_batches(self, context): #region outline calculation region = context.region rv3d = context.region_data rh = region.height rw = region.width center = rw/2 addon_prefs = bpy.context.preferences.addons[__package__].preferences #LASSO SELECTION LINES lassosel_screen_lines = [] if self.lasso_selecting: for i in range(len(self._changing_po_cache)): lassosel_screen_lines.append(self._changing_po_cache[i-1]) lassosel_screen_lines.append(self._changing_po_cache[i]) #CIRCLE SELECTION LINES circlesel_screen_lines = [] if self.circle_selecting or self.circle_select_start or self.circle_resizing: if self.circle_resizing: cur_loc = mathutils.Vector(( self._changing_po_cache[0][0], self._changing_po_cache[0][1] )) else: cur_loc = mathutils.Vector(( self._mouse_loc[0], self._mouse_loc[1] )) co = cur_loc.copy() co[1] += self.circle_radius angle = math.radians(360/32) for i in range(32): circlesel_screen_lines.append(co.copy()) co = rotate_2d(cur_loc, co, angle) circlesel_screen_lines.append(co.copy()) #BOX SELECTION LINES boxsel_screen_lines = [] if self.box_selecting: init_loc = mathutils.Vector(( self._changing_po_cache[0][0], self._changing_po_cache[0][1] )) cur_loc = mathutils.Vector(( self._mouse_loc[0], self._mouse_loc[1] )) top_right = mathutils.Vector(( self._mouse_loc[0], self._changing_po_cache[0][1] )) bot_left = mathutils.Vector(( self._changing_po_cache[0][0], self._mouse_loc[1] )) vec = init_loc-top_right start_co = top_right dashed_lines = vec_to_dashed(start_co, vec, int(vec.length/10)) boxsel_screen_lines += dashed_lines vec = top_right-cur_loc start_co = cur_loc dashed_lines = vec_to_dashed(start_co, vec, int(vec.length/10)) boxsel_screen_lines += dashed_lines vec = cur_loc-bot_left start_co = bot_left dashed_lines = vec_to_dashed(start_co, vec, int(vec.length/10)) boxsel_screen_lines += dashed_lines vec = bot_left-init_loc start_co = init_loc dashed_lines = vec_to_dashed(start_co, vec, int(vec.length/10)) boxsel_screen_lines += dashed_lines rot_screen_lines = [] if self.rotating: cent_loc = view3d_utils.location_3d_to_region_2d(region, rv3d, self._changing_po_cache[1]) cur_loc = mathutils.Vector(( self._mouse_loc[0], self._mouse_loc[1] )) vec = cur_loc-cent_loc start_co = cent_loc dashed_lines = vec_to_dashed(start_co, vec, int(vec.length/10)) rot_screen_lines += dashed_lines #stores 2d batches self.batch_boxsel_screen_lines = batch_for_shader(self.shader_2d, 'LINES', {"pos": boxsel_screen_lines}) self.batch_circlesel_screen_lines = batch_for_shader(self.shader_2d, 'LINES', {"pos": circlesel_screen_lines}) self.batch_lassosel_screen_lines = batch_for_shader(self.shader_2d, 'LINES', {"pos": lassosel_screen_lines}) self.batch_rotate_screen_lines = batch_for_shader(self.shader_2d, 'LINES', {"pos": rot_screen_lines}) if self.redraw: self._points_container.update(addon_prefs.normal_size, self._active_point, addon_prefs.selected_only, addon_prefs.selected_scale) self.redraw = False force_scene_update() return
def modal(self, context, event): context.area.tag_redraw() # allow moving in the 3D View if event.type in { 'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE', 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6', 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5' }: return {'PASS_THROUGH'} if event.type in {'LEFT_ALT', 'RIGHT_ALT'}: if event.value == 'PRESS': pt_buf.alt = True if event.value == 'RELEASE': pt_buf.alt = False return {'RUNNING_MODAL'} elif event.type in {'LEFT_CTRL', 'RIGHT_CTRL'}: if event.value == 'PRESS': pt_buf.ctrl = not pt_buf.ctrl return {'RUNNING_MODAL'} elif event.type in {'LEFT_SHIFT', 'RIGHT_SHIFT'}: if event.value == 'PRESS': pt_buf.shift = True if event.value == 'RELEASE': pt_buf.shift = False return {'RUNNING_MODAL'} elif event.type == 'MOUSEMOVE': if pt_buf.list_m_loc_2d != []: pt_buf_list_m_loc_3d_last_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, pt_buf.list_m_loc_3d[-1]) if pt_buf.alt is True: pt_buf.x = pt_buf_list_m_loc_3d_last_2d[0] pt_buf.y = event.mouse_region_y elif pt_buf.shift is True: pt_buf.x = event.mouse_region_x pt_buf.y = pt_buf_list_m_loc_3d_last_2d[1] else: pt_buf.x = event.mouse_region_x pt_buf.y = event.mouse_region_y else: pt_buf.x = event.mouse_region_x pt_buf.y = event.mouse_region_y elif event.type == 'LEFTMOUSE': if event.value == 'PRESS': mouse_loc_2d = Vector((pt_buf.x, pt_buf.y)) pt_buf.list_m_loc_2d.append(mouse_loc_2d) mouse_loc_3d = region_2d_to_location_3d( context.region, context.space_data.region_3d, mouse_loc_2d, pt_buf.depth_location) pt_buf.list_m_loc_3d.append(mouse_loc_3d) pt_buf.depth_location = pt_buf.list_m_loc_3d[ -1] # <-- depth location # run Extrude at cursor if pt_buf.ctrl: try: bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source=False) except: pass elif event.value == 'RELEASE': pass elif event.type == 'RIGHTMOUSE': context.space_data.draw_handler_remove(self._handle_px, 'WINDOW') self.execute(context) pt_buf.sws = 'off' return {'FINISHED'} elif event.type == 'ESC': context.space_data.draw_handler_remove(self._handle_px, 'WINDOW') store_restore_view(context, False) pt_buf.list_m_loc_2d[:] = [] pt_buf.list_m_loc_3d[:] = [] pt_buf.depth_location = Vector((0.0, 0.0, 0.0)) pt_buf.sws = 'off' pt_buf.store_view_matrix = Matrix() pt_buf.view_location = (0.0, 0.0, 0.0) pt_buf.ctrl = False return {'CANCELLED'} # Return has to be modal or the tool can crash # It's better to define PASS_THROUGH as the exception and not the default return {'RUNNING_MODAL'}
def draw_callback_px(self, context): if context.mode == "EDIT_MESH": en0 = context.scene.dt_custom_props.en0 font_id = 0 font_size = context.scene.dt_custom_props.fs ob_act = context.active_object bme = bmesh.from_edit_mesh(ob_act.data) mtrx = ob_act.matrix_world list_0 = [v.index for v in bme.verts if v.select] if len(list_0) != 0: p = bme.verts[list_0[0]].co.copy() p_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, p) q = mtrx * bme.verts[list_0[0]].co.copy() q_loc_2d = location_3d_to_region_2d(context.region, context.space_data.region_3d, q) # -- -- -- -- distance to adjacent vertices if context.scene.dt_custom_props.b0 == True: list_ = [[v.index for v in e.verts] for e in bme.verts[list_0[0]].link_edges] for ek in list_: vi = [i for i in ek if i != list_0[0]][0] p1 = bme.verts[vi].co.copy() loc_0_3d = mtrx * ((p + p1) * 0.5) loc_0_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, loc_0_3d) bgl.glColor4f(1.0, 1.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, loc_0_2d[0] + 4, loc_0_2d[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round((p - p1).length, 4))) bgl.glLineStipple(4, 0xAAAA) bgl.glEnable(bgl.GL_LINE_STIPPLE) # -- -- -- -- distance to axis local global if context.scene.dt_custom_props.b1 == True: # -- -- -- -- local if en0 == 'opt0': # -- -- -- -- x axis px = mtrx * Vector((0.0, p[1], p[2])) px_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, px) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(px_loc_2d[0], px_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: lx = (q_loc_2d + px_loc_2d) * 0.5 bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, lx[0] + 4, lx[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round(p[0], 4))) # -- -- -- -- y axis py = mtrx * Vector((p[0], 0.0, p[2])) py_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, py) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(py_loc_2d[0], py_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: ly = (q_loc_2d + py_loc_2d) * 0.5 bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, ly[0] + 4, ly[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round(p[1], 4))) # -- -- -- -- z axis pz = mtrx * Vector((p[0], p[1], 0.0)) pz_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, pz) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(pz_loc_2d[0], pz_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: lz = (q_loc_2d + pz_loc_2d) * 0.5 bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, lz[0] + 4, lz[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round(p[2], 4))) # -- -- -- -- if context.scene.dt_custom_props.b2 == True and context.scene.dt_custom_props.b1 == True: blf.size(font_id, font_size, context.user_preferences.system.dpi) bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) blf.position( font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4 + font_size + 4, 0) blf.draw(font_id, 'x ' + str(round(p[0], 4))) bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4, 0) blf.draw(font_id, 'y ' + str(round(p[1], 4))) bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4, 0) blf.draw(font_id, 'z ' + str(round(p[2], 4))) # -- -- -- -- global elif en0 == 'opt1': # -- -- -- -- x axis ip_x = intersect_line_plane( q, q + (Vector((1.0, 0.0, 0.0)) * 0.1), Vector((0.0, 1.0, 0.0)), Vector((1.0, 0.0, 0.0))) ip_x_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, ip_x) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(ip_x_loc_2d[0], ip_x_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: loc_1_2d = (q_loc_2d + ip_x_loc_2d) * 0.5 bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, loc_1_2d[0] + 4, loc_1_2d[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round((q - ip_x).length, 4))) # -- -- -- -- y axis ip_y = intersect_line_plane( q, q + (Vector((0.0, 1.0, 0.0)) * 0.1), Vector((1.0, 0.0, 0.0)), Vector((0.0, 1.0, 0.0))) ip_y_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, ip_y) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(ip_y_loc_2d[0], ip_y_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: loc_2_2d = (q_loc_2d + ip_y_loc_2d) * 0.5 bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, loc_2_2d[0] + 4, loc_2_2d[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round((q - ip_y).length, 4))) # -- -- -- -- z axis ip_z = intersect_line_plane( q, q + (Vector((0.0, 0.0, 1.0)) * 0.1), Vector((1.0, 0.0, 0.0)), Vector((0.0, 0.0, 1.0))) ip_z_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, ip_z) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(q_loc_2d[0], q_loc_2d[1]) bgl.glVertex2f(ip_z_loc_2d[0], ip_z_loc_2d[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) if context.scene.dt_custom_props.b2 == False: loc_3_2d = (q_loc_2d + ip_z_loc_2d) * 0.5 bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, loc_3_2d[0] + 4, loc_3_2d[1] + 4, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round((q - ip_z).length, 4))) # -- -- -- -- if context.scene.dt_custom_props.b2 == True and context.scene.dt_custom_props.b1 == True: blf.size(font_id, font_size, context.user_preferences.system.dpi) bgl.glColor4f(1.0, 0.0, 0.0, context.scene.dt_custom_props.a) blf.position( font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4 + font_size + 4, 0) blf.draw(font_id, 'x ' + str(round((q - ip_x).length, 4))) bgl.glColor4f(0.0, 1.0, 0.0, context.scene.dt_custom_props.a) blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4 + font_size + 4, 0) blf.draw(font_id, 'y ' + str(round((q - ip_y).length, 4))) bgl.glColor4f(0.0, 0.0, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, q_loc_2d[0] + 4, q_loc_2d[1] + 4, 0) blf.draw(font_id, 'z ' + str(round((q - ip_z).length, 4))) # -- -- -- -- mouse location if context.scene.dt_custom_props.b4 == True: rgn = context.region # region rgn_3d = context.space_data.region_3d # region 3d bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(0, dt_buf.y) bgl.glVertex2f(dt_buf.x - 15, dt_buf.y) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(rgn.width, dt_buf.y) bgl.glVertex2f(dt_buf.x + 15, dt_buf.y) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(dt_buf.x, 0) bgl.glVertex2f(dt_buf.x, dt_buf.y - 15) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_BLEND) bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a) bgl.glBegin(bgl.GL_LINES) bgl.glVertex2f(dt_buf.x, rgn.height) bgl.glVertex2f(dt_buf.x, dt_buf.y + 15) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) bgl.glDisable(bgl.GL_LINE_STIPPLE) t = str(dt_buf.x) + ', ' + str(dt_buf.y) lo = region_2d_to_location_3d(context.region, context.space_data.region_3d, Vector((dt_buf.x, dt_buf.y)), Vector((0.0, 0.0, 0.0))) t1 = '( ' + str(round(lo[0], 4)) + ', ' + str(round( lo[1], 4)) + ', ' + str(round(lo[2], 4)) + ' )' bgl.glColor4f(1.0, 1.0, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, dt_buf.x + 15, dt_buf.y + 15, 0) blf.size(font_id, 14, context.user_preferences.system.dpi) blf.draw(font_id, t1 if context.scene.dt_custom_props.b5 == True else t) bgl.glDisable(bgl.GL_LINE_STIPPLE) # -- -- -- -- angles if context.scene.dt_custom_props.b3 == True: list_ek = [[v.index for v in e.verts] for e in bme.verts[list_0[0]].link_edges] n1 = len(list_ek) for j in range(n1): vec1 = p - bme.verts[[ i for i in list_ek[j] if i != list_0[0] ][0]].co.copy() vec2 = p - bme.verts[[ i for i in list_ek[(j + 1) % n1] if i != list_0[0] ][0]].co.copy() ang = vec1.angle(vec2) a_loc_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, mtrx * (((p - (vec1.normalized() * 0.1)) + (p - (vec2.normalized() * 0.1))) * 0.5)) bgl.glColor4f(0.0, 0.757, 1.0, context.scene.dt_custom_props.a) blf.position(font_id, a_loc_2d[0], a_loc_2d[1], 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw( font_id, str( round(ang, 4) if context.scene.dt_custom_props. b6 == True else round(degrees(ang), 2))) # -- -- -- -- tool on/off bgl.glColor4f(1.0, 1.0, 1.0, 1.0) blf.position(font_id, 150, 10, 0) blf.size(font_id, 20, context.user_preferences.system.dpi) blf.draw(font_id, 'Ruler On')
def draw_callback_px(self, context): font_id = 0 alpha = context.scene.pen_tool_props.a font_size = context.scene.pen_tool_props.fs bgl.glColor4f(0.0, 0.6, 1.0, alpha) bgl.glPointSize(4.0) bgl.glBegin(bgl.GL_POINTS) bgl.glVertex2f(pt_buf.x, pt_buf.y) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) # location 3d if context.scene.pen_tool_props.b2 is True: mloc3d = region_2d_to_location_3d(context.region, context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)), pt_buf.depth_location) blf.position(font_id, pt_buf.x + 15, pt_buf.y - 15, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw( font_id, '(' + str(round(mloc3d[0], 4)) + ', ' + str(round(mloc3d[1], 4)) + ', ' + str(round(mloc3d[2], 4)) + ')') n = len(pt_buf.list_m_loc_3d) if n != 0: # add points bgl.glEnable(bgl.GL_BLEND) bgl.glPointSize(4.0) bgl.glBegin(bgl.GL_POINTS) for i in pt_buf.list_m_loc_3d: loc_0 = location_3d_to_region_2d(context.region, context.space_data.region_3d, i) bgl.glVertex2f(loc_0[0], loc_0[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) # text next to the mouse m_loc_3d = region_2d_to_location_3d(context.region, context.space_data.region_3d, Vector((pt_buf.x, pt_buf.y)), pt_buf.depth_location) vec0 = pt_buf.list_m_loc_3d[-1] - m_loc_3d blf.position(font_id, pt_buf.x + 15, pt_buf.y + 15, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round(vec0.length, 4))) # angle first after mouse if n >= 2: vec1 = pt_buf.list_m_loc_3d[-2] - pt_buf.list_m_loc_3d[-1] if vec0.length == 0.0 or vec1.length == 0.0: pass else: ang = vec0.angle(vec1) if round(degrees(ang), 2) == 180.0: text_0 = '0.0' elif round(degrees(ang), 2) == 0.0: text_0 = '180.0' else: text_0 = str(round(degrees(ang), 2)) loc_4 = location_3d_to_region_2d(context.region, context.space_data.region_3d, pt_buf.list_m_loc_3d[-1]) bgl.glColor4f(0.0, 1.0, 0.525, alpha) blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, text_0 + '') bgl.glLineStipple(4, 0x5555) bgl.glEnable(bgl.GL_LINE_STIPPLE) # enable line stipple bgl.glColor4f(0.0, 0.6, 1.0, alpha) # draw line between last point and mouse bgl.glEnable(bgl.GL_BLEND) bgl.glBegin(bgl.GL_LINES) loc_1 = location_3d_to_region_2d(context.region, context.space_data.region_3d, pt_buf.list_m_loc_3d[-1]) bgl.glVertex2f(loc_1[0], loc_1[1]) bgl.glVertex2f(pt_buf.x, pt_buf.y) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) # draw lines between points bgl.glEnable(bgl.GL_BLEND) bgl.glBegin(bgl.GL_LINE_STRIP) for j in pt_buf.list_m_loc_3d: loc_2 = location_3d_to_region_2d(context.region, context.space_data.region_3d, j) bgl.glVertex2f(loc_2[0], loc_2[1]) bgl.glEnd() bgl.glDisable(bgl.GL_BLEND) bgl.glDisable(bgl.GL_LINE_STIPPLE) # disable line stipple # draw line length between points if context.scene.pen_tool_props.b1 is True: for k in range(n - 1): loc_3 = location_3d_to_region_2d( context.region, context.space_data.region_3d, (pt_buf.list_m_loc_3d[k] + pt_buf.list_m_loc_3d[(k + 1) % n]) * 0.5) blf.position(font_id, loc_3[0] + 10, loc_3[1] + 10, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw( font_id, str( round((pt_buf.list_m_loc_3d[k] - pt_buf.list_m_loc_3d[(k + 1) % n]).length, 4))) # draw all angles if context.scene.pen_tool_props.b0 is True: for h in range(n - 1): if n >= 2: if h == 0: pass else: vec_ = pt_buf.list_m_loc_3d[h] - pt_buf.list_m_loc_3d[ (h - 1) % n] vec_1_ = pt_buf.list_m_loc_3d[h] vec_2_ = pt_buf.list_m_loc_3d[(h - 1) % n] if vec_.length == 0.0 or vec_1_.length == 0.0 or vec_2_.length == 0.0: pass else: ang = vec_.angle(vec_1_ - vec_2_) if round(degrees(ang)) == 0.0: pass else: loc_4 = location_3d_to_region_2d( context.region, context.space_data.region_3d, pt_buf.list_m_loc_3d[h]) bgl.glColor4f(0.0, 1.0, 0.525, alpha) blf.position(font_id, loc_4[0] + 10, loc_4[1] + 10, 0) blf.size(font_id, font_size, context.user_preferences.system.dpi) blf.draw(font_id, str(round(degrees(ang), 2)) + '') # tools on / off bgl.glColor4f(1.0, 1.0, 1.0, 1.0) blf.position(font_id, self.text_location, 20, 0) blf.size(font_id, 15, context.user_preferences.system.dpi) blf.draw(font_id, "Draw On") blf.position(font_id, self.text_location, 40, 0) blf.draw(font_id, "Extrude On" if pt_buf.ctrl else "Extrude Off")
def location_to_region(worldcoords): from bpy_extras import view3d_utils return view3d_utils.location_3d_to_region_2d( bpy.context.region, bpy.context.space_data.region_3d, worldcoords)
def draw_IDs(self, context, obj): """ This method draws Verse IDs of vertices, edges and faces """ font_id, font_size, my_dpi = 0, 12, 72 self.update_references() vert_id_layer = self.bmesh.verts.layers.int.get('VertIDs') edge_id_layer = self.bmesh.edges.layers.int.get('EdgeIDs') face_id_layer = self.bmesh.faces.layers.int.get('FaceIDs') bgl.glColor3f(1.0, 1.0, 0.0) for vert_id, vert_co in self.vertices.items.items(): coord_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, obj.matrix_world * mathutils.Vector(vert_co)) b3d_vert = self.vertices.b3d_vertex(vert_id) if b3d_vert is not None: b3d_vert_id = b3d_vert[vert_id_layer] else: b3d_vert_id = None # When coordinates are not outside window, then draw the ID of vertex if coord_2d is not None: blf.size(font_id, font_size, my_dpi) blf.position(font_id, coord_2d[0] + 2, coord_2d[1] + 2, 0) blf.draw(font_id, str((vert_id, b3d_vert_id))) bgl.glColor3f(0.0, 1.0, 0.0) for edge_id, edge_verts in self.edges.items.items(): vert1 = self.vertices.items[edge_verts[0]] vert2 = self.vertices.items[edge_verts[1]] edge_co = mathutils.Vector(( (vert2[0] + vert1[0]) / 2.0, (vert2[1] + vert1[1]) / 2.0, (vert2[2] + vert1[2]) / 2.0)) b3d_edge = self.edges.b3d_edge(edge_id) if b3d_edge is not None: b3d_edge_id = b3d_edge[edge_id_layer] else: b3d_edge_id = None coord_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, obj.matrix_world * edge_co) # When coordinates are not outside window, then draw the ID of edge if coord_2d is not None: blf.size(font_id, font_size, my_dpi) blf.position(font_id, coord_2d[0] + 2, coord_2d[1] + 2, 0) blf.draw(font_id, str((edge_id, b3d_edge_id))) bgl.glColor3f(0.0, 1.0, 1.0) for face_id, face_verts in self.quads.items.items(): if face_verts[3] == 0: vert1 = self.vertices.items[face_verts[0]] vert2 = self.vertices.items[face_verts[1]] vert3 = self.vertices.items[face_verts[2]] face_co = mathutils.Vector(( (vert1[0] + vert2[0] + vert3[0]) / 3.0, (vert1[1] + vert2[1] + vert3[1]) / 3.0, (vert1[2] + vert2[2] + vert3[2]) / 3.0 )) else: vert1 = self.vertices.items[face_verts[0]] vert2 = self.vertices.items[face_verts[1]] vert3 = self.vertices.items[face_verts[2]] vert4 = self.vertices.items[face_verts[3]] face_co = mathutils.Vector(( (vert1[0] + vert2[0] + vert3[0] + vert4[0]) / 4.0, (vert1[1] + vert2[1] + vert3[1] + vert4[1]) / 4.0, (vert1[2] + vert2[2] + vert3[2] + vert4[2]) / 4.0 )) b3d_face = self.quads.find_b3d_face(face_id) if b3d_face is not None: b3d_face_id = b3d_face[face_id_layer] else: b3d_face_id = None coord_2d = location_3d_to_region_2d( context.region, context.space_data.region_3d, obj.matrix_world * face_co) # When coordinates are not outside window, then draw the ID of face if coord_2d is not None: blf.size(font_id, font_size, my_dpi) blf.position(font_id, coord_2d[0] + 2, coord_2d[1] + 2, 0) blf.draw(font_id, str((face_id, b3d_face_id)))
def modal(self, context, event): context.area.tag_redraw() # Tooltip tooltip_text = "Shift: Scale Constraint; Ctrl+MouseWheel, Ctrl+Shift+MouseWheel, +-, Ctrl++, ctrl+-: Change Segments; Shift+LeftClick: Uniform Scale; C: CenterCursor; O: Orient on Surface; R: Rotate, S: Scale" context.area.header_text_set(tooltip_text) m_coords = event.mouse_region_x, event.mouse_region_y rv3d = context.region_data if event.type in {'MIDDLEMOUSE'}: # allow navigation return {'PASS_THROUGH'} elif event.type == 'O' and event.value == 'PRESS': if self.orient_on_surface: self.orient_on_surface = False else: self.orient_on_surface = True return {'RUNNING_MODAL'} elif event.type == 'C' and event.value == 'PRESS': if self.center_is_cursor: self.center_is_cursor = False else: self.center_is_cursor = True return {'RUNNING_MODAL'} elif event.type == 'M' and event.value == 'PRESS': if self.median_center: self.median_center = False else: self.median_center = True return {'RUNNING_MODAL'} elif event.type == 'R' and event.value == 'PRESS': if self.new_prim: if self.tool_mode == 'ROTATE': self.tool_mode = self.tool_mode_before_deform self.tool_mode_before_deform = None return {'RUNNING_MODAL'} else: self.deform_mouse_pos = m_coords self.tool_mode_before_deform = self.tool_mode self.tool_mode = 'ROTATE' else: return {'RUNNING_MODAL'} return {'RUNNING_MODAL'} elif event.type == 'S' and event.value == 'PRESS': if self.new_prim: if self.tool_mode == 'SCALE': self.tool_mode = self.tool_mode_before_deform self.tool_mode_before_deform = None return {'RUNNING_MODAL'} else: self.deform_mouse_pos = m_coords self.tool_mode_before_deform = self.tool_mode self.tool_mode = 'SCALE' else: return {'RUNNING_MODAL'} return {'RUNNING_MODAL'} elif event.type == 'Z' and event.value == 'PRESS' and event.ctrl: # delete object with Ctrl+Z if self.history_objects: del_obj = self.history_objects[-1][0] del self.history_objects[-1] # remove old primitive objs = bpy.data.objects objs.remove(objs[del_obj.name], True) self.new_prim = None self.hit_pos = None self.hit_dir = None self.prim_side_vec = None self.prim_front_vec = None self.tool_mode = 'IDLE' context.scene.update() context.area.tag_redraw() return {'RUNNING_MODAL'} elif event.type in { 'WHEELUPMOUSE', 'WHEELDOWNMOUSE', 'NUMPAD_MINUS', 'MINUS', 'NUMPAD_PLUS', 'EQUAL' }: # just pass it if cloning if self.prim_type == 'Clone': if event.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}: # allow navigation return {'PASS_THROUGH'} else: return {'RUNNING_MODAL'} # CHANGE SEGMENTS HERE if self.new_prim: if event.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}: if event.ctrl: # Meka less/more segments if event.type == 'WHEELUPMOUSE': if self.prim_type == 'Sphere': if event.shift: self.sphere_segments[ 1] = self.sphere_segments[1] + 1 else: self.sphere_segments[ 0] = self.sphere_segments[0] + 1 elif self.prim_type == 'Capsule': if event.shift: self.capsule_segments[ 1] = self.capsule_segments[1] + 1 else: self.capsule_segments[ 0] = self.capsule_segments[0] + 1 else: self.circle_segments[0] += 1 else: if self.prim_type == 'Sphere': if event.shift: self.sphere_segments[ 1] = self.sphere_segments[1] - 1 self.sphere_segments[1] = max( self.sphere_segments[1], 3) else: self.sphere_segments[ 0] = self.sphere_segments[0] - 1 self.sphere_segments[0] = max( self.sphere_segments[0], 3) elif self.prim_type == 'Capsule': if event.shift: self.capsule_segments[ 1] = self.capsule_segments[1] - 1 self.capsule_segments[1] = max( self.capsule_segments[1], 1) else: self.capsule_segments[ 0] = self.capsule_segments[0] - 1 self.capsule_segments[0] = max( self.capsule_segments[0], 3) else: self.circle_segments[0] -= 1 self.circle_segments[0] = max( self.circle_segments[0], 3) else: # allow navigation return {'PASS_THROUGH'} elif event.type in {'NUMPAD_PLUS', 'EQUAL' } and event.value == 'PRESS': if self.prim_type == 'Sphere': if event.ctrl: self.sphere_segments[ 1] = self.sphere_segments[1] + 1 else: self.sphere_segments[ 0] = self.sphere_segments[0] + 1 elif self.prim_type == 'Capsule': if event.ctrl: self.capsule_segments[ 1] = self.capsule_segments[1] + 1 else: self.capsule_segments[ 0] = self.capsule_segments[0] + 1 else: self.circle_segments[0] += 1 elif event.type in {'NUMPAD_MINUS', 'MINUS' } and event.value == 'PRESS': if self.prim_type == 'Sphere': if event.ctrl: self.sphere_segments[ 1] = self.sphere_segments[1] - 1 self.sphere_segments[1] = max( self.sphere_segments[1], 3) else: self.sphere_segments[ 0] = self.sphere_segments[0] - 1 self.sphere_segments[0] = max( self.sphere_segments[0], 3) elif self.prim_type == 'Capsule': if event.ctrl: self.capsule_segments[ 1] = self.capsule_segments[1] - 1 self.capsule_segments[1] = max( self.capsule_segments[1], 1) else: self.capsule_segments[ 0] = self.capsule_segments[0] - 1 self.capsule_segments[0] = max( self.capsule_segments[0], 3) else: self.circle_segments[0] -= 1 self.circle_segments[0] = max(self.circle_segments[0], 3) if self.prim_type in {'Sphere', 'Capsule'}: del self.history_objects[-1] # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) segments = self.sphere_segments if self.prim_type == 'Capsule': segments = self.capsule_segments # Replace Object Primitive if self.tool_mode == 'IDLE': self.new_prim = replace_prim(self.new_prim, segments, self.prim_type, context) else: self.new_prim = replace_prim(self.new_prim, segments, 'Circle', context) self.history_objects.append([self.new_prim, self.hit_pos]) # If Edit Mode if self.edit_obj: bpy.ops.object.select_all(action='DESELECT') self.new_prim.show_wire = True self.new_prim.show_all_edges = True self.edit_obj.select = True context.scene.objects.active = self.edit_obj bpy.ops.object.mode_set(mode='EDIT', toggle=False) else: del self.history_objects[-1] # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # Replace Object Primitive if self.tool_mode == 'IDLE': self.new_prim = replace_prim(self.new_prim, self.circle_segments, self.prim_type, context) else: if self.prim_type == 'Cube' or self.prim_type == 'Plane': self.new_prim = replace_prim( self.new_prim, self.circle_segments, 'Plane', context) else: self.new_prim = replace_prim( self.new_prim, self.circle_segments, 'Circle', context) self.history_objects.append([self.new_prim, self.hit_pos]) # If Edit Mode if self.edit_obj: bpy.ops.object.select_all(action='DESELECT') self.new_prim.show_wire = True self.new_prim.show_all_edges = True self.edit_obj.select = True context.scene.objects.active = self.edit_obj bpy.ops.object.mode_set(mode='EDIT', toggle=False) else: # allow navigation return {'PASS_THROUGH'} # FINISH THE TOOL! elif event.type in {'RIGHTMOUSE', 'ESC'}: # If Edit Mode. Join Primitives if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.select_all(action='DESELECT') for his_obj in self.history_objects: his_obj[0].select = True self.edit_obj.select = True context.scene.objects.active = self.edit_obj bpy.ops.object.join() bpy.ops.object.mode_set(mode='EDIT', toggle=False) # For non Edit Mode else: #bpy.ops.object.select_all(action='DESELECT') cursor_origin = context.scene.cursor_location.copy() for his_obj in self.history_objects: bpy.ops.object.select_all(action='DESELECT') his_obj[0].select = True # apply scale if self.prim_type != 'Clone': context.scene.objects.active = his_obj[0] bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) # set object position to hit if his_obj[0].location != his_obj[1]: context.scene.cursor_location = his_obj[1].copy() bpy.ops.object.origin_set(type='ORIGIN_CURSOR') # apply/fix rotation if round(math.degrees(his_obj[0].rotation_euler.x)) in { -0.0, 0.0, 90.0, 180.0, -180.0, -90.0 }: if round(math.degrees( his_obj[0].rotation_euler.y)) in { -0.0, 0.0, 90.0, 180.0, -180.0, -90.0 }: if round(math.degrees( his_obj[0].rotation_euler.z)) in { -0.0, 0.0, 90.0, 180.0, -180.0, -90.0 }: bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) context.scene.cursor_location = cursor_origin bpy.ops.object.select_all(action='DESELECT') # clean clean(context, self) context.area.header_text_set() bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') self.tool_mode == 'IDLE' return {'FINISHED'} # LEFTMOUSE CLICK if event.type == 'LEFTMOUSE': if self.tool_mode in {'ROTATE', 'SCALE'}: return {'RUNNING_MODAL'} if self.tool_mode == 'IDLE' and event.value == 'PRESS': do_create_prim = False # check if we found hit is_autoaxis = False # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # make raycast only one time! ray_result = ut_base.get_mouse_raycast(context, self.obj_matrices, m_coords) # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='EDIT', toggle=False) if ray_result[ 0] and self.orient_on_surface and not self.center_is_cursor: self.hit_pos = ray_result[2].copy() self.hit_dir = ray_result[1].copy().normalized() do_create_prim = True else: # make auto pick according to 3d cursor if ray_result[ 0] and not self.orient_on_surface and not self.center_is_cursor: ray_result_auto = auto_pick(context, ray_result[2], event) else: ray_result_auto = auto_pick(context, None, event) if self.center_is_cursor: self.hit_pos = context.scene.cursor_location else: self.hit_pos = ray_result_auto[0].copy() self.hit_dir = ray_result_auto[1].copy().normalized() do_create_prim = True is_autoaxis = True # CREATE PRIMITIVE! if do_create_prim: # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # Do Create Primitive if self.prim_type == 'Sphere': new_prim = create_prim(context, event, self.hit_pos, self.hit_dir, self.sphere_segments, is_autoaxis, 'Circle', self) elif self.prim_type == 'Capsule': new_prim = create_prim(context, event, self.hit_pos, self.hit_dir, self.capsule_segments, is_autoaxis, 'Circle', self) elif self.prim_type in {'Cube', 'Plane'}: new_prim = create_prim(context, event, self.hit_pos, self.hit_dir, None, is_autoaxis, 'Plane', self) elif self.prim_type == 'Clone': new_prim = create_prim(context, event, self.hit_pos, self.hit_dir, None, is_autoaxis, 'Clone', self) else: new_prim = create_prim(context, event, self.hit_pos, self.hit_dir, self.circle_segments, is_autoaxis, 'Circle', self) self.new_prim = new_prim[0] self.history_objects.append([self.new_prim, self.hit_pos]) self.prim_side_vec = new_prim[1].copy() self.prim_front_vec = new_prim[2].copy() self.tool_mode = 'DRAW_1' # If Edit Mode if self.edit_obj: bpy.ops.object.select_all(action='DESELECT') self.new_prim.show_wire = True self.new_prim.show_all_edges = True self.edit_obj.select = True context.scene.objects.active = self.edit_obj bpy.ops.object.mode_set(mode='EDIT', toggle=False) # Change tool state to Draw_2. Create depth elif self.tool_mode == 'IDLE_2' and event.value == 'PRESS': # If Edit Mode if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # Replace Plane and Circle del self.history_objects[-1] if self.prim_type == 'Sphere': self.new_prim = replace_prim(self.new_prim, self.sphere_segments, self.prim_type, context) elif self.prim_type == 'Capsule': self.new_prim = replace_prim(self.new_prim, self.capsule_segments, self.prim_type, context) else: self.new_prim = replace_prim(self.new_prim, self.circle_segments, self.prim_type, context) self.history_objects.append([self.new_prim, self.hit_pos]) # If Edit Mode if self.edit_obj: bpy.ops.object.select_all(action='DESELECT') self.new_prim.show_wire = True self.new_prim.show_all_edges = True self.edit_obj.select = True context.scene.objects.active = self.edit_obj bpy.ops.object.mode_set(mode='EDIT', toggle=False) self.tool_mode = 'DRAW_2' if event.value == 'RELEASE': # change tool state. Wait for Draw_2 state if self.tool_mode == 'DRAW_1': # set to IDLE if this is Plane Primitive if self.prim_type in {'Plane', 'Circle', 'Clone'}: self.tool_mode = 'IDLE' return {'RUNNING_MODAL'} if self.new_prim.scale[0] == 0 or self.new_prim.scale[ 1] == 0: # remove primitive with 0,0,0 scale objs = bpy.data.objects del self.history_objects[-1] objs.remove(objs[self.new_prim.name], True) self.new_prim = None self.prim_side_vec = None self.prim_front_vec = None self.tool_mode = 'IDLE' else: self.tool_mode = 'IDLE_2' else: # go to standard state self.tool_mode = 'IDLE' # TOOL WORK # Draw Primitive X and Y if self.tool_mode == 'DRAW_1': plane_pos = ut_base.get_mouse_on_plane(context, self.hit_pos, self.hit_dir, m_coords) if plane_pos: if event.shift: if self.prim_type == 'Clone': self.new_prim.scale = self.objects_to_clone[ 0].scale.copy() else: # Make the same scale with Shift key new_dist = (plane_pos - self.hit_pos).length self.new_prim.scale[0] = new_dist self.new_prim.scale[1] = new_dist else: if self.prim_type == 'Clone': new_dist = (plane_pos - self.hit_pos).length self.new_prim.scale[ 0] = self.objects_to_clone[0].scale[0] * new_dist self.new_prim.scale[ 1] = self.objects_to_clone[0].scale[1] * new_dist self.new_prim.scale[ 2] = self.objects_to_clone[0].scale[2] * new_dist else: dist_x = mathu.geometry.distance_point_to_plane( plane_pos, self.hit_pos, self.prim_side_vec) dist_y = mathu.geometry.distance_point_to_plane( plane_pos, self.hit_pos, self.prim_front_vec) self.new_prim.scale[0] = abs(dist_x) self.new_prim.scale[1] = abs(dist_y) # Draw Primitive Z Depth elif self.tool_mode == 'DRAW_2': if event.shift: # Make the same scale with Shift key new_dist = self.new_prim.scale[0] if self.new_prim.scale[0] < self.new_prim.scale[1]: new_dist = self.new_prim.scale[1] if not self.median_center: self.new_prim.scale[2] = new_dist # set new location mult_vec = self.hit_dir.copy() mult_vec[0] *= (new_dist) mult_vec[1] *= (new_dist) mult_vec[2] *= (new_dist) self.new_prim.location = self.hit_pos + mult_vec else: self.new_prim.scale[2] = new_dist else: view_front_vec = rv3d.view_rotation * Vector( (0.0, 0.0, -1.0)).normalized() plane_pos = ut_base.get_mouse_on_plane(context, self.hit_pos, view_front_vec, m_coords) new_dist = (plane_pos - self.hit_pos).length if not self.median_center: self.new_prim.scale[2] = abs(new_dist) / 2 # set new location mult_vec = self.hit_dir.copy() mult_vec[0] *= (new_dist / 2) mult_vec[1] *= (new_dist / 2) mult_vec[2] *= (new_dist / 2) self.new_prim.location = self.hit_pos + mult_vec else: self.new_prim.scale[2] = (abs(new_dist) / 2) * 2 # Rotate Primitive elif self.tool_mode == 'ROTATE': obj_pos_2d = view3d_utils.location_3d_to_region_2d( context.region, rv3d, self.new_prim.location) if obj_pos_2d: new_prim_mat = self.new_prim.matrix_world v1 = Vector(self.deform_mouse_pos) - obj_pos_2d v1 = Vector((v1[0], v1[1], 0)).normalized() v2 = Vector(m_coords) - obj_pos_2d v2 = Vector((v2[0], v2[1], 0)).normalized() rot_angle = v1.angle(v2) if rot_angle != 0: # check if negative angle if v1.cross(v2)[2] < 0: rot_angle = -rot_angle rot_axis = (new_prim_mat[0][2], new_prim_mat[1][2], new_prim_mat[2][2]) # if edit obj if self.edit_obj: bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.select_all(action='DESELECT') act_temp = context.scene.objects.active #temp_sel = self.new_prim.select self.new_prim.select = True context.scene.objects.active = self.new_prim # do rotation bpy.ops.transform.rotate(value=rot_angle, axis=rot_axis) self.deform_mouse_pos = m_coords # if edit obj if self.edit_obj: self.new_prim.select = False context.scene.objects.active = act_temp bpy.ops.object.mode_set(mode='EDIT', toggle=False) # Rotate Primitive elif self.tool_mode == 'SCALE': obj_pos_2d = view3d_utils.location_3d_to_region_2d( context.region, rv3d, self.new_prim.location) if obj_pos_2d: v1 = Vector(self.deform_mouse_pos) - obj_pos_2d v2 = Vector(m_coords) - obj_pos_2d # do scale self.new_prim.scale *= (v2.length / v1.length) self.deform_mouse_pos = m_coords # fix position for non median primitives if not self.median_center and self.tool_mode_before_deform == 'IDLE' and self.prim_type != 'Clone': mult_vec = self.hit_dir.copy() mult_vec[0] *= (self.new_prim.scale[2]) mult_vec[1] *= (self.new_prim.scale[2]) mult_vec[2] *= (self.new_prim.scale[2]) self.new_prim.location = self.hit_pos + mult_vec return {'RUNNING_MODAL'}
def display_distance_between_two_points(region, rv3d, p1_3d, p2_3d): size_num = addon_settings_graph('size_num') scale_dist = addon_settings_graph('scale_dist') suffix_dist = addon_settings_graph('suffix_dist') if type(p1_3d) is not Vector: p1_3d = Vector(p1_3d) if type(p2_3d) is not Vector: p2_3d = Vector(p2_3d) p1_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, p1_3d) p2_2d = view3d_utils.location_3d_to_region_2d(region, rv3d, p2_3d) if p1_2d is None: p1_2d = 0.0, 0.0 p2_2d = 0.0, 0.0 def get_pts_mean(locs2d, max): res = 0 for i in locs2d: if i > max: res += max elif i > 0: res += i return res / 2 mean_x = get_pts_mean((p1_2d[0], p2_2d[0]), region.width) mean_y = get_pts_mean((p1_2d[1], p2_2d[1]), region.height) distloc = mean_x, mean_y dist_3d = (p2_3d - p1_3d).length dist_3d_rnd = abs(round(dist_3d, 2)) dist = str(dist_3d_rnd) dist_num = (p2_3d - p1_3d).length * scale_dist dist_num = abs(round(dist_num, 2)) if suffix_dist != 'None': dist = str(dist_num) + suffix_dist else: dist = str(dist_num) col_num_main = addon_settings_graph('col_num_main') col_num_shadow = addon_settings_graph('col_num_shadow') #np_print('dist = ', dist, 'distloc = ', distloc, 'dist_num = ', dist_num) if dist_num not in (0, 'a'): bgl.glColor4f(*col_num_shadow) font_id = 0 blf.size(font_id, size_num, 72) blf.position(font_id, (distloc[0] - 1), (distloc[1] - 1), 0) blf.draw(font_id, dist) bgl.glColor4f(*col_num_main) font_id = 0 blf.size(font_id, size_num, 72) blf.position(font_id, distloc[0], distloc[1], 0) blf.draw(font_id, dist) return (dist_num, dist)
def to2d(coords): return view3d_utils.location_3d_to_region_2d(*getRegionData(), coords)
def expand_vert(self, context, event): addon_prefs = context.preferences.addons[__name__].preferences ob = context.active_object obj = bpy.context.object me = obj.data bm = bmesh.from_edit_mesh(me) region = context.region region_3d = context.space_data.region_3d rv3d = context.space_data.region_3d for v in bm.verts: if v.select: v_active = v try: depth_location = v_active.co except: return {'CANCELLED'} # create vert in mouse cursor location mouse_pos = Vector((event.mouse_region_x, event.mouse_region_y)) location_3d = view3d_utils.region_2d_to_location_3d( region, rv3d, mouse_pos, depth_location) c_verts = [] # find and select linked edges that are open (<2 faces connected) add those edge verts to c_verts list linked = v_active.link_edges for edges in linked: if len(edges.link_faces) < 2: edges.select = True for v in edges.verts: if v is not v_active: c_verts.append(v) # Compare distance in 2d between mouse and edges middle points screen_pos_va = view3d_utils.location_3d_to_region_2d( region, region_3d, ob.matrix_world @ v_active.co) screen_pos_v1 = view3d_utils.location_3d_to_region_2d( region, region_3d, ob.matrix_world @ c_verts[0].co) screen_pos_v2 = view3d_utils.location_3d_to_region_2d( region, region_3d, ob.matrix_world @ c_verts[1].co) mid_pos_v1 = Vector(((screen_pos_va[0] + screen_pos_v1[0]) / 2, (screen_pos_va[1] + screen_pos_v1[1]) / 2)) mid_pos_V2 = Vector(((screen_pos_va[0] + screen_pos_v2[0]) / 2, (screen_pos_va[1] + screen_pos_v2[1]) / 2)) dist1 = math.log10( pow((mid_pos_v1[0] - mouse_pos[0]), 2) + pow((mid_pos_v1[1] - mouse_pos[1]), 2)) dist2 = math.log10( pow((mid_pos_V2[0] - mouse_pos[0]), 2) + pow((mid_pos_V2[1] - mouse_pos[1]), 2)) bm.normal_update() bm.verts.ensure_lookup_table() # Deselect not needed point and create new face if dist1 < dist2: c_verts[1].select = False lleft = c_verts[0].link_faces else: c_verts[0].select = False lleft = c_verts[1].link_faces lactive = v_active.link_faces # lverts = lactive[0].verts mat_index = lactive[0].material_index smooth = lactive[0].smooth for faces in lactive: if faces in lleft: cface = faces if len(faces.verts) == 3: bm.normal_update() bmesh.update_edit_mesh(obj.data) bpy.ops.mesh.select_all(action='DESELECT') v_active.select = True bpy.ops.mesh.rip_edge_move('INVOKE_DEFAULT') return {'FINISHED'} lverts = cface.verts # create triangle with correct normal orientation # if You looking at that part - yeah... I know. I still dont get how blender calculates normals... # from L to R if dist1 < dist2: if (lverts[0] == v_active and lverts[3] == c_verts[0]) \ or (lverts[2] == v_active and lverts[1] == c_verts[0]) \ or (lverts[1] == v_active and lverts[0] == c_verts[0]) \ or (lverts[3] == v_active and lverts[2] == c_verts[0]): v_new = bm.verts.new(v_active.co) face_new = bm.faces.new((c_verts[0], v_new, v_active)) elif (lverts[1] == v_active and lverts[2] == c_verts[0]) \ or (lverts[0] == v_active and lverts[1] == c_verts[0]) \ or (lverts[3] == v_active and lverts[0] == c_verts[0]) \ or (lverts[2] == v_active and lverts[3] == c_verts[0]): v_new = bm.verts.new(v_active.co) face_new = bm.faces.new((v_active, v_new, c_verts[0])) else: pass # from R to L else: if (lverts[2] == v_active and lverts[3] == c_verts[1]) \ or (lverts[0] == v_active and lverts[1] == c_verts[1]) \ or (lverts[1] == v_active and lverts[2] == c_verts[1]) \ or (lverts[3] == v_active and lverts[0] == c_verts[1]): v_new = bm.verts.new(v_active.co) face_new = bm.faces.new((v_active, v_new, c_verts[1])) elif (lverts[0] == v_active and lverts[3] == c_verts[1]) \ or (lverts[2] == v_active and lverts[1] == c_verts[1]) \ or (lverts[1] == v_active and lverts[0] == c_verts[1]) \ or (lverts[3] == v_active and lverts[2] == c_verts[1]): v_new = bm.verts.new(v_active.co) face_new = bm.faces.new((c_verts[1], v_new, v_active)) else: pass # set smooth and mat based on starting face if addon_prefs.tris_from_v_mat: face_new.material_index = bpy.context.object.active_material_index else: face_new.material_index = mat_index face_new.smooth = smooth # update normals bpy.ops.mesh.select_all(action='DESELECT') v_new.select = True bm.select_history.add(v_new) bm.normal_update() bmesh.update_edit_mesh(obj.data) bpy.ops.transform.translate('INVOKE_DEFAULT')