semagnum / light-painter

Blender add-on that creates lights based on where the user paints.
https://semagnum.github.io/light-painter/
GNU General Public License v3.0
310 stars 6 forks source link

Cursor fails to wrap around during drag modes #51

Closed chenpaner closed 10 months ago

chenpaner commented 10 months ago

1,When add a “LIGHT_AREA”,Radius mode seems to be ruled out, right?

2,When using the mouse to adjust the brightness, the adjustment range is limited by the width of the area, because when I move the mouse to the edge of the area, I can't continue to adjust. I found this article to solve this limitation. My own plugin is implemented according to the method here. At the moment when the mouse pointer goes beyond the work area on one side, it immediately returns to this area, but from the opposite side. https://b3d.interplanety.org/en/locking-the-mouse-cursor-within-the-area-in-blender/

semagnum commented 10 months ago

Splitting this since into separate issues, especially since they're unrelated.

semagnum commented 10 months ago
  1. Split into #52
  2. This was the plan for the release, but unfortunately adding 'GRAB_CURSOR', 'BLOCKING' doesn't work.
    • the reason for the "Edge of the area" not working is that the bounds for the tool and n panels (not just their actual UI box, but anything below them) are not considered the main area. I initially wanted artists to be able to easily click on buttons and tools as needed, but since that cancels the operator anyway, it may be better to just have it always on. Separate issue.
    • Artists only want this to happen during a drag mode, not the entire time. You can't have it enabled part of the time, as it must be defined and locked in upon operator registration. -When tested, while adding these does solve dragging, it breaks the operator when painting - if I wrap the cursor, it doesn't map the tool's coordinates if I wrap around the area. It simply won't paint.

So, any workaround would involve hacking the cursor to stay in the area (also mentioned in your link, which didn't correctly link in GitHub btw). I'd rather avoid that but may not have that luxury. But if you have a tested solution, feel free to share it with a pull request.

chenpaner commented 10 months ago

I'm` sorry for my English level, I basically rely on google translate to understand your reply, I haven't figured out how to make a pull request.

I guess what you mean is that when the mouse moves, it should be automatically recognized that it is not in the tool and n-plane area to avoid misoperation. At the same time, the mouse can still be operated in the tool and N panel during the operation of the operator. If my understanding is correct, then the following code is my solution.

class SNA_OT_Placereflection_5B904(bpy.types.Operator):
    ......
    def modal(self, context, event):#处理用户交互的模态操作方法  
        check_region(self,context,event)#判断鼠标左键操作时区域,self.in_view_3d让左键在3dview的n面板和工具栏里不是选择操作

        #
        if event.type == 'LEFTMOUSE' and self.in_view_3d:
            if event.value == 'PRESS':
                self.isDragging = True
                bpy.context.window.cursor_modal_set("PAINT_CROSS")#设置鼠标图标CROSSHAIR:十字光标
                return {'RUNNING_MODAL'}

            elif event.value == 'RELEASE':
                self.isDragging = False
                bpy.context.window.cursor_modal_restore()#1还原鼠标图标为默认

       #反射打光
        if event.type == 'MOUSEMOVE' and self.isDragging and self.in_view_3d :
            ......

def check_region(self,context,event):
    try:
        self.in_view_3d = False
        for area in context.screen.areas:
            if area.type == "VIEW_3D" :
                for region in context.area.regions:
                    if region.type == "TOOLS":
                        t_panel = region
                    elif region.type == "UI":
                        ui_panel = region
                # 计算3D视图区域的X和Y范围
                view_3d_region_x = Vector((context.area.x + t_panel.width, context.area.x + context.area.width - (ui_panel.width+1)))
                view_3d_region_y = Vector((context.region.y, context.region.y + context.region.height))
                # 检查鼠标事件是否在3D视图区域内
                if (event.mouse_x > view_3d_region_x[0] and event.mouse_x < view_3d_region_x[1] \
                and event.mouse_y > view_3d_region_y[0] and event.mouse_y < view_3d_region_y[1]):
                    self.in_view_3d = True
                    return True
    except:
        self.report({'WARNING'},
                    "Operation finished. (Check the console for more info)")
semagnum commented 10 months ago

I'm sorry for my English level, I basically rely on google translate to understand your reply, I haven't figured out how to make a pull request.

It's okay. I've worked with non-English speakers in the past; I know it can be frustrating for you. I'll try to be as clear as I can for Google Translate :)

Please continue reporting bugs as you see them. I understand if you do not have a coding environment setup with GitHub. I suggested a pull request as that means the solution has been tested to work. But I understand not everyone has the time to test solutions, especially during this holiday season.

I guess what you mean is that when the mouse moves, it should be automatically recognized that it is not in the tool and n-plane area to avoid misoperation.

Light Painter will not fail if the cursor happened to be under the tool or n-panel areas. I prevent Light Painter from being used while the cursor in those areas because I want to make sure artists can click in the tool header buttons or other tools if necessary. But that is a separate issue that can be changed: I made #53 specifically for that. I'm trying to keep issues separate so we do not get lost or confused.

This issue is specific to your second issue from your first post: the cursor failing to wrap around the region during drag mode.