def pick_voxel(self, context, event, voxelarray):
        """Run this function on left mouse, execute the ray cast
        TODO: report/go through some problems with selecting in the
        operator_modal_view3d_raycast.py. Most of the problem is
        when trying to click close to the edge of the object.
        The distance values are often mucked up"""
        # get the context arguments
        ray_max=10000.0
        region = context.region
        rv3d = context.region_data
        coord = event.mouse_region_x, event.mouse_region_y

        # get the ray from the viewport and mouse
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * ray_max)
        #TODO: raise some kind of error, or do a check/poll on this operator
        #to ensure that there has been a voxel array created and selected

        isects = voxelarray.intersect_ray(ray_origin, ray_target)

        best_dist_squared = ray_max * ray_max
        best_isect = None

        if isects is None:
            return None

        for isect in isects:
            dist_squared = isect.dist_squared
            if(dist_squared < best_dist_squared):
                best_dist_squared = dist_squared
                best_isect = isect

        return best_isect
 def click_add_seed(self,context,x,y):
     '''
     x,y = event.mouse_region_x, event.mouse_region_y
     
     this will add a point into the bezier curve or
     close the curve into a cyclic curve
     '''
     region = context.region
     rv3d = context.region_data
     coord = x, y
     view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
     ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
     ray_target = ray_origin + (view_vector * 1000)
     mx = self.cut_ob.matrix_world
     imx = mx.inverted()
     
     if bversion() < '002.077.000':
         loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
     else:
         res, loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target - imx * ray_origin)
     
     if face_ind == -1: 
         self.selected = -1
         return
     
     self.seed = self.bme.faces[face_ind]
     self.seed_loc = loc
     
     self.geo_data = [dict(), set(), set(), set()]
    def click_add_target(self, context, x, y):
        
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)
        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)

        if face_ind == -1: return
            
            
        self.target = self.bme.faces[face_ind]
        self.target_loc = loc
        
        
        geos, fixed, close, far = geodesic_walk(self.bme, self.seed, self.seed_loc, 
                                                targets = [self.target], subset = None, max_iters = 100000,
                                                min_dist = None)
        
        path_elements, self.path  = gradient_descent(self.bme, geos, 
                                self.target, self.target_loc, epsilon = .0000001)
        
        self.geo_data = [geos, fixed, close, far]
        return
    def set_ray_from_region(self, x, y):
        context = bpy.context
        mesh_object = self.mesh_object
        region = context.region
        region_co = Vector((x, y))
        rv3d = context.region_data
        sv3d = context.space_data

        # Determine the view's clipping distances.
        if rv3d.view_perspective == 'CAMERA':
            camera_data = sv3d.camera.data
            clip_start = camera_data.clip_start
            clip_end = camera_data.clip_end
        else:
            clip_start = sv3d.clip_start
            clip_end = sv3d.clip_end

        # Determine the ray's direction in world space.
        ray_direction = view3d_utils.region_2d_to_vector_3d(
            region, rv3d, region_co
        )

        # For orthographic projections in Blender versions prior to 2.72, the
        # ray's direction needs to be inverted to point into the scene.
        if bpy.app.version < (2, 72, 0):
            if rv3d.view_perspective == 'ORTHO' or (
                   rv3d.view_perspective == 'CAMERA' and
                   sv3d.camera.data.type == 'ORTHO'
               ):
                ray_direction *= -1

        # Determine the ray's origin in world space.
        ray_origin =\
            view3d_utils.region_2d_to_origin_3d(region, rv3d, region_co)

        # Determine the ray's target in world space.
        ray_target = ray_origin + clip_end * ray_direction

        # If the view is an orthographic projection, the ray's origin may exist
        # behind the mesh object.  Therefore, it is necessary to move the ray's
        # origin a sufficient distance antiparallel to the ray's direction to
        # ensure that the ray's origin is in front of the mesh object.
        if rv3d.view_perspective == 'ORTHO':
            ray_origin -= 10000 * ray_direction

        # Otherwise, if the view is a perspective projection or projected from
        # a camera then advance the ray's origin to the near clipping plane.
        else:
            ray_origin += clip_start * ray_direction

        # Convert the ray's origin and target from world space to object space,
        # if necessary.
        if self.coordinate_system == 'OBJECT':
            inverse_model_matrix = mesh_object.matrix_world.inverted()
            for co in ray_origin, ray_target:
                co.xyz = inverse_model_matrix * co

        # Set the ray caster object's ray attributes.
        self.ray_origin = ray_origin
        self.ray_target = ray_target
Exemple #5
0
def pick_object(region, rv3d, x, y, near, far, objects):
    '''
    Selects an object underneath given screen coordinates

    Parameters:
        region (bpy.types.Region): Section of the UI in which to do picking
        rv3d (bpy.types.RegionView3D): 3D view region data
        near (float): Near clipping plane
        far (float): Far clipping plane
        objects (seq<bpy.types.Object>): Sequence of pickable objects

    Returns:
        (obj, location, normal, index): Reference to picked object and raycast
        hit information; otherwise None
            obj (bpy.types.Object): Nearest object in path of the ray
            location (Vector): Object space location of ray-face intersection
            normal (Vector): Normal vector of intersected face
            index (int): Index of intersected face
    '''
    blender_version = bpy.app.version

    # Determine ray extents.
    coord = Vector((x, y))
    ray_dir = region_2d_to_vector_3d(region, rv3d, coord)
    ray_start = region_2d_to_origin_3d(region, rv3d, coord) + ray_dir * near
    ray_end = ray_start + ray_dir * (far - near)

    # Pick a mesh object underneath given screen coordinates.
    result = None
    min_dist_squared = sys.float_info.max
    for obj in objects:

        # Skip objects that cannot participate in ray casting.
        if (not obj.type == 'MESH' or
            obj.mode == 'EDIT' or
            not obj.data.polygons
        ):
            continue

        # Cast ray in object space.
        inverse_model_matrix = obj.matrix_world.inverted()
        hit =  obj.ray_cast(
            inverse_model_matrix * ray_start,
            inverse_model_matrix * ray_end
        )
        if blender_version < (2, 76, 9):
            location, normal, index = hit
        else:
            location, normal, index = hit[1:]

        # Compare intersection distances.
        if index != -1:
            dist_squared = (obj.matrix_world * location - ray_start).length_squared

            # Record closer of the two hits.
            if dist_squared < min_dist_squared:
                min_dist_squared = dist_squared
                result = (obj, location, normal, index)

    return result
 def click_add_target(self, context, x, y):
     
     region = context.region
     rv3d = context.region_data
     coord = x, y
     view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
     ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
     ray_target = ray_origin + (view_vector * 1000)
     mx = self.cut_ob.matrix_world
     imx = mx.inverted()
     
     if bversion() < '002.077.000':
         loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
     else:
         res, loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target - imx * ray_origin)
     if face_ind == -1: return
         
         
     self.target = self.bme.faces[face_ind]
     self.target_loc = loc
     
     
     vrts, eds, ed_cross, f_cross, error = path_between_2_points(self.bme, self.bvh, mx,mx* self.seed_loc,mx*self.target_loc, 
                                                                 max_tests = 10000, debug = True, 
                                                                 prev_face = None, use_limit = True)
         
     if not error:
         self.path = vrts
     else:
         self.path = []
     return
Exemple #7
0
 def raycast_screen(self, loc2d, rgn, r3d):
     o,d = region_2d_to_origin_3d(rgn, r3d, loc2d),region_2d_to_vector_3d(rgn, r3d, loc2d)
     back = 0 if r3d.is_perspective else 100
     p3d,n3d,idx,dist = self.bvh_raycast(self.imx * (o-d*back), self.imx3x3 * d)
     p3d = self.mx * p3d if p3d else None
     n3d = self.nmx * n3d if n3d else None
     return (p3d, n3d)
Exemple #8
0
 def modal(self, context, event):
     region = context.region
     rv3d = context.region_data
     co2d = ((event.mouse_region_x, event.mouse_region_y))
     view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d)
     enterloc = view3d_utils.region_2d_to_origin_3d(region, rv3d, co2d) + view_vector*100
     NP020PL.enterloc = copy.deepcopy(enterloc)
     print('02_GetMouseloc_FINISHED', ';', 'NP020PL.flag = ', NP020PL.flag)
     return{'FINISHED'}
Exemple #9
0
def cast_obj_ray_from_mouse(mousepos,
                            candidates=None,
                            exclude_decals=True,
                            debug=False):
    region = bpy.context.region
    region_data = bpy.context.region_data

    origin_3d = region_2d_to_origin_3d(region, region_data, mousepos)
    vector_3d = region_2d_to_vector_3d(region, region_data, mousepos)

    # get candidate objects, that could be hit
    if not candidates:
        candidates = bpy.context.visible_objects

    if exclude_decals:
        objects = [(obj, None) for obj in candidates
                   if obj.type == "MESH" and not obj.DM.isdecal]
    else:
        objects = [(obj, None) for obj in candidates if obj.type == "MESH"]

    hitobj = None
    hitlocation = None
    hitnormal = None
    hitindex = None
    hitdistance = sys.maxsize

    for obj, src in objects:
        mx = obj.matrix_world
        mxi = mx.inverted()

        ray_origin = mxi @ origin_3d
        ray_direction = mxi.to_3x3() @ vector_3d

        # success, location, normal, index = obj.ray_cast(origin=ray_origin, direction=ray_direction, depsgraph=depsgraph)
        success, location, normal, index = obj.ray_cast(
            origin=ray_origin, direction=ray_direction)
        distance = (mx @ location - origin_3d).length

        if debug:
            print("candidate:", success, obj.name, location, normal, index,
                  distance)

        if success and distance < hitdistance:
            hitobj, hitlocation, hitnormal, hitindex, hitdistance = obj, mx @ location, mx.to_3x3(
            ) @ normal, index, distance

    if debug:
        print("best hit:", hitobj.name if hitobj else None, hitlocation,
              hitnormal, hitindex, hitdistance if hitobj else None)
        print()

    if hitobj:
        return hitobj, hitlocation, hitnormal, hitindex, hitdistance

    return None, None, None, None, None
Exemple #10
0
    def modal(self,context,event):
        print('05_BglPlane_START',';','NP020RM.flag = ', NP020RM.flag)
        context.area.tag_redraw()
        flag = NP020RM.flag
        mode = NP020RM.mode
        plane = NP020RM.plane
        helper = NP020RM.helper
        centerloc = NP020RM.centerloc

        if event.type == 'MOUSEMOVE':
            self.co2d = ((event.mouse_region_x, event.mouse_region_y))
            print('05_BglPlane_mousemove',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)

        elif event.type in ('LEFTMOUSE', 'RIGHTMOUSE', 'RET', 'NUMPAD_ENTER'):
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            region = context.region
            rv3d = context.region_data
            co2d = self.co2d
            view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d)
            viewloc = view3d_utils.region_2d_to_origin_3d(region, rv3d, co2d)
            away = (centerloc - viewloc).length
            pointloc = viewloc + view_vector * away # to place the helper on centerloc to be in the vicinity of projection plane 
            helper.location = pointloc
            helper.hide = False
            NP020RM.qdef = copy.deepcopy(NP020RM.q)
            NP020RM.ndef = copy.deepcopy(NP020RM.n)
            NP020RM.plane = 'SET'
            NP020RM.flag = 'RUNTRANSSTART'
            print('05_BglPlane_lmb_FINISHED',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)
            return{'FINISHED'}

        elif event.ctrl and event.value == 'PRESS':
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            if mode == 'FREE':
                NP020RM.mode = 'X'
            elif mode == 'X':
                NP020RM.mode = 'Y'
            elif mode == 'Y':
                NP020RM.mode = 'Z'
            else:
                NP020RM.mode = 'FREE'
            print('05_BglPlane_rmb_FINISHED',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)

        elif event.type == 'ESC':
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            NP020RM.flag = 'EXIT'
            print('05_BglPlane_esc_FINISHED',';','NP020RM.flag = ', NP020RM.flag)
            return{'FINISHED'}

        elif event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
            print('05_BglPlane_middle_wheel_any_PASS_THROUGH')
            return {'PASS_THROUGH'}

        print('05_BglPlane_standard_RUNNING_MODAL',';','NP020RM.flag = ', NP020RM.flag)
        return {'RUNNING_MODAL'}
Exemple #11
0
    def modal(self,context,event):
        np_print('05_BglPlane_START',';','NP020RM.flag = ', NP020RM.flag)
        context.area.tag_redraw()
        flag = NP020RM.flag
        mode = NP020RM.mode
        plane = NP020RM.plane
        helper = NP020RM.helper
        centerloc = NP020RM.centerloc

        if event.type == 'MOUSEMOVE':
            self.co2d = ((event.mouse_region_x, event.mouse_region_y))
            np_print('05_BglPlane_mousemove',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)

        elif event.type in ('LEFTMOUSE', 'RIGHTMOUSE', 'RET', 'NUMPAD_ENTER'):
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            region = context.region
            rv3d = context.region_data
            co2d = self.co2d
            view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d)
            viewloc = view3d_utils.region_2d_to_origin_3d(region, rv3d, co2d)
            away = (centerloc - viewloc).length
            pointloc = viewloc + view_vector * away # to place the helper on centerloc to be in the vicinity of projection plane 
            helper.location = pointloc
            helper.hide = False
            NP020RM.qdef = copy.deepcopy(NP020RM.q)
            NP020RM.ndef = copy.deepcopy(NP020RM.n)
            NP020RM.plane = 'SET'
            NP020RM.flag = 'RUNTRANSSTART'
            np_print('05_BglPlane_lmb_FINISHED',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)
            return{'FINISHED'}

        elif event.ctrl and event.value == 'PRESS':
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            if mode == 'FREE':
                NP020RM.mode = 'X'
            elif mode == 'X':
                NP020RM.mode = 'Y'
            elif mode == 'Y':
                NP020RM.mode = 'Z'
            else:
                NP020RM.mode = 'FREE'
            np_print('05_BglPlane_rmb_FINISHED',';','NP020RM.flag = ', NP020RM.flag, 'NP020RM.mode = ', NP020RM.mode, 'NP020RM.plane = ', NP020RM.plane)

        elif event.type == 'ESC':
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
            NP020RM.flag = 'EXIT'
            np_print('05_BglPlane_esc_FINISHED',';','NP020RM.flag = ', NP020RM.flag)
            return{'FINISHED'}

        elif event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
            np_print('05_BglPlane_middle_wheel_any_PASS_THROUGH')
            return {'PASS_THROUGH'}

        np_print('05_BglPlane_standard_RUNNING_MODAL',';','NP020RM.flag = ', NP020RM.flag)
        return {'RUNNING_MODAL'}
Exemple #12
0
def pick_object(region, rv3d, x, y, near, far, objects):
    '''
    Selects an object underneath given screen coordinates

    Parameters:
        region (bpy.types.Region): Section of the UI in which to do picking
        rv3d (bpy.types.RegionView3D): 3D view region data
        near (float): Near clipping plane
        far (float): Far clipping plane
        objects (seq<bpy.types.Object>): Sequence of pickable objects

    Returns:
        (obj, location, normal, index): Reference to picked object and raycast
        hit information; otherwise None
            obj (bpy.types.Object): Nearest object in path of the ray
            location (Vector): Object space location of ray-face intersection
            normal (Vector): Normal vector of intersected face
            index (int): Index of intersected face
    '''
    # Determine ray extents.
    coord = Vector((x, y))
    ray_dir = region_2d_to_vector_3d(region, rv3d, coord)
    ray_start = region_2d_to_origin_3d(region, rv3d, coord) + ray_dir * near
    ray_end = ray_start + ray_dir * (far - near)

    # Pick a mesh object underneath given screen coordinates.
    result = None
    min_dist_squared = sys.float_info.max
    for obj in objects:

        # Skip objects that cannot participate in ray casting.
        if (not obj.type == 'MESH' or
            obj.mode == 'EDIT' or
            not obj.data.polygons
            ):
            continue

        # Cast ray in object space.
        inverse_model_matrix = obj.matrix_world.inverted()
        location, normal, index = obj.ray_cast(
            inverse_model_matrix * ray_start,
            inverse_model_matrix * ray_end
        )[0:3]

        # Compare intersection distances.
        if index != -1:
            dist_squared = (obj.matrix_world * location - ray_start).length_squared

            # Record closer of the two hits.
            if dist_squared < min_dist_squared:
                min_dist_squared = dist_squared
                result = (obj, location, normal, index)

    return result
Exemple #13
0
    def get_slide_vector_intersection(self, context):
        view_origin = region_2d_to_origin_3d(context.region,
                                             context.region_data,
                                             self.mousepos)
        view_dir = region_2d_to_vector_3d(context.region, context.region_data,
                                          self.mousepos)

        i = intersect_line_line(view_origin, view_origin + view_dir,
                                self.origin, self.target_avg)

        return i[1]
Exemple #14
0
 def modal(self, context, event):
     region = context.region
     rv3d = context.region_data
     co2d = ((event.mouse_region_x, event.mouse_region_y))
     view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d)
     enterloc = view3d_utils.region_2d_to_origin_3d(
         region, rv3d, co2d) + view_vector * 100
     NP020RM.enterloc = copy.deepcopy(enterloc)
     np_print('02_GetMouseloc_FINISHED', ';', 'NP020RM.flag = ',
              NP020RM.flag)
     return {'FINISHED'}
    def modal(self,context, event):
        region = context.region
        rv3d = context.region_data
        co2d = ((event.mouse_region_x, event.mouse_region_y))
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d) 
        pointloc = view3d_utils.region_2d_to_origin_3d(region, rv3d, co2d) + view_vector/5
        print(pointloc)
        Storage.pointloc=pointloc

        #print('020')         
        return{'FINISHED'}
Exemple #16
0
def get_target(region: bpy.types.Region, region_3d: bpy.types.RegionView3D,
               pixel_coords: Tuple[float, float]):
    from bpy_extras import view3d_utils

    view_vector = view3d_utils.region_2d_to_vector_3d(region, region_3d,
                                                      pixel_coords)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, region_3d,
                                                     pixel_coords)
    target = ray_origin + view_vector

    return [target.x, target.y, target.z]
    def grab_mouse_move(self, context, x, y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        hit = False
        if self.snap_type == 'SCENE':

            mx = Matrix.Identity(4)  #scene ray cast returns world coords
            imx = Matrix.Identity(4)
            no_mx = imx.to_3x3().transposed()
            if bversion() < '002.077.000':
                res, obj, omx, loc, no = context.scene.ray_cast(
                    ray_origin, ray_target)
            else:
                res, loc, no, ind, obj, omx = context.scene.ray_cast(
                    ray_origin, view_vector)

            if res:
                hit = True

            else:
                #cast the ray into a plane a
                #perpendicular to the view dir, at the last bez point of the curve
                hit = True
                view_direction = rv3d.view_rotation * Vector((0, 0, -1))
                plane_pt = self.grab_undo_loc
                loc = intersect_line_plane(ray_origin, ray_target, plane_pt,
                                           view_direction)
                no = view_direction
        elif self.snap_type == 'OBJECT':
            mx = self.snap_ob.matrix_world
            imx = mx.inverted()
            no_mx = imx.to_3x3().transposed()
            if bversion() < '002.077.000':
                loc, no, face_ind = self.snap_ob.ray_cast(
                    imx * ray_origin, imx * ray_target)
                if face_ind != -1:
                    hit = True
            else:
                ok, loc, no, face_ind = self.snap_ob.ray_cast(
                    imx * ray_origin, imx * ray_target - imx * ray_origin)
                if ok:
                    hit = True

        if not hit:
            self.grab_cancel()

        else:
            self.b_pts[self.selected].location = mx * loc
            self.b_pts[self.selected].surface_normal = no_mx * no
def GetMouseLocation(self, event, context):
	region = bpy.context.region
	rv3d = bpy.context.region_data
	coord = event.mouse_region_x, event.mouse_region_y
	view_vector_mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
	ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
	V_a = ray_origin_mouse + view_vector_mouse
	V_b = rv3d.view_rotation @ Vector((0.0, 0.0, -1.0))
	pointLoc = intersect_line_plane(ray_origin_mouse, V_a, context.object.location, V_b)
	loc = (self.GeneralNormal @ pointLoc) * -1
	return loc
def get_ray_target(x, y, ray_max=1e4):
    region = bpy.context.region
    rv3d = bpy.context.region_data
    cam = bpy.context.camera
    coord = x, y
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
    if rv3d.view_perspective == "ORTHO" or (rv3d.view_perspective == "CAMERA" and cam and cam.type == "ORTHO"):
        # move ortho origin back
        ray_origin = ray_origin - (view_vector * (ray_max / 2.0))
    ray_target = ray_origin + (view_vector * 1e4)
Exemple #20
0
    def modal(self, context, event):
        context.area.tag_redraw()

        context.window.cursor_modal_set("EYEDROPPER")

        scene = context.scene
        region = context.region
        rv3d = context.region_data

        if event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
            self.mouse = event.mouse_region_x, event.mouse_region_y

            view_vector = view3d_utils.region_2d_to_vector_3d(
                region, rv3d, self.mouse)
            ray_origin = view3d_utils.region_2d_to_origin_3d(
                region, rv3d, self.mouse)

            raycast = scene.ray_cast(ray_origin, view_vector)

            if raycast[0] == True:
                ob = raycast[4]

                if ob.data.materials:
                    mat = ob.data.materials[0]
                    for shape in [
                            o for o in context.selected_objects
                            if o.type in ('MESH', 'CURVE', 'FONT')
                    ]:
                        if not shape.data.materials:
                            shape.data.materials.append(mat)
                        else:
                            shape.material_slots[0].material = mat

            #context.space_data.draw_handler_remove(self._handle, 'WINDOW')

            context.window.cursor_modal_restore()

            for ob in self.temp_ob:
                bpy.data.objects.remove(ob, True)

            return {'FINISHED'}

            #return {'FINISHED'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:
            #context.object.location.x = self.first_value
            context.window.cursor_modal_restore()

            for ob in self.temp_ob:
                bpy.data.objects.remove(ob, True)
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}
    def hover_non_man(self,context,x,y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        self.mouse = Vector((x, y))
        
        loc3d_reg2D = view3d_utils.location_3d_to_region_2d
        
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)
        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
        
        if len(self.non_man_points):
            co3d, index, dist = self.kd.find(mx * loc)

            #get the actual non man vert from original list
            close_bmvert = self.bme.verts[self.non_man_bmverts[index]] #stupid mapping, unreadable, terrible, fix this, because can't keep a list of actual bmverts
            close_eds = [ed for ed in close_bmvert.link_edges if not ed.is_manifold]
            if len(close_eds) == 2:
                bm0 = close_eds[0].other_vert(close_bmvert)
                bm1 = close_eds[1].other_vert(close_bmvert)
            
                a0 = bm0.co
                b   = close_bmvert.co
                a1  = bm1.co 
                
                inter_0, d0 = intersect_point_line(loc, a0, b)
                inter_1, d1 = intersect_point_line(loc, a1, b)
                
                screen_0 = loc3d_reg2D(region, rv3d, mx * inter_0)
                screen_1 = loc3d_reg2D(region, rv3d, mx * inter_1)
                screen_v = loc3d_reg2D(region, rv3d, mx * b)
                
                screen_d0 = (self.mouse - screen_0).length
                screen_d1 = (self.mouse - screen_1).length
                screen_dv = (self.mouse - screen_v).length
                
                if 0 < d0 <= 1 and screen_d0 < 30:
                    self.hovered = ['NON_MAN_ED', (close_eds[0], mx*inter_0)]
                    return
                elif 0 < d1 <= 1 and screen_d1 < 30:
                    self.hovered = ['NON_MAN_ED', (close_eds[1], mx*inter_1)]
                    return
                elif screen_dv < 30:
                    if abs(d0) < abs(d1):
                        self.hovered = ['NON_MAN_VERT', (close_eds[0], mx*b)]
                        return
                    else:
                        self.hovered = ['NON_MAN_VERT', (close_eds[1], mx*b)]
                        return
 def mouse_to_scene_raycast(self, context, event):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     co2d = (event.mouse_region_x, event.mouse_region_y)
     view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
     ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
     res, pos, normal, face_index, object, matrix_world = context.scene.ray_cast(
         ray_origin_mouse, view_vector_mouse)
     return res, pos, normal, face_index, object, matrix_world
Exemple #23
0
def screen_space_to_3d(location, distance, context):
    region = context.region
    data = context.space_data.region_3d
    if data.is_perspective:
        vec = region_2d_to_vector_3d(region, data, location)
        origin = region_2d_to_origin_3d(region, data, location, distance)
    else:
        vec = data.view_rotation @ Vector((0, 0, -1))
        origin = region_2d_to_location_3d(region, data, location,
                                          -vec * data.view_distance)
    location = vec * distance + origin
    return location
def unProject(region, rv3d, mcursor):
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, mcursor)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, mcursor)
    ray_target = ray_origin + (view_vector * 1000)    
    scene = bpy.context.scene

    # cast the ray
    result, object, matrix, location, normal = scene.ray_cast(ray_origin, ray_target)
    if location == None:
        location = Vector((0,0,0))

    return result, object, matrix, location, normal
Exemple #25
0
    def modal(self, context, event):
        region = context.region
        rv3d = context.region_data
        co2d = ((event.mouse_region_x, event.mouse_region_y))
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, co2d)
        pointloc = view3d_utils.region_2d_to_origin_3d(region, rv3d,
                                                       co2d) + view_vector / 5
        print(pointloc)
        Storage.pointloc = pointloc

        #print('020')
        return {'FINISHED'}
Exemple #26
0
  def grab_mouse_move(self,context,x,y):
      region = context.region
      rv3d = context.region_data
      coord = x, y
      view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
      ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
      ray_target = ray_origin + (view_vector * 1000)
      
      crv_mx = self.crv_obj.matrix_world
      i_crv_mx = crv_mx.inverted()  
      
      
      hit = False
      if self.snap_type == 'SCENE':
          
          mx = Matrix.Identity(4) #scene ray cast returns world coords
          if bversion() < '002.077.000':
              res, obj, omx, loc, no = context.scene.ray_cast(ray_origin, ray_target)
          else:
              res, loc, no, ind, obj, omx = context.scene.ray_cast(ray_origin, view_vector)
          
          if res:
              hit = True
      
          else:
              #cast the ray into a plane a
              #perpendicular to the view dir, at the last bez point of the curve
              hit = True
              view_direction = rv3d.view_rotation * Vector((0,0,-1))
              plane_pt = self.grab_undo_loc
              loc = intersect_line_plane(ray_origin, ray_target,plane_pt, view_direction)
              
      elif self.snap_type == 'OBJECT':
          mx = self.snap_ob.matrix_world
          imx = mx.inverted()
          
          if bversion() < '002.077.000':
              loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin, imx * ray_target)
              if face_ind != -1:
                  hit = True
          else:
              ok, loc, no, face_ind = self.snap_ob.ray_cast(imx * ray_origin, imx * ray_target - imx*ray_origin)
              if ok:
                  hit = True
 
      if not hit:
          self.grab_cancel()
          
      else:
          local_loc = i_crv_mx * mx * loc
          self.crv_data.splines[0].bezier_points[self.selected].co = local_loc
          self.b_pts[self.selected] = mx * loc
    def modal(self, context, event):
        props = context.scene.son_props

        if context.mode == 'OBJECT':
            # マウスカーソルのリージョン座標を取得
            mv = Vector((event.mouse_region_x, event.mouse_region_y))
            # 3Dビューエリアのウィンドウリージョンと、スペースを取得する
            region, space = ShowObjectName.__get_region_space(
                context, 'VIEW_3D', 'WINDOW', 'VIEW_3D'
            )
            # マウスカーソルの位置に向けて発したレイの方向を求める
            ray_dir = view3d_utils.region_2d_to_vector_3d(
                region,
                space.region_3d,
                mv
            )
            # マウスカーソルの位置に向けて発したレイの発生源を求める
            ray_orig = view3d_utils.region_2d_to_origin_3d(
                region,
                space.region_3d,
                mv
            )
            # レイの始点
            start = ray_orig
            # レイの終点(線分の長さは2000とした)
            end = ray_orig + ray_dir * 2000
            # カメラやライトなど、メッシュ型ではないオブジェクトは除く
            objs = [o for o in bpy.data.objects if o.type == 'MESH']
            self.__intersected_objs = []
            for o in objs:
                try:
                    # レイとオブジェクトの交差判定
                    mwi = o.matrix_world.inverted()
                    result = o.ray_cast(mwi * start, mwi * end)
                    # オブジェクトとレイが交差した場合は交差した面のインデックス、交差しない場合は-1が返ってくる
                    if result[2] != -1:
                        self.__intersected_objs.append(o)
                # メッシュタイプのオブジェクトが作られているが、ray_cast対象の面が存在しない場合
                except RuntimeError:
                    print("""サンプル5-4: オブジェクト生成タイミングの問題により、
                             例外エラー「レイキャスト可能なデータなし」が発生""")

        # 3Dビューの画面を更新
        if context.area:
            context.area.tag_redraw()

        # 作業時間計測を停止
        if props.running is False:
            self.__handle_remove(context)
            return {'FINISHED'}

        return {'PASS_THROUGH'}
Exemple #28
0
def mouse_raycast(context: bpy.types.Context, mx: float, my: float) -> tuple:
    """Perform a raycast from the mouse.

    Parameters:
        context: Blender context
        mx: mouse x-coordinate
        my: mouse y-coordinate

    Returns:
        tuple: Tuple containing: if a object was hit; location; normal; rotation;
        face index; object; matrix;
    """
    region = context.region
    rv3d = context.region_data
    coord = mx, my

    # get the ray from the viewport and mouse
    target_distance = 1e9
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
    ray_target = ray_origin + (view_vector * target_distance)

    vec = ray_target - ray_origin

    (
        has_hit,
        snapped_location,
        snapped_normal,
        face_index,
        obj_hit,
        matrix,
    ) = bpy.context.scene.ray_cast(bpy.context.view_layer.depsgraph,
                                   ray_origin, vec)

    randoffset = math.pi
    if has_hit:
        snapped_rotation = snapped_normal.to_track_quat('Z', 'Y').to_euler()
        up = Vector((0, 0, 1))
        props = getattr(bpy.context.window_manager, HANA3D_MODELS)
        angle_threshold = 10.0
        if snapped_normal.angle(up) < math.radians(angle_threshold):
            randoffset = props.offset_rotation_amount + math.pi
        else:
            # we don't rotate this way on walls and ceilings.
            randoffset = props.offset_rotation_amount

    else:
        snapped_rotation = mathutils.Quaternion((0, 0, 0, 0)).to_euler()

    snapped_rotation.rotate_axis('Z', randoffset)

    return has_hit, snapped_location, snapped_normal, snapped_rotation, face_index, obj_hit, matrix
Exemple #29
0
def ray_cast_to_mouse(self):
    # get the ray from the viewport and mouse
    view_vector = view3d_utils.region_2d_to_vector_3d(
        self.act_reg, self.act_rv3d, self._mouse_reg_loc)
    ray_origin = view3d_utils.region_2d_to_origin_3d(
        self.act_reg, self.act_rv3d, self._mouse_reg_loc)

    hit, norm, ind, dist = self._object_bvh.ray_cast(
        ray_origin, view_vector, 10000)

    if hit != None and ind != None:
        return hit, ind
    return None
 def mouse_to_scene_raycast(self, context, event):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     co2d = (event.mouse_region_x, event.mouse_region_y)
     view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
     ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
     res, pos, normal, face_index, object, matrix_world = context.scene.ray_cast(
         ray_origin_mouse,
         view_vector_mouse)
     return res, pos, normal, face_index, object, matrix_world
Exemple #31
0
def unProject(region, rv3d, mcursor):
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, mcursor)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, mcursor)
    ray_target = ray_origin + (view_vector * 1000)
    scene = bpy.context.scene

    # cast the ray
    result, object, matrix, location, normal = scene.ray_cast(
        ray_origin, ray_target)
    if location == None:
        location = Vector((0, 0, 0))

    return result, object, matrix, location, normal
Exemple #32
0
def ray_cast_view_occlude_test(co, mouse_co, bvh, region, rv3d):
    orig_co = view3d_utils.region_2d_to_origin_3d(
        region, rv3d, mouse_co)
    direction_to = (orig_co - co).normalized()

    occluded = False
    hit_to_view, norm_to_view, ind_to_view, dist_to_view = bvh.ray_cast(
        co+direction_to*.001, direction_to, 1000000)

    if hit_to_view != None:
        occluded = True

    return occluded
Exemple #33
0
def to3d(coords, distance=1.0):
    """

    Args:
      coords: 
      distance: (Default value = 1.0)

    Returns:

    """
    # bgl.glUnProject()
    return view3d_utils.region_2d_to_origin_3d(*getRegionData(), (coords),
                                               distance)
Exemple #34
0
def get_mouse_on_plane(context, plane_pos, mouse_coords):
    region = context.region
    rv3d = context.region_data
    cam_dir = rv3d.view_rotation * Vector((0.0, 0.0, -1.0))
    #cam_pos = view3d_utils.region_2d_to_origin_3d(region, rv3d, (region.width/2.0, region.height/2.0))
    mouse_pos = view3d_utils.region_2d_to_origin_3d(region, rv3d, mouse_coords)
    mouse_dir = view3d_utils.region_2d_to_vector_3d(region, rv3d, mouse_coords)
    new_pos = mathu.geometry.intersect_line_plane(mouse_pos, mouse_pos+(mouse_dir*10000.0), plane_pos, cam_dir, False)

    if new_pos:
        return new_pos

    return None
 def modal(self, context, event):
     if event.type == 'MOUSEMOVE':
         mouse = (event.mouse_region_x, event.mouse_region_y)
         input_value = internal.nearestPointOfLines(
             bpy.context.scene.cursor.location,
             bpy.context.scene.cursor.matrix.col[2].xyz,
             view3d_utils.region_2d_to_origin_3d(context.region,
                                                 context.region_data,
                                                 mouse),
             view3d_utils.region_2d_to_vector_3d(context.region,
                                                 context.region_data,
                                                 mouse))[1]
         if self.mode == 'PITCH':
             self.pitch = input_value / (
                 self.slice_count -
                 1) if self.slice_count > 2 else input_value
         elif self.mode == 'OFFSET':
             self.offset = input_value - self.pitch * 0.5 * (
                 (self.slice_count - 1) if self.slice_count > 2 else 1.0)
     elif event.type == 'WHEELUPMOUSE':
         if self.slice_count > 2:
             self.pitch *= (self.slice_count - 1)
         self.slice_count += 1
         if self.slice_count > 2:
             self.pitch /= (self.slice_count - 1)
     elif event.type == 'WHEELDOWNMOUSE':
         if self.slice_count > 2:
             self.pitch *= (self.slice_count - 1)
         if self.slice_count > 1:
             self.slice_count -= 1
         if self.slice_count > 2:
             self.pitch /= (self.slice_count - 1)
     elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
         if self.mode == 'PITCH':
             self.mode = 'OFFSET'
             return {'RUNNING_MODAL'}
         elif self.mode == 'OFFSET':
             self.mesh.free()
             return {'FINISHED'}
     elif event.type in {'RIGHTMOUSE', 'ESC'}:
         self.mesh.free()
         if self.dst_obj.type == 'MESH':
             bpy.data.meshes.remove(self.dst_obj.data)
         else:
             bpy.data.curves.remove(self.dst_obj.data)
         bpy.context.view_layer.objects.active = self.src_obj
         return {'CANCELLED'}
     else:
         return {'PASS_THROUGH'}
     self.perform()
     return {'RUNNING_MODAL'}
Exemple #36
0
def floor_raycast(context: bpy.types.Context, mx: float, my: float) -> tuple:
    """Perform a raycast from the floor.

    Parameters:
        context: Blender context
        mx: mouse x-coordinate
        my: mouse y-coordinate

    Returns:
        tuple: Tuple containing: if a object was hit; location; normal; rotation;
        face index; object; matrix;
    """
    region = context.region
    rv3d = context.region_data
    coord = mx, my

    # get the ray from the viewport and mouse
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
    ray_target = ray_origin + (view_vector * 1000)

    # various intersection plane normals are needed for corner cases
    # that might actually happen quite often - in front and side view.
    # default plane normal is scene floor.
    tolerance = 1e-4
    plane_normal = (0, 0, 1)
    if math.isclose(view_vector.z, 0, abs_tol=tolerance):
        if math.isclose(view_vector.x, 0, abs_tol=tolerance):
            plane_normal = (0, 1, 0)
        else:
            plane_normal = (1, 0, 0)

    origin = (0, 0, 0)
    snapped_location = mathutils.geometry.intersect_line_plane(
        ray_origin,
        ray_target,
        origin,
        plane_normal,
    )
    if snapped_location is not None:
        has_hit = True
        snapped_normal = Vector((0, 0, 1))
        face_index = None
        obj_hit = None
        matrix = None
        snapped_rotation = snapped_normal.to_track_quat('Z', 'Y').to_euler()
        props = getattr(bpy.context.window_manager, HANA3D_MODELS)
        randoffset = props.offset_rotation_amount + math.pi
        snapped_rotation.rotate_axis('Z', randoffset)

    return has_hit, snapped_location, snapped_normal, snapped_rotation, face_index, obj_hit, matrix
    def grab_mouse_move(self, context, x, y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin,
                                                 imx * ray_target)

        if face_ind == -1:
            self.grab_cancel()
            return

        #check if first or end point and it's a non man edge!
        geos, fixed, close, far = self.geo_data

        self.target = self.bme.faces[face_ind]
        self.target_loc = loc

        if all([v in fixed for v in self.target.verts]):

            path_elements, self.path = gradient_descent(self.bme,
                                                        geos,
                                                        self.target,
                                                        self.target_loc,
                                                        epsilon=.0000001)
            print('great we have already waked the geodesic this far')

        else:
            print('continue geo walk until we find it, then get it')
            continue_geodesic_walk(self.bme,
                                   self.seed,
                                   self.seed_loc,
                                   geos,
                                   fixed,
                                   close,
                                   far,
                                   targets=[self.bme.faces[face_ind]],
                                   subset=None,
                                   max_iters=100000,
                                   min_dist=None)

            path_elements, self.path = gradient_descent(self.bme,
                                                        geos,
                                                        self.target,
                                                        self.target_loc,
                                                        epsilon=.0000001)
    def hover(self, context, x, y):
        '''
        hovering happens in mixed 3d and screen space.  It's a mess!
        '''

        if len(self.b_pts) == 0:
            return

        region = context.region
        rv3d = context.region_data
        self.mouse = Vector((x, y))
        coord = x, y
        loc3d_reg2D = view3d_utils.location_3d_to_region_2d

        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        if self.snap_type == 'OBJECT':
            mx = self.snap_ob.matrix_world
            imx = mx.inverted()

            
            res, loc, no, face_ind = self.snap_ob.ray_cast(imx @ ray_origin, imx @ ray_target - imx @ ray_origin)
            if not res:
                #do some shit
                pass
        elif self.snap_type == 'SCENE':

            mx = Matrix.Identity(4) #scene ray cast returns world coords
            
            res, loc, no, ind, obj, omx = context.scene.ray_cast(context.view_layer, ray_origin, view_vector)


            print(obj)
            
        def dist(v):
            diff = v - Vector((x,y))
            return diff.length

        def dist3d(pt):
            if pt.location is None:
                return 100000000
            delt = pt.location - mx @ loc
            return delt.length

        closest_3d_point = min(self.b_pts, key=dist3d)
        screen_dist = dist(loc3d_reg2D(context.region, context.space_data.region_3d, closest_3d_point.location))

        self.hovered = ['POINT', self.b_pts.index(closest_3d_point)] if screen_dist < 20 else [None, -1]
        print(self.hovered)
Exemple #39
0
    def GetValue(self, MousePosition, normal, clip_normal):
        region = bpy.context.region
        rv3d = bpy.context.region_data

        view_vector_mouse = view3d_utils.region_2d_to_vector_3d(region, rv3d, MousePosition)
        ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(region, rv3d, MousePosition)
        MouseVector =  view_vector_mouse + ray_origin_mouse
        pointLoc = intersect_line_plane(ray_origin_mouse, MouseVector, self.Center, clip_normal)

        # dvec = self.Center-pointLoc
        # dnormal = dvec.dot(normal)
        # val = self.Center + Vector(dnormal*normal)

        return ((((pointLoc - self.Center)) @ normal) * -1)
def mouse_sc_raycast(context, co2d):
    '''Raycast that works in edit mode - caution: returns evaluated face idx does not match'''
    view_vector = region_2d_to_vector_3d(context.region, context.region_data,
                                         co2d)
    ray_origin = region_2d_to_origin_3d(context.region, context.region_data,
                                        co2d)
    viewlayer = context.view_layer

    hidden = []
    hit_index = None
    hit_obj = None
    hit_loc = None
    hit_normal = None
    hit_mtx = None
    hit = False
    is_visible = False

    # scene invisible is dfferent from view invisible, so we must do this dance
    while not is_visible:
        result, location, normal, index, obj, matrix = context.scene.ray_cast(
            context.evaluated_depsgraph_get(),
            ray_origin,
            view_vector,
            distance=9001)
        if obj is not None:
            is_visible = obj.visible_get(view_layer=viewlayer)

            if not is_visible:
                obj.hide_viewport = True
                hidden.append(obj)

            if is_visible:
                if obj.type == 'MESH':
                    hit_index = index
                    hit_obj = obj
                    hit_normal = normal
                    # hit_normal = correct_normal(matrix, normal)
                    hit_loc = location
                    hit_mtx = matrix
                    hit = result
        else:
            hit_obj = None
            hit_index = None
            is_visible = True

    if hidden:
        for o in hidden:
            o.hide_viewport = False

    return hit, hit_loc, hit_normal, hit_index, hit_obj, hit_mtx
Exemple #41
0
    def getOrigin(self, context, event, mode=False):
        scene = context.scene
        region = context.region
        rv3d = context.region_data
        coord = event.mouse_region_x, event.mouse_region_y

        # get the ray from the viewport and mouse
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)

        origin_ = intersect_point_line(self.actPos, ray_origin,
                                       ray_origin + view_vector)
        origin = origin_[0]
        return origin
    def modal(self, context, event):

        # get the ray from the viewport and mouse
        if bpy.context.mode == 'OBJECT':
            MousePosition = Vector(
                ((event.mouse_x) - context.area.regions.data.x,
                 event.mouse_y - context.area.regions.data.y))
            region = bpy.context.region
            rv3d = bpy.context.region_data
            view_vector_mouse = view3d_utils.region_2d_to_vector_3d(
                region, rv3d, MousePosition)
            ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(
                region, rv3d, MousePosition)
            direction = ray_origin_mouse + (view_vector_mouse * 1000)
            direction = direction - ray_origin_mouse
            result, location, normal, index, obj, matrix = bpy.context.scene.ray_cast(
                bpy.context.view_layer.depsgraph, ray_origin_mouse, direction)

            if result:
                if self.Extend and not obj.select_get():
                    bpy.ops.view3d.select('INVOKE_DEFAULT',
                                          extend=True,
                                          deselect=False)
                elif self.Deselect and obj.select_get():
                    obj.select_set(False)
                elif not self.Extend and not self.Deselect and not obj.select_get(
                ):
                    bpy.ops.view3d.select('INVOKE_DEFAULT',
                                          extend=True,
                                          deselect=False)

        else:  # context.mode in ['EDIT_CURVE','EDIT_MESH']:
            if self.Extend:
                bpy.ops.view3d.select('INVOKE_DEFAULT',
                                      extend=True,
                                      deselect=False)
            elif self.Deselect:
                bpy.ops.view3d.select('INVOKE_DEFAULT',
                                      extend=False,
                                      deselect=True)
            elif not self.Extend and not self.Deselect:
                bpy.ops.view3d.select('INVOKE_DEFAULT',
                                      extend=True,
                                      deselect=False)
        # elif context.mode == 'EDIT_ARMATURE':
        #     self.obj =

        if event.value == 'RELEASE':
            return {'CANCELLED'}
        return {'RUNNING_MODAL'}
def raycast_2d_3d(_ctx, _2dPos):
    region, regionData = get_regiondata_view3d(_ctx)  # get region data
    # normalized 3d vector from 2d region coords to 3d space # length of 1
    vNormalized = view3d_utils.region_2d_to_vector_3d(
        region, regionData,
        _2dPos)  # this returns a 3d vector (mathutils.Vector)
    # Get view origin from relative 2d coords of the region to the 3d spcace
    origin = view3d_utils.region_2d_to_origin_3d(region, regionData, _2dPos)
    # hit, pos, normal, index, obj, matrix
    return _ctx.scene.ray_cast(_ctx.view_layer if blender_version()[1] < 91
                               else _ctx.view_layer.depsgraph,
                               origin,
                               vNormalized,
                               distance=1e+10)  # distance can be higher
    def __StarPosMouse(self, context, event):
        region = bpy.context.region
        rv3d = bpy.context.region_data
        coord = event.mouse_region_x, event.mouse_region_y
        view_vector_mouse = view3d_utils.region_2d_to_vector_3d(
            region, rv3d, coord)
        ray_origin_mouse = view3d_utils.region_2d_to_origin_3d(
            region, rv3d, coord)

        pointLoc = intersect_line_plane(
            ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
            self.center, rv3d.view_rotation * Vector((0.0, 0.0, -1.0)), False)

        return pointLoc, (self.direction * pointLoc) * -1
def out_Location(rv3d, region, mcursor):
    view_matrix = rv3d.view_matrix.transposed()
    orig = view3d_utils.region_2d_to_origin_3d(region, rv3d, mcursor)
    vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, mcursor)
    v1 = Vector((int(view_matrix[0][0]*1.5),int(view_matrix[1][0]*1.5),int(view_matrix[2][0]*1.5)))
    v2 = Vector((int(view_matrix[0][1]*1.5),int(view_matrix[1][1]*1.5),int(view_matrix[2][1]*1.5)))
    
    hit = mathutils.geometry.intersect_ray_tri(Vector((1,0,0)), Vector((0,1,0)), Vector((0,0,0)), (vector), (orig), False)
    if hit == None:
        hit = mathutils.geometry.intersect_ray_tri(v1, v2, Vector((0,0,0)), (vector), (orig), False)        
    if hit == None:
        hit = mathutils.geometry.intersect_ray_tri(v1, v2, Vector((0,0,0)), (-vector), (orig), False)
    if hit == None:
        hit = Vector((0,0,0))
    return hit
Exemple #46
0
    def click_model(self, context, x, y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        ray_max = 10000
        view_vector = region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * ray_max)

        imx = self.model.matrix_world.inverted()

        result, loc, normal, idx = self.model.ray_cast(
            imx * ray_origin, imx * ray_target - imx * ray_origin)

        return result
Exemple #47
0
def get_view_origin_position():
    #method 1
    from bpy_extras import view3d_utils
    region = bpy.context.region
    rv3d = bpy.context.region_data
    view_loc = view3d_utils.region_2d_to_origin_3d(region, rv3d, (region.width/2.0, region.height/2.0))
    print("view_loc1", view_loc)#Dbg

    #method 2
    r3d = bpy.context.space_data.region_3d
    view_loc2 = r3d.view_matrix.inverted().translation
    print("view_loc2", view_loc2)#Dbg
    if view_loc != view_loc2: print('there might be an errror when finding view coordinate')

    return view_loc
 def mousemove_drawing(self, context, event):
     screen_v = Vector((event.mouse_region_x, event.mouse_region_y))
     self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
    
     #this will just add in apoint every 10 recorded mouse positions
     #later you will want to do something smarter :-)
     if len(self.mouse_path) > self.draw_points_max or (screen_v - Vector(self.mouse_path[0])).length >= self.extrusion_radius:
         region = context.region
         rv3d = context.region_data
         #this is the view_vector @ the mous coord
         #which is not the same as the view_direction!!!
         view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, self.mouse_path[-1])
         ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, self.mouse_path[-1])
         ray_target = ray_origin + (view_vector * 10000)
        
         #cast the ray into a plane a
         #perpendicular to the view dir, at the last bez point of the curve
         
         view_direction = rv3d.view_rotation * Vector((0,0,-1))
         if self.active_spline.type == 'BEZIER':
             plane_pt = self.curve_object.matrix_world * self.active_spline.bezier_points[-1].co
         elif self.active_spline.type == 'NURBS':
             plane_pt = self.curve_object.matrix_world * self.active_spline.points[-1].co
             
         new_coord = intersect_line_plane(ray_origin, ray_target,plane_pt, view_direction)
        
         if new_coord:
             if self.active_spline.type == 'BEZIER':
                 self.active_spline.bezier_points.add(1)
                 self.active_spline.bezier_points[-1].co = self.curve_object.matrix_world.inverted() * new_coord
                 self.active_spline.bezier_points[-1].handle_right.xyz = self.active_spline.bezier_points[-1].co
                 self.active_spline.bezier_points[-1].handle_left.xyz = self.active_spline.bezier_points[-1].co
                 self.active_spline.bezier_points[-1].handle_left_type = 'AUTO'
                 self.active_spline.bezier_points[-1].handle_right_type = 'AUTO'
                 
             elif self.active_spline.type == 'NURBS':
                 self.active_spline.points.add(1)
                 loc = self.curve_object.matrix_world.inverted() * new_coord
                 #NURBS pahts have 4 dim points
                 self.active_spline.points[-1].co = Vector((loc[0], loc[1], loc[2], 1))
                 
            
             #udpate everything
             #udpate modifiers and objects etc.
             self.curve_object.update_tag()
             context.scene.update()
            
         self.mouse_path = []
 def mouse_to_plane(self, context, event, origin=Vector((0, 0, 0)), normal=Vector((0, 0, 1))):
     """
         convert mouse pos to 3d point over plane defined by origin and normal
     """
     region = context.region
     rv3d = context.region_data
     co2d = (event.mouse_region_x, event.mouse_region_y)
     view_vector_mouse = region_2d_to_vector_3d(region, rv3d, co2d)
     ray_origin_mouse = region_2d_to_origin_3d(region, rv3d, co2d)
     pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
        origin, normal, False)
     # fix issue with parallel plane
     if pt is None:
         pt = intersect_line_plane(ray_origin_mouse, ray_origin_mouse + view_vector_mouse,
             origin, view_vector_mouse, False)
     return pt
def get_mouse_on_plane(context, plane_pos, plane_dir, mouse_coords):
    region = context.region
    rv3d = context.region_data

    final_dir = plane_dir
    if plane_dir is None:
        final_dir = rv3d.view_rotation * Vector((0.0, 0.0, -1.0))

    mouse_pos = view3d_utils.region_2d_to_origin_3d(region, rv3d, mouse_coords)
    mouse_dir = view3d_utils.region_2d_to_vector_3d(region, rv3d, mouse_coords)
    new_pos = mathu.geometry.intersect_line_plane(
        mouse_pos, mouse_pos + (mouse_dir * 10000.0), plane_pos, final_dir, False)
    if new_pos:
        return new_pos

    return None
Exemple #51
0
    def click_add_point(self,context,x,y):
        '''
        x,y = event.mouse_region_x, event.mouse_region_y
        
        this will add a point into the bezier curve or
        close the curve into a cyclic curve
        '''
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)
        mx = self.cut_ob.matrix_world
        imx = mx.inverted()

        if bversion() < '002.077.000':
            loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
        else:
            ok, loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target - imx*ray_origin)
            
        if face_ind == -1: 
            self.selected = -1
            return
        
        if self.hovered[0] == None:  #adding in a new point
            self.pts += [mx * loc]
            self.cut_pts += [loc]
            self.normals += [no]
            self.face_map += [face_ind]
            self.selected = len(self.pts) -1
                
        if self.hovered[0] == 'POINT':
            self.selected = self.hovered[1]
            if self.hovered[1] == 0:  #clicked on first bpt, close loop
                self.cyclic = self.cyclic == False
            return
         
        elif self.hovered[0] == 'EDGE':  #cut in a new point
            self.pts.insert(self.hovered[1]+1, mx * loc)
            self.cut_pts.insert(self.hovered[1]+1, loc)
            self.normals.insert(self.hovered[1]+1, no)
            self.face_map.insert(self.hovered[1]+1, face_ind)
            self.selected = self.hovered[1] + 1
            return
def ray_cast_region2d(region, rv3d, screen_coord, ob, settings):
    '''
    performs ray casting on object given region, rv3d, and coords wrt region.
    returns tuple of ray vector (from coords of region) and hit info
    '''
    mx = ob.matrix_world
    imx = mx.inverted()
    
    ray_vector = region_2d_to_vector_3d(region, rv3d, screen_coord).normalized()
    ray_origin = region_2d_to_origin_3d(region, rv3d, screen_coord)
    
    if rv3d.is_perspective:
        #ray_target = ray_origin + ray_vector * 100
        r1 = get_ray_origin(ray_origin, -ray_vector, ob)
        ray_target = r1
    else:
        # need to back up the ray's origin, because ortho projection has front and back
        # projection planes at inf
        r0 = get_ray_origin(ray_origin,  ray_vector, ob)
        r1 = get_ray_origin(ray_origin, -ray_vector, ob)
        dprint(str(r0) + '->' + str(r1), l=4)
        ray_origin = r0
        ray_target = r1
    
    #TODO: make a max ray depth or pull this depth from clip depth
    
    ray_start_local  = imx * ray_origin
    ray_target_local = imx * ray_target
    
    if settings.debug > 3:
        print('ray_persp  = ' + str(rv3d.is_perspective))
        print('ray_origin = ' + str(ray_origin))
        print('ray_target = ' + str(ray_target))
        print('ray_vector = ' + str(ray_vector))
        print('ray_diff   = ' + str((ray_target - ray_origin).normalized()))
        print('start:  ' + str(ray_start_local))
        print('target: ' + str(ray_target_local))
    
    if bversion() >= '002.077.000':
        hit = ob.ray_cast(ray_start_local, (ray_target_local - ray_start_local))
        
    else:
        hit = ob.ray_cast(ray_start_local, ray_target_local)
     
    return (ray_vector, hit)
 def hover_scene(self,context,x, y):
     scene = context.scene
     region = context.region
     rv3d = context.region_data
     coord = x, y
     ray_max = 10000
     view_vector = region_2d_to_vector_3d(region, rv3d, coord)
     ray_origin = region_2d_to_origin_3d(region, rv3d, coord)
     ray_target = ray_origin + (view_vector * ray_max)
     result, ob, mx, loc, normal = scene.ray_cast(ray_origin, ray_target)
     
     if result:
         self.ob = ob
         self.ob_preview = ob.name
         context.area.header_text_set(ob.name)
     else:
         self.ob = None
         self.ob_preview = 'None'
         context.area.header_text_set('None')
Exemple #54
0
def get_mouse_raycast(context, objects_list, coords_2d, ray_max=10000.0):
    region = context.region
    rv3d = context.region_data

    best_obj, hit_normal, hit_position = None, None, None
    best_length_squared = 20000.0 * 20000.0

    # get the ray from the viewport and mouse
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coords_2d)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coords_2d)

    for obj, matrix in objects_list:
        # Do RayCast! t1,t2,t3,t4 - temp values
        t1, t2, t3 = obj_raycast(obj, matrix, view_vector, ray_origin, ray_max)
        if t1 is not None and t3 < best_length_squared:
            best_obj, hit_normal, hit_position = obj, t1, t2
            best_length_squared = t3

    return best_obj, hit_normal, hit_position
    def grab_mouse_move(self,context,x,y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        if bversion() < '002.077.000':
            loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
            if face_ind == -1:        
                self.grab_cancel()
                return
        else:
            res, loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target - imx * ray_origin)
        
            if not res:
                self.grab_cancel()
                return
        
        #check if first or end point and it's a non man edge!   
        geos, fixed, close, far = self.geo_data
        
        self.target = self.bme.faces[face_ind]
        self.target_loc = loc
        
        if all([v in fixed for v in self.target.verts]):
            
            path_elements, self.path = gradient_descent(self.bme, geos, 
                                self.target, self.target_loc, epsilon = .0000001)
            print('great we have already waked the geodesic this far')
            
        else:
            print('continue geo walk until we find it, then get it')
            continue_geodesic_walk(self.bme, self.seed, self.seed_loc, 
                           geos, fixed, close, far,
                           targets =[self.bme.faces[face_ind]], subset = None, max_iters = 100000, min_dist = None)
            
            path_elements, self.path = gradient_descent(self.bme, geos, 
                                self.target, self.target_loc, epsilon = .0000001)
    def mousePlaneIntersection(self, context, event, o, N):
        scene  = context.scene
        region = context.region
        rv3d   = context.region_data
        coord  = event.mouse_region_x, event.mouse_region_y
        
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin  = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)

        if rv3d.view_perspective != 'ORTHO':
            return rayPlaneIntersection(ray_origin, view_vector, o, N), view_vector

        if abs(view_vector.y) == 1:
            ray_origin.y = 0
        elif abs(view_vector.x) == 1:
            ray_origin.x = 0
        elif abs(view_vector.z) == 1:
            ray_origin.z = 0
                    
        return ray_origin, view_vector
def get_ray_origin_target(region, rv3d, screen_coord, ob):
    ray_vector = region_2d_to_vector_3d(region, rv3d, screen_coord).normalized()
    ray_origin = region_2d_to_origin_3d(region, rv3d, screen_coord)
    if not rv3d.is_perspective:
        # need to back up the ray's origin, because ortho projection has front and back
        # projection planes at inf
        
        bver = '%03d.%03d.%03d' % (bpy.app.version[0],bpy.app.version[1],bpy.app.version[2])
        # why does this need to be negated?
        # but not when ortho front/back view??
        if bver < '002.073.000' and abs(ray_vector.y)<1: ray_vector = -ray_vector
        
        r0 = get_ray_origin(ray_origin, ray_vector, ob)
        r1 = get_ray_origin(ray_origin, -ray_vector, ob)
        ray_origin = r0
        ray_target = r1
    else:
        ray_target = get_ray_origin(ray_origin, -ray_vector, ob)
    
    return (ray_origin, ray_target)
    def click_seed_select(self, context, x, y):
        
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)
        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)

        if face_ind != -1:
            self.face_seed = face_ind
            print('face selected!!')
            return True
            
        else:
            self.face_seed = None
            print('face not selected')
            return False
Exemple #59
0
    def grab_mouse_move(self,context,x,y):
        region = context.region
        rv3d = context.region_data
        coord = x, y
        view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
        ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
        ray_target = ray_origin + (view_vector * 1000)

        mx = self.cut_ob.matrix_world
        imx = mx.inverted()
        if bversion() < '002.077.000':
            loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target)
        else:
            ok, loc, no, face_ind = self.cut_ob.ray_cast(imx * ray_origin, imx * ray_target - imx*ray_origin)
        
        if face_ind == -1:        
            self.grab_cancel()  
        else:
            self.pts[self.selected] = mx * loc
            self.cut_pts[self.selected] = loc
            self.normals[self.selected] = no
            self.face_map[self.selected] = face_ind
Exemple #60
0
def Pick(context, event, self, ray_max=10000.0):
    scene = context.scene
    region = context.region
    rv3d = context.region_data
    coord = event.mouse_region_x, event.mouse_region_y
    view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
    ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
    ray_target = ray_origin + (view_vector * ray_max)

    def obj_ray_cast(obj, matrix):
        matrix_inv = matrix.inverted()
        ray_origin_obj = matrix_inv * ray_origin
        ray_target_obj = matrix_inv * ray_target
        hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
        if face_index != -1:
            return hit, normal, face_index
        else:
            return None, None, None

    best_length_squared = ray_max * ray_max
    best_obj = None
    for obj in self.CList:
        matrix = obj.matrix_world
        hit, normal, face_index = obj_ray_cast(obj, matrix)
        if hit is not None:
            hit_world = matrix * hit
            length_squared = (hit_world - ray_origin).length_squared
            if length_squared < best_length_squared:
                best_length_squared = length_squared
                best_obj = obj
                hits = hit_world
                ns = normal
                fs = face_index
            
    if best_obj is not None:
        return hits, ns, fs
    else:
        return None, None, None