vscode用python開發maya聯動調試設置
3dsMax Python開發環境搭建
3文聯動之debugpy調試max‘python.
3文聯動之socket插槽注入max‘python
本教程是max主動接收創建代碼的方式(預先運行界面,通過按鈕主動讀取py腳本,執行斷點),雖然繞過了pymxs不能在外部編輯器里運行,但是這種方式并不優雅(理想)~~
? ? 從外部進程訪問3ds Max API存在權限問題
? ? Max 2018 (Python 2.7) + VSCode (maxPlus)→ 不支持遠程 attach。
? ? 調試器有Eclipse公司 的pydevd,微軟vs的ptvsd(py2.7,3.0+)->debugpy (py30+),max自身的maxPlus(非遠程調試)
? ? 你要么用 Eclipse的PyCharm + pydevd,要么在用微軟的 VSCode + (ptvsd)里退而求其次(用日志 / socket 打印調試)
? ? 要么升級 Max 到 2021+(Python 3.6+)支 持 debugpy。
?
在這個教程中,我們將使用visualsudio code和Python模塊ptrsd(python TodksforWisualsudioDebugger)創建并調試一個名為“pyamid” 的小型3ds Maxprside2工具。該工具顯示一個帶有按鈕的Q對話框,按下技
鈕會在當前場景中添加一個黑色金字塔。
完成的教程代碼可以在本主題末尾找到,供參考。
先決條件
本教程系列需要以下條件:
·安裝了3ds Max2021或更高版本
·啟動了3ds Max2021或更高版本,并使用Python3解釋器(默認設置)
·已安裝VS Code和Python擴展
·安裝了PS6的3ds Max Python(參見使用pip與Python3)
創建項目
這個項目將被命名為pyramid。PEP-8(Python風格指南)建議模塊使用小寫的名稱。
所以在我們的文件系統中的某個地方,創建一個嵌套的目錄集,兩者都命名為'pyramid':
mkdir -p pyramid/pyramid
我們最終會使用這個目錄結構,為我們的項目添加適當的 pip 包裝信息。在本教程中,我們只需在其中創建程序
啟動 VS Code
·開始與代碼
·使用File>OpenFolder選擇我們的頂級pyramid文件夾
創建源文件
我們的項目很小,但我們將將其分為兩個文件以模擬一個更大的項目。
在pyramid子目錄中創建一個名為?ui.py?的新文件,然后添加以下代碼:
"""Provide a PySide2 dialog for the pyramid tool.
"""
from PySide2.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout, QPushButton
from pymxs import runtime as rt
from .graphics import make_pyramid_meshclass PyMaxDialog(QDialog):"""Custom dialog attached to the 3ds Max main windowMessage label and action push button to create a pyramid in the 3ds Max scene graph"""def __init__(self, parent=QWidget.find(rt.windows.getMAXHWND())):super(PyMaxDialog, self).__init__(parent)self.setWindowTitle('Pyside2 Qt Window')self.init_ui()def init_ui(self):""" Prepare Qt UI layout for custom dialog """main_layout = QVBoxLayout()label = QLabel("Click button to create a pyramid in the scene")main_layout.addWidget(label)btn = QPushButton("Pyramid")btn.clicked.connect(make_pyramid_mesh)main_layout.addWidget(btn)self.setLayout(main_layout)self.resize(250, 100)
建立一個其他的文件名?graphics.py?在同一個目錄里, 并且添加代碼:
"""Provide the graphic functionality for the pryamid tool.
"""
from pymxs import runtime as rtdef make_pyramid_mesh(side=20.0):'''Construct a pyramid from vertices and faces.'''halfside = side / 2.0pyr = rt.mesh(vertices=[rt.point3(0.0, 0.0, side),rt.point3(-halfside, -halfside, 0.0),rt.point3(-halfside, halfside, 0.0),rt.point3(halfside, 0.0, 0.0)],faces=[rt.point3(1, 2, 3),rt.point3(1, 3, 4),rt.point3(1, 4, 2),rt.point3(2, 3, 4),])rt.redrawViews()return pyr
在這個位置你將有以下的目錄結構:
pyramid/pyramid/ui.pygraphics.py
等等,我看到我的導入語句有問題。
Visualstudio code 使用一個代碼檢查工具來驗證導入,默認情況下,它不知道在哪里查找 3ds MaxPython模塊。自動補全系統也可能存在理解源代碼方面的問題。為了解決這個問題,請將Visualstudio Code指向3ds Max的Python解釋器:
通過文件>首選項設置打開設置
·在設置頁面中,打開擴展>Python>自動完成:額外路徑>在settings.json中編輯。這將打開settings.json文件。
添加:
,"python.pythonPath": "C:\\Program Files\\Autodesk\\3ds Max 2021\\Python37\\python.exe","python.autoComplete.extraPaths": [ "C:\\Program Files\\Autodesk\\3ds Max 2021\\Python37" ]
有關此問題的更多信息,請參見此處和此處。
在3ds Max中運行項目的第一版
切換到3ds Max,打開監聽器窗口并選擇Python選項卡。此時,我們應該看到監聽器中顯示的版本字符串表明正在使用Python 3.默認情況下,3dsMaxPython 解釋器不知道示例的位置,但我們希望能夠通過導入使其可用。因此,我們可以在Python監聽器中鍵入此內容(用您自己的路徑替換append 函數):? ? 直接在監聽窗口這里輸出py執行,似乎沒有反應的。
import sys
sys.path.append(r'd:\sources\hacking\python\pyramid')
注意:逐行輸入,使用CtrltEnter執行它們。
然后輸入:
import pyramid.ui
dialog = pyramid.ui.PyMaxDialog()
dialog.show()
這將顯示對話框
如果你按下Pyramid按鈕,你會得到一個異常:
現在我們需要調試這個問題。
從VS Code調試3ds Max的Python代碼
在我們能夠使用調試器來調試3ds Max中的Python代碼之前,我們需要安裝ptvsd(VisualStudio調試服務器的Python工具):
在你的3ds Max Python 3目錄中,在命令行x:\Program Files\Autodesk\3ds Max 2024\Python>中,輸入:
python -m pip install --user ptvsd
安裝完成的樣子
在3ds Max端啟用調試器
ptvsd調試服務器需要在3ds Max Python解釋器中運行。在3ds Max監聽窗口中,輸入:
import ptvsd
ptvsd.enable_attach()
這應該顯示:
('0.0.0.0', 5678)
這里但是!直接輸出python是沒有反應的。
那只有這樣了,做成一個py文件保存,ctrl+e運行。
代碼如下
import sys
sys.path.append(r'd:\sources\hacking\python\pyramid')
import pyramid.ui
dialog = pyramid.ui.PyMaxDialog()
dialog.show()
(在我們的3ds Max會話中,無需重復上一步操作)。
第一次與Vs Code連接
3dsMax現在已準備好接受來自VS Code的連接,但我們仍需告訴vs Code如何與3dsMax進行連接。首次嘗試與3dsMax連接時,需要在VS code中添加遠程調試配置。
在VS Code中,選擇運行>添加配置。
從下拉列表中選擇遠程附加。
然后按回車鍵選擇localhost(默認)然后按回車鍵選擇5678(默認值)
這將添加一個看起來像這樣的配置代碼:
{"name": "Python: Remote Attach","type": "python","request": "attach","connect": {"host": "localhost","port": 5678},"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "."}]}
我們不需要修改這個,除了我們需要指向
直接在我們的源處設置remoteRoot
"remoteRoot": "${workspaceFolder}",
此配置只需設置一次。
如果我們也想調試第三方模塊(例如在pyside2代碼中設置斷點),雖然這在本次示例中不會實現,但這是一個非常常見的調試任務,我們還需要通過在 JSON 文件中添加以下內容來啟用它.
"justMyCode": false
最后,你的Launch.json配置文件是這樣的:(官方代碼里沒有版號和configuaratiions是不能正常運作的,端口號和localhost及得在connect字段里,排在前面的字段后面的逗號記得加)
{"version": "0.2.0","configurations": [{"name": "Python: Remote Attach","type": "python","request": "attach","justMyCode": false,"connect": {"host": "localhost","port": 5678},"pathMappings": [{"localRoot": "${workspaceFolder}","remoteRoot": "${workspaceFolder}"}]}]
}
連接到vs Code
首先通過選擇View>Open View... 并選擇“Run and Debug”來打開運行和調試視圖。我們需要在VS Code中選擇調試配置:
確保選擇了我們的 Python:Remote Attach 配置。在這種情況下,我們可以通過在 Vs Code 菜單中選擇“調試”“開始調試”來將調試器連接到 3ds Max Python.如果我們回到3ds Max,我們會看到UI不再凍結。然而,我們的程序仍然沒有運行。運行程序
要運行我們的腳本,我們需要在3ds Max監聽器窗口中輸入:
dialog.show()
這將運行我們想要但不起作用的對話框。
添加斷點
通過我們程序之前的運行,我們知道graphics.py的第11行存在一個問題。因此,在VScode中,我們可以通過點擊該行左側的邊距來添加斷點:
觸發斷點
此時,當你點擊對話框中的Pyramid
按鈕時,你的斷點將被到達,并且你將在VS Code中看到它被高亮顯示。
你可以檢查局部變量,你會發現 side 變量是 False,這不是我們想要的。
修復代碼
發生的問題是side為False。我們將make_pyramid mesh()連接到對話框按鈕的代碼如下:
btn.clicked.connect(make_pyramid_mesh)
這是有誤的,因為btn.cicked 傳遞給我們的是一個布爾值,它告訴我們按鈕是否處于選中狀態。我們的代碼接收了這個布爾值,而不是我們期望的默認值 20.0.因此我們可以修改這段代碼,傳遞一個將side設置為20.0的lambda函數。
btn.clicked.connect(lambda: make_pyramid_mesh(20.0))
然后我們保存
使新代碼運行
為了將控制權交還給max,我們按下F5(運行->繼續)。我們看到3ds Max再次變得響應。關閉對話框
在監聽器窗口的Python命令提示符中輸入
import importlib
然后
importlib.reload(pyramid.ui)
這顯示類似的內容:
<module 'pyramid.ui' from 'd:\\sources\\hacking\\python\\pyramid\\pyramid\\ui.py'>
我們現在必須通過以下操作重新創建一個全新的對話版本:
dialog = pyramid.ui.PyMaxDialog()
然后:
dialog.show()
臨時的aaa.py內容如下
import sys
sys.path.append(r'd:\sources\hacking\python\pyramid')
import pyramid.ui
import importlib
importlib.reload(pyramid.ui)
dialog = pyramid.ui.PyMaxDialog()
dialog.show()
我們的斷點已到達,但此時 side=20 和 halfside=10 。如果我們按 F5,代碼現在將成功完成,并在視圖中顯示我們的黑色金字塔。
完整代碼:
ui.py:
"""Provide a PySide2 dialog for the pyramid tool.
"""
from PySide2.QtWidgets import QWidget, QDialog, QLabel, QVBoxLayout, QPushButton
from pymxs import runtime as rt
from .graphics import make_pyramid_meshclass PyMaxDialog(QDialog):"""Custom dialog attached to the 3ds Max main windowMessage label and action push button to create a pyramid in the 3ds Max scene graph"""def __init__(self, parent=QWidget.find(rt.windows.getMAXHWND())):super(PyMaxDialog, self).__init__(parent)self.setWindowTitle('Pyside2 Qt Window')self.init_ui()def init_ui(self):""" Prepare Qt UI layout for custom dialog """main_layout = QVBoxLayout()label = QLabel("Click button to create a pyramid in the scene")main_layout.addWidget(label)btn = QPushButton("Pyramid")btn.clicked.connect(lambda: make_pyramid_mesh(20.0))main_layout.addWidget(btn)self.setLayout(main_layout)self.resize(250, 100)
graphics.py:
"""Provide the graphic functionality for the pryamid tool.
"""
from pymxs import runtime as rtdef make_pyramid_mesh(side=20.0):'''Construct a pyramid from vertices and faces.'''halfside = side / 2.0pyr = rt.mesh(vertices=[rt.point3(0.0, 0.0, side),rt.point3(-halfside, -halfside, 0.0),rt.point3(-halfside, halfside, 0.0),rt.point3(halfside, 0.0, 0.0)],faces=[rt.point3(1, 2, 3),rt.point3(1, 3, 4),rt.point3(1, 4, 2),rt.point3(2, 3, 4),])rt.redrawViews()return pyr
父頁: ?教程
下一頁:教程2-添加NumPy,一個外部組件