Skip to content

Commit da4a6eb

Browse files
committed
Add sample based for QtQuick/QML
1 parent b49d5c3 commit da4a6eb

11 files changed

Lines changed: 1280 additions & 0 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ project (occt-qt)
55

66
add_subdirectory (occt-qwidget)
77
add_subdirectory (occt-qopenglwidget)
8+
add_subdirectory (occt-qtquick)

ReadMe.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,15 @@ Unlike `QWidget` sample, the widgets on top of `QOpenGLWidget` holding 3D Viewer
3838
as Qt will be able to blend widgets together on its own.
3939

4040
![sample screenshot](/images/occt-qopenglwidget-sample-x11.png)
41+
42+
## OCCT QtQuick/QML sample
43+
44+
Project within `occt-qtquick` subfolder shows initialization of OCCT 3D viewer
45+
from OpenGL context created by `QQuickFramebufferObject` within Qt5 QtQuick/QML application.
46+
47+
The approach with `QQuickFramebufferObject` requires careful gluing layer for Qt and OCCT 3D Viewer to share common OpenGL context.
48+
49+
`QtQuick` by default will attempt offloading rendering into a separate working thread (`QSGRenderThread`) on some systems,
50+
which requires addition of multithreading synchronization mechanism when dealing with OCCT 3D Viewer from GUI thread.
51+
Uncomment lines setting `QSG_RENDER_LOOP` environment variable,
52+
if these complexities are undesired to ask Qt managing rendering from GUI thread.

occt-qtquick/CMakeLists.txt

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
cmake_minimum_required (VERSION 3.2)
2+
3+
project (occt-qtquick-sample)
4+
5+
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../adm/cmake" ${CMAKE_MODULE_PATH})
6+
set (APP_VERSION_MAJOR 1)
7+
set (APP_VERSION_MINOR 0)
8+
9+
# compiler flags
10+
set (CMAKE_CXX_STANDARD 11)
11+
if (MSVC)
12+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise /EHa /MP")
13+
string (REGEX REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
14+
add_definitions (-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -DUNICODE)
15+
else()
16+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -fPIC")
17+
add_definitions (-DOCC_CONVERT_SIGNALS)
18+
endif()
19+
20+
# increase compiler warnings level (-W3 for MSVC, -Wextra for GCC)
21+
if (MSVC)
22+
if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
23+
string (REGEX REPLACE "/W[0-4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
24+
else()
25+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
26+
endif()
27+
elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
28+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
29+
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
30+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshorten-64-to-32")
31+
endif()
32+
if (BUILD_SHARED_LIBS)
33+
if (APPLE)
34+
set (CMAKE_SHARED_LINKER_FLAGS "-lm ${CMAKE_SHARED_LINKER_FLAGS}")
35+
elseif (NOT WIN32)
36+
set (CMAKE_SHARED_LINKER_FLAGS "-lm ${CMAKE_SHARED_LINKER_FLAGS}")
37+
endif()
38+
endif()
39+
endif()
40+
41+
# Find dependencies
42+
set (OpenCASCADE_DIR "" CACHE PATH "Path to Open CASCADE libraries.")
43+
if (MSVC)
44+
set (3RDPARTY_DLL_DIRS "" CACHE STRING "Paths to external DLLs separated by semicolon (FreeImage, FreeType, etc.)")
45+
endif()
46+
47+
# Find OpenGL
48+
find_package (OpenGL REQUIRED)
49+
50+
# Find Qt
51+
set (QT_VERSION "Qt5" CACHE STRING "Qt major version to use")
52+
set_property (CACHE QT_VERSION PROPERTY STRINGS Qt5 Qt6)
53+
set (CMAKE_AUTOUIC ON)
54+
set (CMAKE_AUTOMOC ON)
55+
set (CMAKE_AUTORCC ON)
56+
set_property (GLOBAL PROPERTY AUTOMOC_SOURCE_GROUP "Generated Files/Moc")
57+
set_property (GLOBAL PROPERTY AUTORCC_SOURCE_GROUP "Generated Files/Resources")
58+
set (Qt_COMPONENTS Core Gui Qml Quick QuickControls2 Widgets)
59+
set (Qt_LIBS)
60+
foreach (aLibIter ${Qt_COMPONENTS})
61+
list (APPEND Qt_LIBS "${QT_VERSION}::${aLibIter}")
62+
endforeach()
63+
find_package (${QT_VERSION} COMPONENTS ${Qt_COMPONENTS} REQUIRED)
64+
message (STATUS "Using ${QT_VERSION} from \"${${QT_VERSION}_DIR}\"")
65+
66+
# Find Open CASCADE Technology
67+
find_package (OpenCASCADE REQUIRED)
68+
if (NOT OpenCASCADE_FOUND)
69+
message (FATAL_ERROR "could not find OpenCASCADE, please set OpenCASCADE_DIR variable" )
70+
else()
71+
message (STATUS "Using OpenCASCADE from \"${OpenCASCADE_INSTALL_PREFIX}\"" )
72+
message (STATUS "OpenCASCADE_INCLUDE_DIR=${OpenCASCADE_INCLUDE_DIR}")
73+
message (STATUS "OpenCASCADE_LIBRARY_DIR=${OpenCASCADE_LIBRARY_DIR}")
74+
include_directories(${OpenCASCADE_INCLUDE_DIR})
75+
link_directories (${OpenCASCADE_LIBRARY_DIR})
76+
endif()
77+
set (OpenCASCADE_LIBS TKRWMesh TKBinXCAF TKBin TKBinL TKOpenGl TKXCAF TKVCAF TKCAF TKV3d TKHLR TKMesh TKService TKShHealing TKPrim TKTopAlgo TKGeomAlgo TKBRep TKGeomBase TKG3d TKG2d TKMath TKLCAF TKCDF TKernel)
78+
79+
# main project target
80+
add_executable (${PROJECT_NAME}
81+
main.cpp
82+
main.qml
83+
OcctGlTools.h
84+
OcctGlTools.cpp
85+
OcctQtTools.h
86+
OcctQQuickFramebufferViewer.h
87+
OcctQQuickFramebufferViewer.cpp
88+
occt-qtquick.qrc
89+
)
90+
target_link_libraries (${PROJECT_NAME} PRIVATE
91+
${Qt_LIBS}
92+
${OpenCASCADE_LIBS}
93+
${OPENGL_LIBRARIES}
94+
)
95+
96+
# auxiliary development environment
97+
if (MSVC)
98+
set (X_COMPILER_BITNESS x64)
99+
get_target_property (QtCore_location ${QT_VERSION}::Core LOCATION)
100+
get_filename_component (QT_BINARY_DIR ${QtCore_location} DIRECTORY)
101+
set (QT_PLUGINS_DIR)
102+
if (EXISTS "${QT_BINARY_DIR}/../plugins")
103+
set (QT_PLUGINS_DIR "${QT_BINARY_DIR}/../plugins")
104+
endif()
105+
106+
get_target_property (aTKernelRel "TKernel" IMPORTED_LOCATION_RELEASE)
107+
get_target_property (aTKernelDbg "TKernel" IMPORTED_LOCATION_DEBUG)
108+
get_filename_component (OpenCASCADE_BINARY_DIR_RELEASE ${aTKernelRel} DIRECTORY)
109+
get_filename_component (OpenCASCADE_BINARY_DIR_DEBUG ${aTKernelDbg} DIRECTORY)
110+
if (NOT EXISTS "${OpenCASCADE_BINARY_DIR_DEBUG}" AND EXISTS "${OpenCASCADE_BINARY_DIR_RELEASE}")
111+
set (OpenCASCADE_BINARY_DIR_DEBUG "${OpenCASCADE_BINARY_DIR_RELEASE}")
112+
elseif (NOT EXISTS "${OpenCASCADE_BINARY_DIR_RELEASE}" AND EXISTS "${OpenCASCADE_BINARY_DIR_DEBUG}")
113+
set (OpenCASCADE_BINARY_DIR_RELEASE "${OpenCASCADE_BINARY_DIR_DEBUG}")
114+
endif()
115+
116+
set_target_properties (${PROJECT_NAME} PROPERTIES
117+
VS_DEBUGGER_ENVIRONMENT "\
118+
PATH=%PATH%;$<IF:$<CONFIG:Debug>,${OpenCASCADE_BINARY_DIR_DEBUG},${OpenCASCADE_BINARY_DIR_RELEASE}>;${3RDPARTY_DLL_DIRS};${QT_BINARY_DIR}\n\
119+
QT_PLUGIN_PATH=${QT_PLUGINS_DIR}"
120+
)
121+
endif()

occt-qtquick/OcctGlTools.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2023 Kirill Gavrilov
2+
3+
#include "OcctGlTools.h"
4+
5+
#include <OpenGl_GraphicDriver.hxx>
6+
#include <OpenGl_FrameBuffer.hxx>
7+
#include <OpenGl_View.hxx>
8+
#include <OpenGl_Window.hxx>
9+
10+
// ================================================================
11+
// Function : GetGlContext
12+
// ================================================================
13+
Handle(OpenGl_Context) OcctGlTools::GetGlContext(const Handle(V3d_View)& theView)
14+
{
15+
Handle(OpenGl_View) aGlView = Handle(OpenGl_View)::DownCast(theView->View());
16+
return aGlView->GlWindow()->GetGlContext();
17+
}

occt-qtquick/OcctGlTools.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2023 Kirill Gavrilov
2+
3+
#ifndef _OcctGlTools_HeaderFile
4+
#define _OcctGlTools_HeaderFile
5+
6+
#include <V3d_View.hxx>
7+
8+
class OpenGl_Context;
9+
10+
//! Auxiliary wrapper to avoid OpenGL macros collisions between Qt and OCCT headers.
11+
class OcctGlTools
12+
{
13+
public:
14+
//! Return GL context.
15+
static Handle(OpenGl_Context) GetGlContext(const Handle(V3d_View)& theView);
16+
};
17+
18+
#endif // _OcctGlTools_HeaderFile

0 commit comments

Comments
 (0)