轉載請注明原文鏈接:https://www.cnblogs.com/mechanicoder/p/16892989.html
1. 前言
本想通過 Context 與 Viewer 的多對一關系嘗試實作三維視圖圖層、圖元分類管理的功能,但經過幾次驗證,尚未找到可行的方法,
2. 三者之間的關系
如下圖所示:

圖1. Context Viewer View 三者之間關系
圖中的各命名分別表示:
Context: AIS_InteractiveContext
Viewer: V3d_Viewer
View: V3d_View
GUI: 與實作相關,互動界面,如 Qt 中的QWidget
OpenGL: OpenGl_GraphicDriver
Viewer:3D查看器,建立用戶 GUI 與OpenGL 之間的連接,處理渲染,如著色、光照、投影方式等,同一個3D 查看器可以被多個互動場景使用,可實作多個場景的快速切換,
Handle(OpenGl_GraphicDriver) graph_driver = new OpenGl_GraphicDriver(aDisplayConnection);
Handle(V3d_Viewer) viewer = new V3d_Viewer(graph_driver);
// 默認是 Graphic3d_TypeOfShadingModel_Phong
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_Phong);
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_Unlit);
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_PhongFacet);
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_Gouraud);
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_Pbr);
viewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_PbrFacet);

圖2. 不同光照渲染效果
Context:互動場景,負責管理顯示物件(或稱圖元),例如顯示模型、顯示網格、處理模型選擇等,初始化時必須指定一個 3D查看器,也就是說必須告訴互動場景以何種方式顯示其中的各個圖元,
Handle(AIS_InteractiveContext) context = new AIS_InteractiveContext(viewer);
for (size_t i = 0; i < _contexts.size(); i++) // Viewer->Context 1對多
{
_contexts[i] = new AIS_InteractiveContext(viewer);
_contexts[i]->SetDisplayMode(1, false); // Shaded
}
context->SetDeviationCoefficient(0.001); // 設定構造渲染資料時的誤差系數
View:3D視圖,由 3D查看器創建的具體視圖,以特定的相機視角顯示Viewer渲染后的圖元,一個3D查看器可以創建多個多個視圖,例如以不同的相機視角、不同的縮放比例顯示同一個場景(當前激活場景)中的圖元,可參考文章Open Cascade 多視圖-多個3D視圖,
Handle(V3d_View) view = viewer->CreateView()
在圖1可中,AIS_ViewController 是OCC升級新增的一個互動工具類,用于處理3D視圖GUI執行緒和渲染執行緒之間的互動事件,如滑鼠旋轉、框選等操作,建立了 View 與 Context 之間的直接聯系,
因此,GUI 對 3D視圖 View 的滑鼠懸浮、點擊等互動操作通過 AIS_ViewController 傳遞給 Context 進行處理,對應地分別回應為高亮、選中等顯示效果,并將更新后的互動場景由 Viewer 重繪至 View 中,
AIS_ViewController::FlushViewEvents(allContexts[0], myView, true); // GUI 事件由 allContexts[0] 回應
AIS_ViewController::FlushViewEvents(allContexts[1], myView, true); // 2
AIS_ViewController::FlushViewEvents(allContexts[2], myView, true); // 3
以上注釋為 2、3的兩行代碼并不產生實際效果(參考最后實作效果),仍然只有 allContexts[0] 回應了 GUI 事件,直觀理解:GUI 事件被一個互動場景 Context 處理后即被標記為“已處理”,不再向后傳遞,實際原理如何還需要再深究,
3. 測驗驗證
同一個3D查看器對應多個互動場景,各互動場景可顯示、隱藏其中的所有圖元,按圖元型別分別創建多個互動場景:0-立方體Box, 1-圓環Torus, 2-坐標系Trihedron, 3-球體Spherre, 4-PointCloud點云(點云的生成即不同顯示效果可參考Open Cascade 7.7.0:新功能-模擬三維掃面點云-BRepLib_PointCloudShape),實作的效果如下:

圖3. GUI 事件僅被一個互動場景 Context 處理
上圖中,通過點擊左上角按鈕 隨機生成不同型別的圖元資料,并按型別將圖元資料放置到不同的交出場景 Context 中,左下角按鈕 用于顯示或隱藏其對應的 Context 中的所有圖元,
從圖中可以看出只有球可以被選中,無法選中立方體、圓環等其他物體,而球型別的圖元放置在 _contexts[3] 中,在 Qt GUI 的重繪事件中如下實作:
void GUIView::paintEvent(QPaintEvent*)
{
myView->InvalidateImmediate();
FlushViewEvents(allContexts[3], myView, true);
FlushViewEvents(allContexts[1], myView, true); // 實際不產生效果
}
結論:無法將 GUI 事件直接傳遞到多個互動場景 Context 中,
源代碼地址,
參考資料
1. OCC用戶檔案:V3d_Viewer Class Reference - Open CASCADE Technology Documentation
2. OCC用戶檔案:AIS_InteractiveContext Class Reference - Open CASCADE Technology Documentation
3. OCC用戶檔案:Open CASCADE Technology: AIS_ViewController Class Reference
4. OCC已被廢棄的功能——Local Context removal - Forum Open Cascade Technology
轉載請注明原文鏈接:https://www.cnblogs.com/mechanicoder/p/16892989.html
?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/534178.html
標籤:其他
上一篇:隱私計算開源框架「隱語SecretFlow」分層拆解和聯邦學習演算法使用
下一篇:Markdown基礎指令及用處
