mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9e4269d8e6 | ||
|
5f55b8e615 | ||
|
057d4b15e3 | ||
|
4c04741d4c | ||
|
0d56f7433b | ||
|
acc6542a1b | ||
|
803bdcdf2b | ||
|
b6c113d0eb | ||
|
82c59511b4 | ||
|
d9dd07545d | ||
|
88c3accd1a | ||
|
3c1b70842d | ||
|
62810a3c51 | ||
|
bbf3fcdecd | ||
|
e05d8d90c0 | ||
|
841aa8c47b | ||
|
95bde2af7f | ||
|
64a4475285 | ||
|
0c33a0bf4d | ||
|
4151c94d20 | ||
|
0a419c51ed | ||
|
eec6e810f1 | ||
|
c2a25d522b | ||
|
fe525c6f7c | ||
|
3b739e69c9 | ||
|
c9983ee863 | ||
|
912761ea17 | ||
|
1bb67d3844 |
@@ -633,6 +633,26 @@ else()
|
|||||||
OCCT_CHECK_AND_UNSET ("INSTALL_TBB")
|
OCCT_CHECK_AND_UNSET ("INSTALL_TBB")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# RapidJSON
|
||||||
|
# search for CSF_RapidJSON variable in EXTERNLIB of each being used toolkit
|
||||||
|
OCCT_IS_PRODUCT_REQUIRED (CSF_RapidJSON CAN_USE_RAPIDJSON)
|
||||||
|
if (CAN_USE_RAPIDJSON)
|
||||||
|
set (USE_RAPIDJSON OFF CACHE BOOL "${USE_RAPIDJSON_DESCR}")
|
||||||
|
|
||||||
|
if (USE_RAPIDJSON)
|
||||||
|
add_definitions (-DHAVE_RAPIDJSON)
|
||||||
|
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/rapidjson")
|
||||||
|
else()
|
||||||
|
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_RAPIDJSON")
|
||||||
|
OCCT_CHECK_AND_UNSET ("INSTALL_RAPIDJSON")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
OCCT_CHECK_AND_UNSET ("USE_RAPIDJSON")
|
||||||
|
|
||||||
|
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_RAPIDJSON")
|
||||||
|
OCCT_CHECK_AND_UNSET ("INSTALL_RAPIDJSON")
|
||||||
|
endif()
|
||||||
|
|
||||||
# EIGEN
|
# EIGEN
|
||||||
if (CAN_USE_EIGEN)
|
if (CAN_USE_EIGEN)
|
||||||
set (USE_EIGEN OFF CACHE BOOL "${USE_EIGEN_DESCR}")
|
set (USE_EIGEN OFF CACHE BOOL "${USE_EIGEN_DESCR}")
|
||||||
|
@@ -440,4 +440,6 @@ t TKVCAF
|
|||||||
n XCAFView
|
n XCAFView
|
||||||
n XCAFNoteObjects
|
n XCAFNoteObjects
|
||||||
t TKRWMesh
|
t TKRWMesh
|
||||||
|
n RWGltf
|
||||||
n RWMesh
|
n RWMesh
|
||||||
|
n RWObj
|
||||||
|
@@ -73,7 +73,7 @@ if (WIN32)
|
|||||||
set (CSF_OpenGlLibs "opengl32.lib")
|
set (CSF_OpenGlLibs "opengl32.lib")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set (CSF_objc "objc")
|
set (CSF_objc "objc")
|
||||||
@@ -117,5 +117,6 @@ if (WIN32)
|
|||||||
endif()
|
endif()
|
||||||
set (CSF_XwLibs "X11 Xext Xmu Xi")
|
set (CSF_XwLibs "X11 Xext Xmu Xi")
|
||||||
set (CSF_dl "dl")
|
set (CSF_dl "dl")
|
||||||
|
set (CSF_fontconfig "fontconfig")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
86
adm/cmake/rapidjson.cmake
Normal file
86
adm/cmake/rapidjson.cmake
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# RapidJSON
|
||||||
|
|
||||||
|
if (NOT DEFINED INSTALL_RAPIDJSON)
|
||||||
|
set (INSTALL_RAPIDJSON OFF CACHE BOOL "${INSTALL_RAPIDJSON_DESCR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# RapidJSON directory
|
||||||
|
if (NOT DEFINED 3RDPARTY_RAPIDJSON_DIR)
|
||||||
|
set (3RDPARTY_RAPIDJSON_DIR "" CACHE PATH "The directory containing RapidJSON")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# search for RapidJSON in user defined directory
|
||||||
|
if (3RDPARTY_DIR AND EXISTS "${3RDPARTY_DIR}")
|
||||||
|
if (NOT 3RDPARTY_RAPIDJSON_DIR OR NOT EXISTS "${3RDPARTY_RAPIDJSON_DIR}")
|
||||||
|
FIND_PRODUCT_DIR("${3RDPARTY_DIR}" RapidJSON RAPIDJSON_DIR_NAME)
|
||||||
|
if (RAPIDJSON_DIR_NAME)
|
||||||
|
set (3RDPARTY_RAPIDJSON_DIR "${3RDPARTY_DIR}/${RAPIDJSON_DIR_NAME}" CACHE PATH "The directory containing RapidJSON" FORCE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT DEFINED 3RDPARTY_RAPIDJSON_INCLUDE_DIR)
|
||||||
|
set (3RDPARTY_RAPIDJSON_INCLUDE_DIR "" CACHE FILEPATH "The directory containing headers of the RAPIDJSON")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT 3RDPARTY_RAPIDJSON_INCLUDE_DIR OR NOT EXISTS "${3RDPARTY_RAPIDJSON_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
set (HEADER_NAMES rapidjson/rapidjson.h)
|
||||||
|
|
||||||
|
set (3RDPARTY_RAPIDJSON_INCLUDE_DIR "3RDPARTY_RAPIDJSON_INCLUDE_DIR-NOTFOUND" CACHE PATH "the path to RapidJSON header file" FORCE)
|
||||||
|
|
||||||
|
if (3RDPARTY_RAPIDJSON_DIR AND EXISTS "${3RDPARTY_RAPIDJSON_DIR}")
|
||||||
|
find_path (3RDPARTY_RAPIDJSON_INCLUDE_DIR NAMES ${HEADER_NAMES}
|
||||||
|
PATHS ${3RDPARTY_RAPIDJSON_DIR}
|
||||||
|
PATH_SUFFIXES include rapidjson
|
||||||
|
CMAKE_FIND_ROOT_PATH_BOTH
|
||||||
|
NO_DEFAULT_PATH)
|
||||||
|
else()
|
||||||
|
find_path (3RDPARTY_RAPIDJSON_INCLUDE_DIR NAMES ${HEADER_NAMES}
|
||||||
|
PATH_SUFFIXES include rapidjson
|
||||||
|
CMAKE_FIND_ROOT_PATH_BOTH)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# use default (CMake) RapidJSON search
|
||||||
|
if (NOT 3RDPARTY_RAPIDJSON_INCLUDE_DIR OR NOT EXISTS "${3RDPARTY_RAPIDJSON_INCLUDE_DIR}")
|
||||||
|
if (3RDPARTY_RAPIDJSON_DIR AND EXISTS "${3RDPARTY_RAPIDJSON_DIR}")
|
||||||
|
set (CACHED_RAPIDJSON_DIR $ENV{RapidJSON_DIR})
|
||||||
|
set (ENV{RapidJSON_DIR} "${3RDPARTY_RAPIDJSON_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(RapidJSON QUIET)
|
||||||
|
|
||||||
|
# restore ENV{RapidJSON_DIR}
|
||||||
|
if (3RDPARTY_RAPIDJSON_DIR AND EXISTS "${3RDPARTY_RAPIDJSON_DIR}")
|
||||||
|
set (ENV{RapidJSON_DIR} ${CACHED_RAPIDJSON_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${RAPIDJSON_FOUND})
|
||||||
|
set (3RDPARTY_RAPIDJSON_INCLUDE_DIR "${RAPIDJSON_INCLUDE_DIR}" CACHE PATH "the path to RapidJSON header file" FORCE)
|
||||||
|
set (3RDPARTY_RAPIDJSON_DIR "${RAPIDJSON_ROOT_DIR}" CACHE PATH "The directory containing RapidJSON" FORCE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (3RDPARTY_RAPIDJSON_INCLUDE_DIR AND EXISTS "${3RDPARTY_RAPIDJSON_INCLUDE_DIR}")
|
||||||
|
list (APPEND 3RDPARTY_INCLUDE_DIRS "${3RDPARTY_RAPIDJSON_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
# Install header files
|
||||||
|
if (INSTALL_RAPIDJSON)
|
||||||
|
file(GLOB RAPIDJSON_SUBDIRS "${3RDPARTY_RAPIDJSON_INCLUDE_DIR}/*")
|
||||||
|
foreach(SUBDIR ${RAPIDJSON_SUBDIRS})
|
||||||
|
if(IS_DIRECTORY "${SUBDIR}")
|
||||||
|
install (DIRECTORY "${SUBDIR}" DESTINATION "${INSTALL_DIR_INCLUDE}")
|
||||||
|
else()
|
||||||
|
install (FILES "${SUBDIR}" DESTINATION "${INSTALL_DIR_INCLUDE}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_RAPIDJSON_INCLUDE_DIR)
|
||||||
|
|
||||||
|
set (3RDPARTY_RAPIDJSON_INCLUDE_DIR "" CACHE PATH "the path to RapidJSON header file" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# unset all redundant variables
|
||||||
|
OCCT_CHECK_AND_UNSET(RapidJSON_DIR)
|
@@ -94,6 +94,7 @@ INSTALL_MESSAGE (INSTALL_EGL "EGL binaries")
|
|||||||
INSTALL_MESSAGE (INSTALL_GLES2 "OpenGL ES 2.0 binaries")
|
INSTALL_MESSAGE (INSTALL_GLES2 "OpenGL ES 2.0 binaries")
|
||||||
INSTALL_MESSAGE (INSTALL_FREETYPE "FreeType binaries")
|
INSTALL_MESSAGE (INSTALL_FREETYPE "FreeType binaries")
|
||||||
INSTALL_MESSAGE (INSTALL_TBB "TBB binaries")
|
INSTALL_MESSAGE (INSTALL_TBB "TBB binaries")
|
||||||
|
INSTALL_MESSAGE (INSTALL_RAPIDJSON "RapidJSON header files")
|
||||||
INSTALL_MESSAGE (INSTALL_TCL "TCL binaries")
|
INSTALL_MESSAGE (INSTALL_TCL "TCL binaries")
|
||||||
INSTALL_MESSAGE (INSTALL_TK "TK binaries")
|
INSTALL_MESSAGE (INSTALL_TK "TK binaries")
|
||||||
INSTALL_MESSAGE (INSTALL_VTK "VTK binaries ")
|
INSTALL_MESSAGE (INSTALL_VTK "VTK binaries ")
|
||||||
@@ -161,6 +162,10 @@ set (USE_FREEIMAGE_DESCR
|
|||||||
"Indicates whether Freeimage product should be used in OCCT visualization
|
"Indicates whether Freeimage product should be used in OCCT visualization
|
||||||
module for support of popular graphics image formats (PNG, BMP etc)")
|
module for support of popular graphics image formats (PNG, BMP etc)")
|
||||||
|
|
||||||
|
set (USE_RAPIDJSON_DESCR
|
||||||
|
"Indicates whether RapidJSON product should be used in OCCT DataExchange
|
||||||
|
module for support of JSON-based formats like glTF")
|
||||||
|
|
||||||
set (USE_EGL_DESCR
|
set (USE_EGL_DESCR
|
||||||
"Indicates whether EGL should be used in OCCT visualization
|
"Indicates whether EGL should be used in OCCT visualization
|
||||||
module instead of conventional OpenGL context creation APIs")
|
module instead of conventional OpenGL context creation APIs")
|
||||||
|
@@ -189,6 +189,9 @@ proc wokdep:gui:UpdateList {} {
|
|||||||
}
|
}
|
||||||
wokdep:SearchStandardLibrary anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs "liblzma" "lzma.h" "$aCheckLib" {"lzma" "xz"}
|
wokdep:SearchStandardLibrary anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs "liblzma" "lzma.h" "$aCheckLib" {"lzma" "xz"}
|
||||||
}
|
}
|
||||||
|
if { "$::HAVE_RAPIDJSON" == "true" } {
|
||||||
|
wokdep:SearchRapidJson anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||||
|
}
|
||||||
|
|
||||||
if { "$::CHECK_QT4" == "true" } {
|
if { "$::CHECK_QT4" == "true" } {
|
||||||
wokdep:SearchQt4 anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
wokdep:SearchQt4 anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||||
@@ -456,6 +459,9 @@ ttk::label .myFrame.myChecks.myZLibLbl -text "Use zlib"
|
|||||||
checkbutton .myFrame.myChecks.myLzmaCheck -offvalue "false" -onvalue "true" -variable HAVE_LIBLZMA -command wokdep:gui:UpdateList
|
checkbutton .myFrame.myChecks.myLzmaCheck -offvalue "false" -onvalue "true" -variable HAVE_LIBLZMA -command wokdep:gui:UpdateList
|
||||||
ttk::label .myFrame.myChecks.myLzmaLbl -text "Use liblzma"
|
ttk::label .myFrame.myChecks.myLzmaLbl -text "Use liblzma"
|
||||||
|
|
||||||
|
checkbutton .myFrame.myChecks.myRapidJsonCheck -offvalue "false" -onvalue "true" -variable HAVE_RAPIDJSON -command wokdep:gui:UpdateList
|
||||||
|
ttk::label .myFrame.myChecks.myRapidJsonLbl -text "Use RapidJSON"
|
||||||
|
|
||||||
checkbutton .myFrame.myChecks.myQt4Check -offvalue "false" -onvalue "true" -variable CHECK_QT4 -command wokdep:gui:UpdateList
|
checkbutton .myFrame.myChecks.myQt4Check -offvalue "false" -onvalue "true" -variable CHECK_QT4 -command wokdep:gui:UpdateList
|
||||||
ttk::label .myFrame.myChecks.myQt4Lbl -text "Search Qt4"
|
ttk::label .myFrame.myChecks.myQt4Lbl -text "Search Qt4"
|
||||||
checkbutton .myFrame.myChecks.myJDKCheck -offvalue "false" -onvalue "true" -variable CHECK_JDK -command wokdep:gui:UpdateList
|
checkbutton .myFrame.myChecks.myJDKCheck -offvalue "false" -onvalue "true" -variable CHECK_JDK -command wokdep:gui:UpdateList
|
||||||
@@ -564,8 +570,8 @@ if { "$::tcl_platform(os)" != "Darwin" } {
|
|||||||
grid .myFrame.myChecks.myZLibCheck -row $aCheckRowIter -column 6 -sticky e
|
grid .myFrame.myChecks.myZLibCheck -row $aCheckRowIter -column 6 -sticky e
|
||||||
grid .myFrame.myChecks.myZLibLbl -row $aCheckRowIter -column 7 -sticky w
|
grid .myFrame.myChecks.myZLibLbl -row $aCheckRowIter -column 7 -sticky w
|
||||||
|
|
||||||
grid .myFrame.myChecks.myQt4Check -row $aCheckRowIter -column 10 -sticky e
|
grid .myFrame.myChecks.myQt4Check -row $aCheckRowIter -column 12 -sticky e
|
||||||
grid .myFrame.myChecks.myQt4Lbl -row $aCheckRowIter -column 11 -sticky w
|
grid .myFrame.myChecks.myQt4Lbl -row $aCheckRowIter -column 13 -sticky w
|
||||||
|
|
||||||
incr aCheckRowIter
|
incr aCheckRowIter
|
||||||
grid .myFrame.myChecks.myFFmpegCheck -row $aCheckRowIter -column 0 -sticky e
|
grid .myFrame.myChecks.myFFmpegCheck -row $aCheckRowIter -column 0 -sticky e
|
||||||
@@ -578,8 +584,8 @@ if { "$::tcl_platform(platform)" == "windows" } {
|
|||||||
}
|
}
|
||||||
grid .myFrame.myChecks.myLzmaCheck -row $aCheckRowIter -column 6 -sticky e
|
grid .myFrame.myChecks.myLzmaCheck -row $aCheckRowIter -column 6 -sticky e
|
||||||
grid .myFrame.myChecks.myLzmaLbl -row $aCheckRowIter -column 7 -sticky w
|
grid .myFrame.myChecks.myLzmaLbl -row $aCheckRowIter -column 7 -sticky w
|
||||||
grid .myFrame.myChecks.myJDKCheck -row $aCheckRowIter -column 10 -sticky e
|
grid .myFrame.myChecks.myJDKCheck -row $aCheckRowIter -column 12 -sticky e
|
||||||
grid .myFrame.myChecks.myJDKLbl -row $aCheckRowIter -column 11 -sticky w
|
grid .myFrame.myChecks.myJDKLbl -row $aCheckRowIter -column 13 -sticky w
|
||||||
|
|
||||||
incr aCheckRowIter
|
incr aCheckRowIter
|
||||||
if { "$::tcl_platform(os)" == "Darwin" } {
|
if { "$::tcl_platform(os)" == "Darwin" } {
|
||||||
@@ -588,6 +594,10 @@ if { "$::tcl_platform(os)" == "Darwin" } {
|
|||||||
incr aCheckRowIter
|
incr aCheckRowIter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grid .myFrame.myChecks.myRapidJsonCheck -row $aCheckRowIter -column 6 -sticky e
|
||||||
|
grid .myFrame.myChecks.myRapidJsonLbl -row $aCheckRowIter -column 7 -sticky w
|
||||||
|
incr aCheckRowIter
|
||||||
|
|
||||||
# Additional headers search paths
|
# Additional headers search paths
|
||||||
grid .myFrame.myIncLbl -row $aRowIter -column 0 -columnspan 10 -sticky w
|
grid .myFrame.myIncLbl -row $aRowIter -column 0 -columnspan 10 -sticky w
|
||||||
incr aRowIter
|
incr aRowIter
|
||||||
|
@@ -68,7 +68,7 @@ if { [info exists ::env(SHORTCUT_HEADERS)] } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name
|
# fetch environment variables (e.g. set by custom.sh or custom.bat) and set them as tcl variables with the same name
|
||||||
set THE_ENV_VARIABLES {HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_OPENCL CHECK_QT4 CHECK_JDK MACOSX_USE_GLX HAVE_RelWithDebInfo}
|
set THE_ENV_VARIABLES {HAVE_FREEIMAGE HAVE_FFMPEG HAVE_TBB HAVE_GLES2 HAVE_D3D HAVE_VTK HAVE_ZLIB HAVE_LIBLZMA HAVE_RAPIDJSON HAVE_OPENCL CHECK_QT4 CHECK_JDK MACOSX_USE_GLX HAVE_RelWithDebInfo}
|
||||||
foreach anEnvIter $THE_ENV_VARIABLES {
|
foreach anEnvIter $THE_ENV_VARIABLES {
|
||||||
set ${anEnvIter} "false"
|
set ${anEnvIter} "false"
|
||||||
if { [info exists ::env(${anEnvIter})] } {
|
if { [info exists ::env(${anEnvIter})] } {
|
||||||
@@ -858,6 +858,25 @@ proc wokdep:SearchGLES {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin6
|
|||||||
return "$isFound"
|
return "$isFound"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Search RapidJSON headers
|
||||||
|
proc wokdep:SearchRapidJson {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64} {
|
||||||
|
upvar $theErrInc anErrInc
|
||||||
|
|
||||||
|
set isFound "true"
|
||||||
|
set aRJHPath [wokdep:SearchHeader "rapidjson/rapidjson.h"]
|
||||||
|
if { "$aRJHPath" == "" } {
|
||||||
|
set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{rapidjson}*] "$::VCVER" "$::ARCH" ]
|
||||||
|
if { "$aPath" != "" && [file exists "$aPath/include/rapidjson/rapidjson.h"] } {
|
||||||
|
lappend ::CSF_OPT_INC "$aPath/include"
|
||||||
|
} else {
|
||||||
|
lappend anErrInc "Error: 'rapidjson/rapidjson.h' not found (RapidJSON)"
|
||||||
|
set isFound "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "$isFound"
|
||||||
|
}
|
||||||
|
|
||||||
# Auxiliary function, gets VTK version to set default search directory
|
# Auxiliary function, gets VTK version to set default search directory
|
||||||
proc wokdep:VtkVersion { thePath } {
|
proc wokdep:VtkVersion { thePath } {
|
||||||
set aResult "6.1"
|
set aResult "6.1"
|
||||||
|
@@ -1393,6 +1393,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
|
|||||||
set aLibsMap(CSF_TclTkLibs) ""
|
set aLibsMap(CSF_TclTkLibs) ""
|
||||||
set aLibsMap(CSF_QT) "QtCore QtGui"
|
set aLibsMap(CSF_QT) "QtCore QtGui"
|
||||||
} else {
|
} else {
|
||||||
|
set aLibsMap(CSF_fontconfig) "fontconfig"
|
||||||
if { "$theOS" == "qnx" } {
|
if { "$theOS" == "qnx" } {
|
||||||
# CSF_ThreadLibs - pthread API is part of libc on QNX
|
# CSF_ThreadLibs - pthread API is part of libc on QNX
|
||||||
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
||||||
|
@@ -63,6 +63,7 @@ win32 {
|
|||||||
CSF_TclTkLibs = -lX11 -ltk8.6
|
CSF_TclTkLibs = -lX11 -ltk8.6
|
||||||
CSF_XwLibs = -lX11 -lXext -lXmu -lXi
|
CSF_XwLibs = -lX11 -lXext -lXmu -lXi
|
||||||
CSF_MotifLibs = -lX11
|
CSF_MotifLibs = -lX11
|
||||||
|
CSF_fontconfig = -lfontconfig
|
||||||
HAVE_GLES2 { CSF_OpenGlLibs = -lEGL -lGLESv2 }
|
HAVE_GLES2 { CSF_OpenGlLibs = -lEGL -lGLESv2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ set "HAVE_GLES2=false"
|
|||||||
set "HAVE_D3D=false"
|
set "HAVE_D3D=false"
|
||||||
set "HAVE_ZLIB=false"
|
set "HAVE_ZLIB=false"
|
||||||
set "HAVE_LIBLZMA=false"
|
set "HAVE_LIBLZMA=false"
|
||||||
|
set "HAVE_RAPIDJSON=false"
|
||||||
set "CSF_OPT_INC="
|
set "CSF_OPT_INC="
|
||||||
set "CSF_OPT_LIB32="
|
set "CSF_OPT_LIB32="
|
||||||
set "CSF_OPT_LIB64="
|
set "CSF_OPT_LIB64="
|
||||||
@@ -163,6 +164,7 @@ if ["%HAVE_GLES2%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DH
|
|||||||
if ["%HAVE_D3D%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_D3D" & set "CSF_DEFINES=HAVE_D3D;%CSF_DEFINES%"
|
if ["%HAVE_D3D%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_D3D" & set "CSF_DEFINES=HAVE_D3D;%CSF_DEFINES%"
|
||||||
if ["%HAVE_ZLIB%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_ZLIB" & set "CSF_DEFINES=HAVE_ZLIB;%CSF_DEFINES%"
|
if ["%HAVE_ZLIB%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_ZLIB" & set "CSF_DEFINES=HAVE_ZLIB;%CSF_DEFINES%"
|
||||||
if ["%HAVE_LIBLZMA%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_LIBLZMA" & set "CSF_DEFINES=HAVE_LIBLZMA;%CSF_DEFINES%"
|
if ["%HAVE_LIBLZMA%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_LIBLZMA" & set "CSF_DEFINES=HAVE_LIBLZMA;%CSF_DEFINES%"
|
||||||
|
if ["%HAVE_RAPIDJSON%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_RAPIDJSON" & set "CSF_DEFINES=HAVE_RAPIDJSON;%CSF_DEFINES%"
|
||||||
|
|
||||||
rem Eliminate VS warning
|
rem Eliminate VS warning
|
||||||
if ["%CSF_DEFINES%"] == [""] set "CSF_DEFINES=;"
|
if ["%CSF_DEFINES%"] == [""] set "CSF_DEFINES=;"
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -222,6 +222,7 @@ for which OCCT is certified to work.
|
|||||||
| Freetype (for text rendering) | FreeType 2.4.11-2.7.1 https://sourceforge.net/projects/freetype/files/ |
|
| Freetype (for text rendering) | FreeType 2.4.11-2.7.1 https://sourceforge.net/projects/freetype/files/ |
|
||||||
| FreeImage (optional, for support of common 2D graphic formats) | FreeImage 3.17.0+ https://sourceforge.net/projects/freeimage/files |
|
| FreeImage (optional, for support of common 2D graphic formats) | FreeImage 3.17.0+ https://sourceforge.net/projects/freeimage/files |
|
||||||
| FFmpeg (optional, for video recording) | FFmpeg 3.1+ https://www.ffmpeg.org/download.html |
|
| FFmpeg (optional, for video recording) | FFmpeg 3.1+ https://www.ffmpeg.org/download.html |
|
||||||
|
| RapidJSON (optional, for reading glTF) | RapidJSON 1.1+ http://rapidjson.org/ |
|
||||||
| Intel TBB (optional, for multithreaded algorithms) | TBB 4.x or 5.x https://www.threadingbuildingblocks.org/ |
|
| Intel TBB (optional, for multithreaded algorithms) | TBB 4.x or 5.x https://www.threadingbuildingblocks.org/ |
|
||||||
| VTK (for VTK Integration Services | VTK 6.1+ http://www.vtk.org/download/ |
|
| VTK (for VTK Integration Services | VTK 6.1+ http://www.vtk.org/download/ |
|
||||||
| Doxygen (optional for building documentation) | Doxygen 1.8.5+ https://www.stack.nl/~dimitri/doxygen/download.html |
|
| Doxygen (optional for building documentation) | Doxygen 1.8.5+ https://www.stack.nl/~dimitri/doxygen/download.html |
|
||||||
|
@@ -5595,7 +5595,7 @@ Draw provides command to create curves and surfaces by approximation.
|
|||||||
* **appro** fits a curve through 3d points;
|
* **appro** fits a curve through 3d points;
|
||||||
* **surfapp** and **grilapp** fit a surface through 3d points by approximation;
|
* **surfapp** and **grilapp** fit a surface through 3d points by approximation;
|
||||||
* **surfint** fit a surface through 3d points by interpolation;
|
* **surfint** fit a surface through 3d points by interpolation;
|
||||||
* **2dinterpolate** interpolates a curve.
|
* **2dinterpole** interpolates a curve.
|
||||||
|
|
||||||
@subsubsection occt_draw_6_8_1 appro, dapprox
|
@subsubsection occt_draw_6_8_1 appro, dapprox
|
||||||
|
|
||||||
|
BIN
dox/user_guides/modeling_data/images/modeling_data_obb_125K.png
Normal file
BIN
dox/user_guides/modeling_data/images/modeling_data_obb_125K.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@@ -1341,7 +1341,26 @@ Further, let us consider the triangle \f$ T_{0}\left \langle p_{0}, p_{1}, p_{2}
|
|||||||
<span>10.</span> Compute the center of OBB and its half dimensions.<br>
|
<span>10.</span> Compute the center of OBB and its half dimensions.<br>
|
||||||
<span>11.</span> Create OBB using the center, axes and half dimensions.<br>
|
<span>11.</span> Create OBB using the center, axes and half dimensions.<br>
|
||||||
|
|
||||||
This algorithm is implemented in the *Bnd_OBB::ReBuild(...)* method.
|
@subsubsection occt_modat_6_1_1_opt Creation of Optimal OBB from set of points
|
||||||
|
|
||||||
|
For creation of the optimal OBB from set of points the same algorithm as described above is used but with some simplifications in logic and increased computation time.
|
||||||
|
For the optimal OBB it is necessary to check all possible axes which can be created by the extremal points. And since the extremal points are only valid for the initial axes it is necessary to project the whole set of points on each axis.
|
||||||
|
This approach usually provides much tighter OBB but the performance is lower. The complexity of the algorithm is still linear and with use of BVH for the set of points it is O(N + C*log(N)).
|
||||||
|
|
||||||
|
Here is the example of optimal and not optimal OBB for the model using the set of 125K nodes:
|
||||||
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<td>@figure{/user_guides/modeling_data/images/modeling_data_obb_125K.png,"Not optimal OBB by DiTo-14",160}</td>
|
||||||
|
<td>@figure{/user_guides/modeling_data/images/modeling_data_opt_obb_125K.png,"Optimal OBB by DiTo-14",160}</td>
|
||||||
|
<td>@figure{/user_guides/modeling_data/images/modeling_data_pca_obb_125K.png,"Not optimal OBB by PCA",160}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
Computation of the not optimal OBB in this case took 0.007 sec, optimal - 0.1 sec, which is about 14 times slower. Such performance is comparable to creation of the OBB for this shape by PCA approach (see below) which takes about 0.17 sec.
|
||||||
|
|
||||||
|
The computation of optimal OBB is controlled by the same *theIsOptimal* flag in the BRepBndLib::AddOBB method as for PCA algorithm.
|
||||||
|
|
||||||
|
These algorithms are implemented in the *Bnd_OBB::ReBuild(...)* method.
|
||||||
|
|
||||||
@subsubsection occt_modat_6_1_2 Creation of OBB based on Axes of inertia
|
@subsubsection occt_modat_6_1_2 Creation of OBB based on Axes of inertia
|
||||||
|
|
||||||
|
@@ -783,6 +783,7 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
|||||||
BRepAdaptor_Surface surf1( aFace );
|
BRepAdaptor_Surface surf1( aFace );
|
||||||
Handle( Adaptor3d_HSurface ) surf2;
|
Handle( Adaptor3d_HSurface ) surf2;
|
||||||
Standard_Boolean isOffset = Standard_False;
|
Standard_Boolean isOffset = Standard_False;
|
||||||
|
Offset = 0.0;
|
||||||
|
|
||||||
if (surf1.GetType() == GeomAbs_OffsetSurface)
|
if (surf1.GetType() == GeomAbs_OffsetSurface)
|
||||||
{
|
{
|
||||||
@@ -801,7 +802,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
|||||||
{
|
{
|
||||||
aPlane = surf2->Plane();
|
aPlane = surf2->Plane();
|
||||||
aSurfType = AIS_KOS_Plane;
|
aSurfType = AIS_KOS_Plane;
|
||||||
Offset = 0.;
|
|
||||||
Result = Standard_True;
|
Result = Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +817,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
|||||||
gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
|
gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
|
||||||
aPlane = thePlane;
|
aPlane = thePlane;
|
||||||
aSurfType = AIS_KOS_Plane;
|
aSurfType = AIS_KOS_Plane;
|
||||||
Offset = 0.;
|
|
||||||
Result = Standard_True;
|
Result = Standard_True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -826,7 +825,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
|||||||
{
|
{
|
||||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||||
aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
|
aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
|
||||||
Offset = 0.0e0;
|
|
||||||
}
|
}
|
||||||
if (Result == Standard_False)
|
if (Result == Standard_False)
|
||||||
{
|
{
|
||||||
@@ -839,7 +837,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
|||||||
TheType == STANDARD_TYPE(Geom_ToroidalSurface))
|
TheType == STANDARD_TYPE(Geom_ToroidalSurface))
|
||||||
{
|
{
|
||||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||||
Offset = 0.0e0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -899,20 +896,18 @@ gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
|
|||||||
//function : InitFaceLength
|
//function : InitFaceLength
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void AIS::InitFaceLength (const TopoDS_Face& aFace,
|
void AIS::InitFaceLength (const TopoDS_Face& theFace,
|
||||||
gp_Pln & aPlane,
|
gp_Pln& thePlane,
|
||||||
Handle(Geom_Surface) & aSurface,
|
Handle(Geom_Surface)& theSurface,
|
||||||
AIS_KindOfSurface & aSurfaceType,
|
AIS_KindOfSurface& theSurfaceType,
|
||||||
Standard_Real & anOffset)
|
Standard_Real& theOffset)
|
||||||
{
|
{
|
||||||
AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
|
if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
|
||||||
|
&& Abs (theOffset) > Precision::Confusion())
|
||||||
if (Abs( anOffset ) > Precision::Confusion())
|
|
||||||
{
|
{
|
||||||
aSurface = new Geom_OffsetSurface( aSurface, anOffset );
|
theSurface = new Geom_OffsetSurface (theSurface, theOffset);
|
||||||
anOffset = 0.0e0;
|
theOffset = 0.0e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -633,9 +633,6 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
|
|||||||
{
|
{
|
||||||
aShadedGroup = thePrs->NewGroup();
|
aShadedGroup = thePrs->NewGroup();
|
||||||
aShadedGroup->SetClosed (isClosed);
|
aShadedGroup->SetClosed (isClosed);
|
||||||
if (isClosed
|
|
||||||
&& !myCappingStyle.IsNull())
|
|
||||||
aShadedGroup->SetGroupPrimitivesAspect (myCappingStyle);
|
|
||||||
}
|
}
|
||||||
aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
|
aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
|
||||||
aShadedGroup->AddPrimitiveArray (aTriangles);
|
aShadedGroup->AddPrimitiveArray (aTriangles);
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <AIS_InteractiveContext.hxx>
|
#include <AIS_InteractiveContext.hxx>
|
||||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||||
#include <Graphic3d_AspectFillCapping.hxx>
|
|
||||||
#include <Graphic3d_AspectLine3d.hxx>
|
#include <Graphic3d_AspectLine3d.hxx>
|
||||||
#include <Graphic3d_AspectMarker3d.hxx>
|
#include <Graphic3d_AspectMarker3d.hxx>
|
||||||
#include <Graphic3d_AspectText3d.hxx>
|
#include <Graphic3d_AspectText3d.hxx>
|
||||||
@@ -84,37 +83,6 @@ void AIS_InteractiveObject::SetContext (const Handle(AIS_InteractiveContext)& th
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : SetCappingStyle
|
|
||||||
//purpose :
|
|
||||||
//=======================================================================
|
|
||||||
void AIS_InteractiveObject::SetCappingStyle (const Handle(Graphic3d_AspectFillCapping)& theStyle)
|
|
||||||
{
|
|
||||||
myCappingStyle = theStyle;
|
|
||||||
|
|
||||||
// Modify existing presentations
|
|
||||||
for (Standard_Integer aPrsIter = 1, n = myPresentations.Length(); aPrsIter <= n; ++aPrsIter)
|
|
||||||
{
|
|
||||||
const Handle(PrsMgr_Presentation)& aPrs3d = myPresentations (aPrsIter);
|
|
||||||
if (!aPrs3d.IsNull())
|
|
||||||
{
|
|
||||||
const Handle(Graphic3d_Structure)& aStruct = aPrs3d->Presentation();
|
|
||||||
if (!aStruct.IsNull())
|
|
||||||
{
|
|
||||||
const Graphic3d_SequenceOfGroup& aGroups = aStruct->Groups();
|
|
||||||
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_Group)& aGrp = aGroupIter.ChangeValue();
|
|
||||||
if (aGrp.IsNull())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
aGrp->SetGroupPrimitivesAspect (theStyle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : HasPresentation
|
//function : HasPresentation
|
||||||
//purpose :
|
//purpose :
|
||||||
|
@@ -104,12 +104,6 @@ public:
|
|||||||
void ClearOwner() { myOwner.Nullify(); }
|
void ClearOwner() { myOwner.Nullify(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Set style of filling capping section created by clipping planes.
|
|
||||||
Standard_EXPORT virtual void SetCappingStyle (const Handle(Graphic3d_AspectFillCapping)& theStyle);
|
|
||||||
|
|
||||||
//! Returns style for filling capping section created by clipping planes.
|
|
||||||
const Handle(Graphic3d_AspectFillCapping)& CappingStyle() const { return myCappingStyle; }
|
|
||||||
|
|
||||||
|
|
||||||
//! Returns the context pointer to the interactive context.
|
//! Returns the context pointer to the interactive context.
|
||||||
Standard_EXPORT Handle(AIS_InteractiveContext) GetContext() const;
|
Standard_EXPORT Handle(AIS_InteractiveContext) GetContext() const;
|
||||||
@@ -134,7 +128,6 @@ protected:
|
|||||||
|
|
||||||
AIS_InteractiveContext* myCTXPtr; //!< pointer to Interactive Context, where object is currently displayed; @sa SetContext()
|
AIS_InteractiveContext* myCTXPtr; //!< pointer to Interactive Context, where object is currently displayed; @sa SetContext()
|
||||||
Handle(Standard_Transient) myOwner; //!< application-specific owner object
|
Handle(Standard_Transient) myOwner; //!< application-specific owner object
|
||||||
Handle(Graphic3d_AspectFillCapping) myCappingStyle;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1035,15 +1035,21 @@ void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationMan
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aPresentation->CStructure()->ViewAffinity = thePM->StructureManager()->ObjectAffinity (Handle(Standard_Transient) (this));
|
||||||
|
|
||||||
if (anOwner->Mode() == AIS_MM_TranslationPlane)
|
if (anOwner->Mode() == AIS_MM_TranslationPlane)
|
||||||
{
|
{
|
||||||
Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
|
Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
|
||||||
aStyle->SetColor(myAxes[anOwner->Index()].Color());
|
aStyle->SetColor (myAxes[anOwner->Index()].Color());
|
||||||
aStyle->SetTransparency(0.5);
|
aStyle->SetTransparency (0.5);
|
||||||
aPresentation->Highlight(aStyle);
|
aPresentation->Highlight (aStyle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aPresentation->Highlight(theStyle);
|
{
|
||||||
|
aPresentation->Highlight (theStyle);
|
||||||
|
}
|
||||||
|
|
||||||
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
|
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
|
||||||
aGroupIter.More(); aGroupIter.Next())
|
aGroupIter.More(); aGroupIter.Next())
|
||||||
{
|
{
|
||||||
|
@@ -180,7 +180,10 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
OCC_CATCH_SIGNALS
|
OCC_CATCH_SIGNALS
|
||||||
StdPrs_ShadedShape::Add (aPrs, myshape, myDrawer, myCappingStyle);
|
StdPrs_ShadedShape::Add (aPrs, myshape, myDrawer,
|
||||||
|
myDrawer->ShadingAspect()->Aspect()->ToMapTexture()
|
||||||
|
&& !myDrawer->ShadingAspect()->Aspect()->TextureMap().IsNull(),
|
||||||
|
myUVOrigin, myUVRepeat, myUVScale);
|
||||||
}
|
}
|
||||||
catch (Standard_Failure const& anException)
|
catch (Standard_Failure const& anException)
|
||||||
{
|
{
|
||||||
|
@@ -93,9 +93,8 @@ public:
|
|||||||
//! be ignored at all.
|
//! be ignored at all.
|
||||||
//! If theIsShapeToleranceUsed == TRUE then resulting box will be
|
//! If theIsShapeToleranceUsed == TRUE then resulting box will be
|
||||||
//! extended on the tolerance of the shape.
|
//! extended on the tolerance of the shape.
|
||||||
//! theIsOptimal flag defines the algorithm for construction of initial
|
//! theIsOptimal flag defines whether to look for the more tight
|
||||||
//! Bnd_Box for the second method (if theIsOptimal == TRUE then
|
//! OBB for the cost of performance or not.
|
||||||
//! this box will be created by AddOptimal(...) method).
|
|
||||||
Standard_EXPORT static
|
Standard_EXPORT static
|
||||||
void AddOBB(const TopoDS_Shape& theS,
|
void AddOBB(const TopoDS_Shape& theS,
|
||||||
Bnd_OBB& theOBB,
|
Bnd_OBB& theOBB,
|
||||||
|
@@ -293,6 +293,7 @@ static Standard_Integer IsWCS(const gp_Dir& theDir)
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
static Standard_Boolean CheckPoints(const TopoDS_Shape& theS,
|
static Standard_Boolean CheckPoints(const TopoDS_Shape& theS,
|
||||||
const Standard_Boolean theIsTriangulationUsed,
|
const Standard_Boolean theIsTriangulationUsed,
|
||||||
|
const Standard_Boolean theIsOptimal,
|
||||||
const Standard_Boolean theIsShapeToleranceUsed,
|
const Standard_Boolean theIsShapeToleranceUsed,
|
||||||
Bnd_OBB& theOBB)
|
Bnd_OBB& theOBB)
|
||||||
{
|
{
|
||||||
@@ -329,7 +330,7 @@ static Standard_Boolean CheckPoints(const TopoDS_Shape& theS,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
theOBB.ReBuild(anArrPnts, aPtrArrTol);
|
theOBB.ReBuild(anArrPnts, aPtrArrTol, theIsOptimal);
|
||||||
|
|
||||||
return (!theOBB.IsVoid());
|
return (!theOBB.IsVoid());
|
||||||
}
|
}
|
||||||
@@ -498,7 +499,7 @@ void BRepBndLib::AddOBB(const TopoDS_Shape& theS,
|
|||||||
const Standard_Boolean theIsOptimal,
|
const Standard_Boolean theIsOptimal,
|
||||||
const Standard_Boolean theIsShapeToleranceUsed)
|
const Standard_Boolean theIsShapeToleranceUsed)
|
||||||
{
|
{
|
||||||
if(CheckPoints(theS, theIsTriangulationUsed, theIsShapeToleranceUsed, theOBB))
|
if (CheckPoints(theS, theIsTriangulationUsed, theIsOptimal, theIsShapeToleranceUsed, theOBB))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ComputePCA(theS, theOBB, theIsTriangulationUsed, theIsOptimal, theIsShapeToleranceUsed);
|
ComputePCA(theS, theOBB, theIsTriangulationUsed, theIsOptimal, theIsShapeToleranceUsed);
|
||||||
|
@@ -1437,16 +1437,13 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
|||||||
gp_Pnt2d ap = aCurve->Value(f);
|
gp_Pnt2d ap = aCurve->Value(f);
|
||||||
Standard_Boolean bFirstFound = Standard_False;
|
Standard_Boolean bFirstFound = Standard_False;
|
||||||
Standard_Boolean bLastFound = Standard_False;
|
Standard_Boolean bLastFound = Standard_False;
|
||||||
Standard_Boolean bforward = Standard_True;
|
|
||||||
|
|
||||||
if(ap.Distance(theFirstPoint) < aTolerance1) {
|
if(ap.Distance(theFirstPoint) < aTolerance1) {
|
||||||
bforward = Standard_True;
|
|
||||||
if(theOrientedList.IsEmpty())
|
if(theOrientedList.IsEmpty())
|
||||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
||||||
bFirstFound = Standard_True;
|
bFirstFound = Standard_True;
|
||||||
}
|
}
|
||||||
else if(ap.Distance(theLastPoint) < aTolerance1) {
|
else if(ap.Distance(theLastPoint) < aTolerance1) {
|
||||||
bforward = Standard_False;
|
|
||||||
if(theOrientedList.IsEmpty())
|
if(theOrientedList.IsEmpty())
|
||||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
||||||
bLastFound = Standard_True;
|
bLastFound = Standard_True;
|
||||||
@@ -1454,36 +1451,31 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
|||||||
ap = aCurve->Value(l);
|
ap = aCurve->Value(l);
|
||||||
|
|
||||||
if(ap.Distance(theLastPoint) < aTolerance2) {
|
if(ap.Distance(theLastPoint) < aTolerance2) {
|
||||||
bforward = Standard_True;
|
|
||||||
|
|
||||||
if(theOrientedList.IsEmpty())
|
if(theOrientedList.IsEmpty())
|
||||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
||||||
bLastFound = Standard_True;
|
bLastFound = Standard_True;
|
||||||
}
|
}
|
||||||
else if(ap.Distance(theFirstPoint) < aTolerance2) {
|
else if(ap.Distance(theFirstPoint) < aTolerance2) {
|
||||||
bforward = Standard_False;
|
|
||||||
|
|
||||||
if(theOrientedList.IsEmpty())
|
if(theOrientedList.IsEmpty())
|
||||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
||||||
bFirstFound = Standard_True;
|
bFirstFound = Standard_True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!theOrientedList.IsEmpty())
|
||||||
|
aEPrev = TopoDS::Edge (theOrientedList.Last());
|
||||||
|
|
||||||
for(; anIt.More(); anIt.Next()) {
|
for(; anIt.More(); anIt.Next()) {
|
||||||
const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
|
const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
|
||||||
TopoDS_Vertex aV11, aV12;
|
TopoDS_Vertex aV11, aV12;
|
||||||
TopExp::Vertices(aEPrev, aV11, aV12);
|
TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
|
||||||
TopoDS_Vertex aV21, aV22;
|
TopoDS_Vertex aV21, aV22;
|
||||||
TopExp::Vertices(aE, aV21, aV22);
|
TopExp::Vertices(aE, aV21, aV22, Standard_False);
|
||||||
TopAbs_Orientation anOri = TopAbs_FORWARD;
|
|
||||||
|
|
||||||
if(aV12.IsSame(aV21) || aV11.IsSame(aV22)) {
|
TopAbs_Orientation anOri =
|
||||||
anOri = (bforward) ? TopAbs_FORWARD : TopAbs_REVERSED;
|
(aV12.IsSame (aV21) || aV11.IsSame (aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
|
||||||
}
|
|
||||||
else {
|
|
||||||
anOri = (bforward) ? TopAbs_REVERSED : TopAbs_FORWARD;
|
|
||||||
}
|
|
||||||
theOrientedList.Append(aE.Oriented(anOri));
|
theOrientedList.Append(aE.Oriented(anOri));
|
||||||
aEPrev = aE;
|
aEPrev = TopoDS::Edge (theOrientedList.Last());
|
||||||
|
|
||||||
aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
|
aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
|
||||||
aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
|
aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
|
||||||
utol = aBAS.UResolution(aTolerance1);
|
utol = aBAS.UResolution(aTolerance1);
|
||||||
@@ -1511,9 +1503,7 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!bFirstFound || !bLastFound)
|
return bFirstFound && bLastFound;
|
||||||
return Standard_False;
|
|
||||||
return Standard_True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
@@ -55,6 +55,8 @@ static Standard_Boolean findNearestValidPoint(
|
|||||||
//
|
//
|
||||||
// the general step is computed using general curve resolution
|
// the general step is computed using general curve resolution
|
||||||
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
||||||
|
if (aStep < theEps)
|
||||||
|
aStep = theEps;
|
||||||
// aD1Mag is a threshold to consider local derivative magnitude too small
|
// aD1Mag is a threshold to consider local derivative magnitude too small
|
||||||
// and to accelerate going out of sphere
|
// and to accelerate going out of sphere
|
||||||
// (inverse of resolution is the maximal derivative);
|
// (inverse of resolution is the maximal derivative);
|
||||||
@@ -159,11 +161,19 @@ Standard_Boolean BRepLib::FindValidRange
|
|||||||
if (theParV2 - theParV1 < Precision::PConfusion())
|
if (theParV2 - theParV1 < Precision::PConfusion())
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
|
|
||||||
Standard_Real anEps = Max(Max(theCurve.Resolution(theTolE) * 0.1,
|
Standard_Boolean isInfParV1 = Precision::IsInfinite (theParV1),
|
||||||
Epsilon(Max(Abs(theParV1), Abs(theParV2)))),
|
isInfParV2 = Precision::IsInfinite (theParV2);
|
||||||
|
|
||||||
|
Standard_Real aMaxPar = 0.0;
|
||||||
|
if (!isInfParV1)
|
||||||
|
aMaxPar = Abs (theParV1);
|
||||||
|
if (!isInfParV2)
|
||||||
|
aMaxPar = Max (aMaxPar, Abs (theParV2));
|
||||||
|
|
||||||
|
Standard_Real anEps = Max (Max (theCurve.Resolution (theTolE) * 0.1, Epsilon (aMaxPar)),
|
||||||
Precision::PConfusion());
|
Precision::PConfusion());
|
||||||
|
|
||||||
if (Precision::IsInfinite(theParV1))
|
if (isInfParV1)
|
||||||
theFirst = theParV1;
|
theFirst = theParV1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -174,7 +184,7 @@ Standard_Boolean BRepLib::FindValidRange
|
|||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Precision::IsInfinite(theParV2))
|
if (isInfParV2)
|
||||||
theLast = theParV2;
|
theLast = theParV2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -65,7 +65,7 @@ void BRepMesh_BaseMeshAlgo::Perform(
|
|||||||
commitSurfaceTriangulation();
|
commitSurfaceTriangulation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Standard_Failure& /*theExeption*/)
|
catch (Standard_Failure const& /*theExeption*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -83,6 +83,12 @@ public:
|
|||||||
myFaceMax = theMax;
|
myFaceMax = theMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Retruns true if cell filter contains no circle.
|
||||||
|
inline Standard_Boolean IsEmpty () const
|
||||||
|
{
|
||||||
|
return mySelector.Circles ().IsEmpty ();
|
||||||
|
}
|
||||||
|
|
||||||
//! Binds the circle to the tool.
|
//! Binds the circle to the tool.
|
||||||
//! @param theIndex index a circle should be bound with.
|
//! @param theIndex index a circle should be bound with.
|
||||||
//! @param theCircle circle to be bound.
|
//! @param theCircle circle to be bound.
|
||||||
|
60
src/BRepMesh/BRepMesh_ConstrainedBaseMeshAlgo.hxx
Normal file
60
src/BRepMesh/BRepMesh_ConstrainedBaseMeshAlgo.hxx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// Created on: 2019-07-08
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _BRepMesh_ConstrainedBaseMeshAlgo_HeaderFile
|
||||||
|
#define _BRepMesh_ConstrainedBaseMeshAlgo_HeaderFile
|
||||||
|
|
||||||
|
#include <BRepMesh_BaseMeshAlgo.hxx>
|
||||||
|
#include <NCollection_Shared.hxx>
|
||||||
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
|
||||||
|
class BRepMesh_DataStructureOfDelaun;
|
||||||
|
class BRepMesh_Delaun;
|
||||||
|
|
||||||
|
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
|
||||||
|
//! Performs generation of mesh using raw data from model.
|
||||||
|
class BRepMesh_ConstrainedBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
BRepMesh_ConstrainedBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
virtual ~BRepMesh_ConstrainedBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ConstrainedBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Returns size of cell to be used by acceleration circles grid structure.
|
||||||
|
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer /*theVerticesNb*/)
|
||||||
|
{
|
||||||
|
return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Perfroms processing of generated mesh.
|
||||||
|
//! By default does nothing.
|
||||||
|
//! Expected to be called from method generateMesh() in successor classes.
|
||||||
|
virtual void postProcessMesh (BRepMesh_Delaun& /*theMesher*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -20,7 +20,9 @@
|
|||||||
#include <BRepMesh_FaceDiscret.hxx>
|
#include <BRepMesh_FaceDiscret.hxx>
|
||||||
#include <BRepMesh_ModelPreProcessor.hxx>
|
#include <BRepMesh_ModelPreProcessor.hxx>
|
||||||
#include <BRepMesh_ModelPostProcessor.hxx>
|
#include <BRepMesh_ModelPostProcessor.hxx>
|
||||||
|
|
||||||
#include <BRepMesh_MeshAlgoFactory.hxx>
|
#include <BRepMesh_MeshAlgoFactory.hxx>
|
||||||
|
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// Function: Constructor
|
// Function: Constructor
|
||||||
@@ -28,11 +30,33 @@
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
BRepMesh_Context::BRepMesh_Context ()
|
BRepMesh_Context::BRepMesh_Context ()
|
||||||
{
|
{
|
||||||
|
enum MeshAlgo
|
||||||
|
{
|
||||||
|
MeshAlgo_Default = 0x0,
|
||||||
|
MeshAlgo_Delabella = 0x1
|
||||||
|
};
|
||||||
|
|
||||||
|
char* anAlgoVar;
|
||||||
|
anAlgoVar = getenv ("CSF_MeshAlgo");
|
||||||
|
const Standard_Integer anAlgoId = (anAlgoVar ? atoi (anAlgoVar) : MeshAlgo_Default);
|
||||||
|
|
||||||
|
Handle (IMeshTools_MeshAlgoFactory) aAlgoFactory;
|
||||||
|
switch (anAlgoId)
|
||||||
|
{
|
||||||
|
case MeshAlgo_Delabella:
|
||||||
|
aAlgoFactory = new BRepMesh_DelabellaMeshAlgoFactory;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
aAlgoFactory = new BRepMesh_MeshAlgoFactory;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SetModelBuilder (new BRepMesh_ModelBuilder);
|
SetModelBuilder (new BRepMesh_ModelBuilder);
|
||||||
SetEdgeDiscret (new BRepMesh_EdgeDiscret);
|
SetEdgeDiscret (new BRepMesh_EdgeDiscret);
|
||||||
SetModelHealer (new BRepMesh_ModelHealer);
|
SetModelHealer (new BRepMesh_ModelHealer);
|
||||||
SetPreProcessor (new BRepMesh_ModelPreProcessor);
|
SetPreProcessor (new BRepMesh_ModelPreProcessor);
|
||||||
SetFaceDiscret (new BRepMesh_FaceDiscret(new BRepMesh_MeshAlgoFactory));
|
SetFaceDiscret (new BRepMesh_FaceDiscret (aAlgoFactory));
|
||||||
SetPostProcessor(new BRepMesh_ModelPostProcessor);
|
SetPostProcessor(new BRepMesh_ModelPostProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include <Adaptor3d_HCurveOnSurface.hxx>
|
#include <Adaptor3d_HCurveOnSurface.hxx>
|
||||||
#include <Adaptor2d_HCurve2d.hxx>
|
#include <Adaptor2d_HCurve2d.hxx>
|
||||||
#include <Standard_Failure.hxx>
|
#include <Standard_Failure.hxx>
|
||||||
|
#include <GCPnts_AbscissaPoint.hxx>
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Constructor
|
//function : Constructor
|
||||||
@@ -79,21 +80,28 @@ void BRepMesh_CurveTessellator::init()
|
|||||||
aPreciseLinDef *= 0.5;
|
aPreciseLinDef *= 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
aPreciseLinDef = Max(aPreciseLinDef, Precision::Confusion());
|
aPreciseLinDef = Max (aPreciseLinDef, Precision::Confusion());
|
||||||
aPreciseAngDef = Max(aPreciseAngDef, Precision::Angular());
|
aPreciseAngDef = Max (aPreciseAngDef, Precision::Angular());
|
||||||
|
|
||||||
|
Standard_Real aMinSize = myParameters.MinSize;
|
||||||
|
if (myParameters.AdjustMinSize)
|
||||||
|
{
|
||||||
|
aMinSize = Min (aMinSize, myParameters.RelMinSize() * GCPnts_AbscissaPoint::Length (
|
||||||
|
myCurve, myCurve.FirstParameter(), myCurve.LastParameter(), aPreciseLinDef));
|
||||||
|
}
|
||||||
|
|
||||||
mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
|
mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
|
||||||
mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize);
|
mySquareMinSize = Max (mySquareEdgeDef, aMinSize * aMinSize);
|
||||||
|
|
||||||
myEdgeSqTol = BRep_Tool::Tolerance(myEdge);
|
myEdgeSqTol = BRep_Tool::Tolerance (myEdge);
|
||||||
myEdgeSqTol *= myEdgeSqTol;
|
myEdgeSqTol *= myEdgeSqTol;
|
||||||
|
|
||||||
const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
|
const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
|
||||||
|
|
||||||
myDiscretTool.Initialize(myCurve,
|
myDiscretTool.Initialize (myCurve,
|
||||||
myCurve.FirstParameter(), myCurve.LastParameter(),
|
myCurve.FirstParameter(), myCurve.LastParameter(),
|
||||||
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
|
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
|
||||||
Precision::PConfusion(), myParameters.MinSize);
|
Precision::PConfusion(), aMinSize);
|
||||||
|
|
||||||
if (myCurve.IsCurveOnSurface())
|
if (myCurve.IsCurveOnSurface())
|
||||||
{
|
{
|
||||||
|
93
src/BRepMesh/BRepMesh_CustomBaseMeshAlgo.hxx
Normal file
93
src/BRepMesh/BRepMesh_CustomBaseMeshAlgo.hxx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Created on: 2019-06-07
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _BRepMesh_CustomBaseMeshAlgo_HeaderFile
|
||||||
|
#define _BRepMesh_CustomBaseMeshAlgo_HeaderFile
|
||||||
|
|
||||||
|
#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
|
||||||
|
#include <NCollection_Shared.hxx>
|
||||||
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
|
||||||
|
#include <BRepMesh_Delaun.hxx>
|
||||||
|
#include <BRepMesh_MeshTool.hxx>
|
||||||
|
|
||||||
|
class BRepMesh_DataStructureOfDelaun;
|
||||||
|
|
||||||
|
//! Class provides base fuctionality to build face triangulation using custom triangulation algorithm.
|
||||||
|
//! Performs generation of mesh using raw data from model.
|
||||||
|
class BRepMesh_CustomBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
Standard_EXPORT BRepMesh_CustomBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
Standard_EXPORT virtual ~BRepMesh_CustomBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_CustomBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Generates mesh for the contour stored in data structure.
|
||||||
|
Standard_EXPORT virtual void generateMesh () Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
const Handle (BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure ();
|
||||||
|
const Standard_Integer aNodesNb = aStructure->NbNodes ();
|
||||||
|
|
||||||
|
buildBaseTriangulation ();
|
||||||
|
|
||||||
|
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes ());
|
||||||
|
BRepMesh_Delaun aMesher (aStructure, aCellsCount.first, aCellsCount.second, Standard_False);
|
||||||
|
|
||||||
|
const Standard_Integer aNewNodesNb = aStructure->NbNodes ();
|
||||||
|
const Standard_Boolean isRemoveAux = aNewNodesNb > aNodesNb;
|
||||||
|
if (isRemoveAux)
|
||||||
|
{
|
||||||
|
IMeshData::VectorOfInteger aAuxVertices (aNewNodesNb - aNodesNb);
|
||||||
|
for (Standard_Integer aExtNodesIt = aNodesNb + 1; aExtNodesIt <= aNewNodesNb; ++aExtNodesIt)
|
||||||
|
{
|
||||||
|
aAuxVertices.Append (aExtNodesIt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set aux vertices if there are some to clean up mesh correctly.
|
||||||
|
aMesher.SetAuxVertices (aAuxVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
aMesher.ProcessConstraints ();
|
||||||
|
|
||||||
|
// Destruction of triangles containing aux vertices added (possibly) during base mesh computation.
|
||||||
|
if (isRemoveAux)
|
||||||
|
{
|
||||||
|
aMesher.RemoveAuxElements ();
|
||||||
|
}
|
||||||
|
|
||||||
|
BRepMesh_MeshTool aCleaner (aStructure);
|
||||||
|
aCleaner.EraseFreeLinks ();
|
||||||
|
|
||||||
|
postProcessMesh (aMesher);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Builds base triangulation using custom triangulation algorithm.
|
||||||
|
Standard_EXPORT virtual void buildBaseTriangulation() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
53
src/BRepMesh/BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
Normal file
53
src/BRepMesh/BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// Created on: 2019-06-07
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _BRepMesh_CustomDelaunayBaseMeshAlgo_HeaderFile
|
||||||
|
#define _BRepMesh_CustomDelaunayBaseMeshAlgo_HeaderFile
|
||||||
|
|
||||||
|
class BRepMesh_DataStructureOfDelaun;
|
||||||
|
class BRepMesh_Delaun;
|
||||||
|
|
||||||
|
//! Class provides base fuctionality to build face triangulation using custom
|
||||||
|
//! triangulation algorithm with possibility to modify final mesh.
|
||||||
|
//! Performs generation of mesh using raw data from model.
|
||||||
|
template<class BaseAlgo>
|
||||||
|
class BRepMesh_CustomDelaunayBaseMeshAlgo : public BaseAlgo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
BRepMesh_CustomDelaunayBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
virtual ~BRepMesh_CustomDelaunayBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Perfroms processing of generated mesh.
|
||||||
|
virtual void postProcessMesh(BRepMesh_Delaun& theMesher)
|
||||||
|
{
|
||||||
|
BaseAlgo::postProcessMesh (theMesher);
|
||||||
|
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
|
||||||
|
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes());
|
||||||
|
theMesher.InitCirclesTool (aCellsCount.first, aCellsCount.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
155
src/BRepMesh/BRepMesh_DelabellaBaseMeshAlgo.cxx
Normal file
155
src/BRepMesh/BRepMesh_DelabellaBaseMeshAlgo.cxx
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
// Created on: 2019-07-05
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_MeshTool.hxx>
|
||||||
|
#include <BRepMesh_Delaun.hxx>
|
||||||
|
|
||||||
|
#include "delabella.h"
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function: Constructor
|
||||||
|
// Purpose :
|
||||||
|
//=======================================================================
|
||||||
|
BRepMesh_DelabellaBaseMeshAlgo::BRepMesh_DelabellaBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function: Destructor
|
||||||
|
// Purpose :
|
||||||
|
//=======================================================================
|
||||||
|
BRepMesh_DelabellaBaseMeshAlgo::~BRepMesh_DelabellaBaseMeshAlgo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : buildBaseTriangulation
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation()
|
||||||
|
{
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
|
||||||
|
|
||||||
|
Bnd_B2d aBox;
|
||||||
|
const Standard_Integer aNodesNb = aStructure->NbNodes ();
|
||||||
|
std::vector<Standard_Real> aPoints (2 * (aNodesNb + 4));
|
||||||
|
for (Standard_Integer aNodeIt = 0; aNodeIt < aNodesNb; ++aNodeIt)
|
||||||
|
{
|
||||||
|
const BRepMesh_Vertex& aVertex = aStructure->GetNode (aNodeIt + 1);
|
||||||
|
|
||||||
|
const size_t aBaseIdx = 2 * static_cast<size_t> (aNodeIt);
|
||||||
|
aPoints[aBaseIdx + 0] = aVertex.Coord ().X ();
|
||||||
|
aPoints[aBaseIdx + 1] = aVertex.Coord ().Y ();
|
||||||
|
|
||||||
|
aBox.Add (gp_Pnt2d(aVertex.Coord ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
aBox.Enlarge (0.1 * (aBox.CornerMax () - aBox.CornerMin ()).Modulus ());
|
||||||
|
const gp_XY aMin = aBox.CornerMin ();
|
||||||
|
const gp_XY aMax = aBox.CornerMax ();
|
||||||
|
|
||||||
|
aPoints[2 * aNodesNb + 0] = aMin.X ();
|
||||||
|
aPoints[2 * aNodesNb + 1] = aMin.Y ();
|
||||||
|
aStructure->AddNode (BRepMesh_Vertex (
|
||||||
|
aPoints[2 * aNodesNb + 0],
|
||||||
|
aPoints[2 * aNodesNb + 1], BRepMesh_Free));
|
||||||
|
|
||||||
|
aPoints[2 * aNodesNb + 2] = aMax.X ();
|
||||||
|
aPoints[2 * aNodesNb + 3] = aMin.Y ();
|
||||||
|
aStructure->AddNode (BRepMesh_Vertex (
|
||||||
|
aPoints[2 * aNodesNb + 2],
|
||||||
|
aPoints[2 * aNodesNb + 3], BRepMesh_Free));
|
||||||
|
|
||||||
|
aPoints[2 * aNodesNb + 4] = aMax.X ();
|
||||||
|
aPoints[2 * aNodesNb + 5] = aMax.Y ();
|
||||||
|
aStructure->AddNode (BRepMesh_Vertex (
|
||||||
|
aPoints[2 * aNodesNb + 4],
|
||||||
|
aPoints[2 * aNodesNb + 5], BRepMesh_Free));
|
||||||
|
|
||||||
|
aPoints[2 * aNodesNb + 6] = aMin.X ();
|
||||||
|
aPoints[2 * aNodesNb + 7] = aMax.Y ();
|
||||||
|
aStructure->AddNode (BRepMesh_Vertex (
|
||||||
|
aPoints[2 * aNodesNb + 6],
|
||||||
|
aPoints[2 * aNodesNb + 7], BRepMesh_Free));
|
||||||
|
|
||||||
|
const Standard_Real aDiffX = (aMax.X () - aMin.X ());
|
||||||
|
const Standard_Real aDiffY = (aMax.Y () - aMin.Y ());
|
||||||
|
for (size_t i = 0; i < aPoints.size(); i += 2)
|
||||||
|
{
|
||||||
|
aPoints[i + 0] = (aPoints[i + 0] - aMin.X ()) / aDiffX - 0.5;
|
||||||
|
aPoints[i + 1] = (aPoints[i + 1] - aMin.Y ()) / aDiffY - 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDelaBella* aTriangulator = IDelaBella::Create();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (aTriangulator != NULL)
|
||||||
|
{
|
||||||
|
const int aVerticesNb = aTriangulator->Triangulate (
|
||||||
|
static_cast<int>(aPoints.size () / 2),
|
||||||
|
&aPoints[0], &aPoints[1], 2 * sizeof (Standard_Real));
|
||||||
|
|
||||||
|
if (aVerticesNb > 0)
|
||||||
|
{
|
||||||
|
const DelaBella_Triangle* aTrianglePtr = aTriangulator->GetFirstDelaunayTriangle();
|
||||||
|
while (aTrianglePtr != NULL)
|
||||||
|
{
|
||||||
|
Standard_Integer aNodes[3] = {
|
||||||
|
aTrianglePtr->v[0]->i + 1,
|
||||||
|
aTrianglePtr->v[2]->i + 1,
|
||||||
|
aTrianglePtr->v[1]->i + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
Standard_Integer aEdges [3];
|
||||||
|
Standard_Boolean aOrientations[3];
|
||||||
|
for (Standard_Integer k = 0; k < 3; ++k)
|
||||||
|
{
|
||||||
|
const BRepMesh_Edge aLink (aNodes[k], aNodes[(k + 1) % 3], BRepMesh_Free);
|
||||||
|
|
||||||
|
const Standard_Integer aLinkInfo = aStructure->AddLink (aLink);
|
||||||
|
aEdges [k] = Abs (aLinkInfo);
|
||||||
|
aOrientations[k] = aLinkInfo > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BRepMesh_Triangle aTriangle (aEdges, aOrientations, BRepMesh_Free);
|
||||||
|
aStructure->AddElement (aTriangle);
|
||||||
|
|
||||||
|
aTrianglePtr = aTrianglePtr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aTriangulator->Destroy ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const& theException)
|
||||||
|
{
|
||||||
|
if (aTriangulator != NULL)
|
||||||
|
{
|
||||||
|
aTriangulator->Destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Standard_Failure (theException);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (aTriangulator != NULL)
|
||||||
|
{
|
||||||
|
aTriangulator->Destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Standard_Failure ("BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation: exception in triangulation algorithm");
|
||||||
|
}
|
||||||
|
}
|
46
src/BRepMesh/BRepMesh_DelabellaBaseMeshAlgo.hxx
Normal file
46
src/BRepMesh/BRepMesh_DelabellaBaseMeshAlgo.hxx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Created on: 2019-07-05
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _BRepMesh_DelabellaBaseMeshAlgo_HeaderFile
|
||||||
|
#define _BRepMesh_DelabellaBaseMeshAlgo_HeaderFile
|
||||||
|
|
||||||
|
#include <BRepMesh_CustomBaseMeshAlgo.hxx>
|
||||||
|
#include <NCollection_Shared.hxx>
|
||||||
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
|
||||||
|
class BRepMesh_DataStructureOfDelaun;
|
||||||
|
class BRepMesh_Delaun;
|
||||||
|
|
||||||
|
//! Class provides base fuctionality to build face triangulation using Delabella project.
|
||||||
|
//! Performs generation of mesh using raw data from model.
|
||||||
|
class BRepMesh_DelabellaBaseMeshAlgo : public BRepMesh_CustomBaseMeshAlgo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
Standard_EXPORT BRepMesh_DelabellaBaseMeshAlgo ();
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
Standard_EXPORT virtual ~BRepMesh_DelabellaBaseMeshAlgo ();
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Builds base triangulation using Delabella project.
|
||||||
|
Standard_EXPORT virtual void buildBaseTriangulation() Standard_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
143
src/BRepMesh/BRepMesh_DelabellaMeshAlgoFactory.cxx
Normal file
143
src/BRepMesh/BRepMesh_DelabellaMeshAlgoFactory.cxx
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
// Created on: 2019-07-05
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
|
||||||
|
#include <BRepMesh_DefaultRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_NURBSRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_SphereRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_CylinderRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_ConeRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_TorusRangeSplitter.hxx>
|
||||||
|
#include <BRepMesh_DelaunayBaseMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_CustomDelaunayBaseMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx>
|
||||||
|
#include <BRepMesh_BoundaryParamsRangeSplitter.hxx>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct DefaultBaseMeshAlgo
|
||||||
|
{
|
||||||
|
typedef BRepMesh_DelaunayBaseMeshAlgo Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class RangeSplitter>
|
||||||
|
struct DefaultNodeInsertionMeshAlgo
|
||||||
|
{
|
||||||
|
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BaseMeshAlgo
|
||||||
|
{
|
||||||
|
typedef BRepMesh_DelabellaBaseMeshAlgo Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class RangeSplitter>
|
||||||
|
struct NodeInsertionMeshAlgo
|
||||||
|
{
|
||||||
|
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class RangeSplitter>
|
||||||
|
struct DeflectionControlMeshAlgo
|
||||||
|
{
|
||||||
|
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function: Constructor
|
||||||
|
// Purpose :
|
||||||
|
//=======================================================================
|
||||||
|
BRepMesh_DelabellaMeshAlgoFactory::BRepMesh_DelabellaMeshAlgoFactory ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function: Destructor
|
||||||
|
// Purpose :
|
||||||
|
//=======================================================================
|
||||||
|
BRepMesh_DelabellaMeshAlgoFactory::~BRepMesh_DelabellaMeshAlgoFactory ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function: GetAlgo
|
||||||
|
// Purpose :
|
||||||
|
//=======================================================================
|
||||||
|
Handle(IMeshTools_MeshAlgo) BRepMesh_DelabellaMeshAlgoFactory::GetAlgo(
|
||||||
|
const GeomAbs_SurfaceType theSurfaceType,
|
||||||
|
const IMeshTools_Parameters& theParameters) const
|
||||||
|
{
|
||||||
|
switch (theSurfaceType)
|
||||||
|
{
|
||||||
|
case GeomAbs_Plane:
|
||||||
|
return theParameters.InternalVerticesMode ?
|
||||||
|
new NodeInsertionMeshAlgo<BRepMesh_DefaultRangeSplitter>::Type :
|
||||||
|
new BaseMeshAlgo::Type;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeomAbs_Sphere:
|
||||||
|
{
|
||||||
|
NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type* aMeshAlgo =
|
||||||
|
new NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type;
|
||||||
|
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
|
||||||
|
return aMeshAlgo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeomAbs_Cylinder:
|
||||||
|
return theParameters.InternalVerticesMode ?
|
||||||
|
new DefaultNodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
|
||||||
|
new DefaultBaseMeshAlgo::Type;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeomAbs_Cone:
|
||||||
|
{
|
||||||
|
NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type* aMeshAlgo =
|
||||||
|
new NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type;
|
||||||
|
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
|
||||||
|
return aMeshAlgo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeomAbs_Torus:
|
||||||
|
{
|
||||||
|
NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type* aMeshAlgo =
|
||||||
|
new NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type;
|
||||||
|
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
|
||||||
|
return aMeshAlgo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GeomAbs_SurfaceOfRevolution:
|
||||||
|
{
|
||||||
|
DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type* aMeshAlgo =
|
||||||
|
new DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type;
|
||||||
|
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
|
||||||
|
return aMeshAlgo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type* aMeshAlgo =
|
||||||
|
new DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type;
|
||||||
|
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
|
||||||
|
return aMeshAlgo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
src/BRepMesh/BRepMesh_DelabellaMeshAlgoFactory.hxx
Normal file
44
src/BRepMesh/BRepMesh_DelabellaMeshAlgoFactory.hxx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Created on: 2019-07-05
|
||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
// Created by: Oleg AGASHIN
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _BRepMesh_DelabellaMeshAlgoFactory_HeaderFile
|
||||||
|
#define _BRepMesh_DelabellaMeshAlgoFactory_HeaderFile
|
||||||
|
|
||||||
|
#include <Standard_Transient.hxx>
|
||||||
|
#include <Standard_Type.hxx>
|
||||||
|
#include <GeomAbs_SurfaceType.hxx>
|
||||||
|
#include <IMeshTools_MeshAlgoFactory.hxx>
|
||||||
|
|
||||||
|
//! Implementation of IMeshTools_MeshAlgoFactory providing Delabella-based
|
||||||
|
//! algorithms of different compexity depending on type of target surface.
|
||||||
|
class BRepMesh_DelabellaMeshAlgoFactory : public IMeshTools_MeshAlgoFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor.
|
||||||
|
Standard_EXPORT BRepMesh_DelabellaMeshAlgoFactory ();
|
||||||
|
|
||||||
|
//! Destructor.
|
||||||
|
Standard_EXPORT virtual ~BRepMesh_DelabellaMeshAlgoFactory ();
|
||||||
|
|
||||||
|
//! Creates instance of meshing algorithm for the given type of surface.
|
||||||
|
Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo(
|
||||||
|
const GeomAbs_SurfaceType theSurfaceType,
|
||||||
|
const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaMeshAlgoFactory, IMeshTools_MeshAlgoFactory)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -78,13 +78,34 @@ namespace {
|
|||||||
}
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : BRepMesh_Delaun
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
BRepMesh_Delaun::BRepMesh_Delaun (
|
||||||
|
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||||
|
const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV,
|
||||||
|
const Standard_Boolean isFillCircles)
|
||||||
|
: myMeshData ( theOldMesh ),
|
||||||
|
myCircles (new NCollection_IncAllocator(
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
|
||||||
|
mySupVert (3)
|
||||||
|
{
|
||||||
|
if (isFillCircles)
|
||||||
|
{
|
||||||
|
InitCirclesTool (theCellsCountU, theCellsCountV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : BRepMesh_Delaun
|
//function : BRepMesh_Delaun
|
||||||
//purpose : Creates the triangulation with an empty Mesh data structure
|
//purpose : Creates the triangulation with an empty Mesh data structure
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
BRepMesh_Delaun::BRepMesh_Delaun(IMeshData::Array1OfVertexOfDelaun& theVertices)
|
BRepMesh_Delaun::BRepMesh_Delaun(IMeshData::Array1OfVertexOfDelaun& theVertices)
|
||||||
: myCircles (theVertices.Length(), new NCollection_IncAllocator(
|
: myCircles (theVertices.Length(), new NCollection_IncAllocator(
|
||||||
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
|
||||||
|
mySupVert (3)
|
||||||
{
|
{
|
||||||
if ( theVertices.Length() > 2 )
|
if ( theVertices.Length() > 2 )
|
||||||
{
|
{
|
||||||
@@ -103,7 +124,9 @@ BRepMesh_Delaun::BRepMesh_Delaun(
|
|||||||
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||||
IMeshData::Array1OfVertexOfDelaun& theVertices)
|
IMeshData::Array1OfVertexOfDelaun& theVertices)
|
||||||
: myMeshData( theOldMesh ),
|
: myMeshData( theOldMesh ),
|
||||||
myCircles ( theVertices.Length(), theOldMesh->Allocator() )
|
myCircles ( theVertices.Length(), new NCollection_IncAllocator(
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
|
||||||
|
mySupVert (3)
|
||||||
{
|
{
|
||||||
if ( theVertices.Length() > 2 )
|
if ( theVertices.Length() > 2 )
|
||||||
{
|
{
|
||||||
@@ -119,7 +142,9 @@ BRepMesh_Delaun::BRepMesh_Delaun(
|
|||||||
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||||
IMeshData::VectorOfInteger& theVertexIndices)
|
IMeshData::VectorOfInteger& theVertexIndices)
|
||||||
: myMeshData( theOldMesh ),
|
: myMeshData( theOldMesh ),
|
||||||
myCircles ( theVertexIndices.Length(), theOldMesh->Allocator() )
|
myCircles ( theVertexIndices.Length(), new NCollection_IncAllocator(
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
|
||||||
|
mySupVert (3)
|
||||||
{
|
{
|
||||||
perform(theVertexIndices);
|
perform(theVertexIndices);
|
||||||
}
|
}
|
||||||
@@ -133,7 +158,9 @@ BRepMesh_Delaun::BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)&
|
|||||||
const Standard_Integer theCellsCountU,
|
const Standard_Integer theCellsCountU,
|
||||||
const Standard_Integer theCellsCountV)
|
const Standard_Integer theCellsCountV)
|
||||||
: myMeshData (theOldMesh),
|
: myMeshData (theOldMesh),
|
||||||
myCircles (theVertexIndices.Length (), theOldMesh->Allocator ())
|
myCircles (theVertexIndices.Length (), new NCollection_IncAllocator(
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
|
||||||
|
mySupVert (3)
|
||||||
{
|
{
|
||||||
perform (theVertexIndices, theCellsCountU, theCellsCountV);
|
perform (theVertexIndices, theCellsCountU, theCellsCountV);
|
||||||
}
|
}
|
||||||
@@ -157,6 +184,63 @@ void BRepMesh_Delaun::Init(IMeshData::Array1OfVertexOfDelaun& theVertices)
|
|||||||
perform( aVertexIndexes );
|
perform( aVertexIndexes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : InitCirclesTool
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void BRepMesh_Delaun::InitCirclesTool (const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV)
|
||||||
|
{
|
||||||
|
Bnd_Box2d aBox;
|
||||||
|
for (Standard_Integer aNodeIt = 1; aNodeIt <= myMeshData->NbNodes(); ++aNodeIt)
|
||||||
|
{
|
||||||
|
aBox.Add (gp_Pnt2d (GetVertex (aNodeIt).Coord ()));
|
||||||
|
}
|
||||||
|
aBox.Enlarge (Precision);
|
||||||
|
|
||||||
|
initCirclesTool (aBox, theCellsCountU, theCellsCountV);
|
||||||
|
|
||||||
|
IMeshData::IteratorOfMapOfInteger aTriangleIt (myMeshData->ElementsOfDomain());
|
||||||
|
for (; aTriangleIt.More(); aTriangleIt.Next())
|
||||||
|
{
|
||||||
|
Standard_Integer aNodesIndices[3];
|
||||||
|
const BRepMesh_Triangle& aTriangle = myMeshData->GetElement (aTriangleIt.Key());
|
||||||
|
myMeshData->ElementNodes (aTriangle, aNodesIndices);
|
||||||
|
myCircles.Bind (aTriangleIt.Key(),
|
||||||
|
GetVertex( aNodesIndices[0] ).Coord(),
|
||||||
|
GetVertex( aNodesIndices[1] ).Coord(),
|
||||||
|
GetVertex( aNodesIndices[2] ).Coord());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : initCirclesTool
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void BRepMesh_Delaun::initCirclesTool (const Bnd_Box2d& theBox,
|
||||||
|
const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV)
|
||||||
|
{
|
||||||
|
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
|
||||||
|
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
|
||||||
|
const Standard_Real aDeltaX = aMaxX - aMinX;
|
||||||
|
const Standard_Real aDeltaY = aMaxY - aMinY;
|
||||||
|
|
||||||
|
Standard_Integer aScaler = 2;
|
||||||
|
if ( myMeshData->NbNodes() > 100 )
|
||||||
|
{
|
||||||
|
aScaler = 5;
|
||||||
|
}
|
||||||
|
else if( myMeshData->NbNodes() > 1000 )
|
||||||
|
{
|
||||||
|
aScaler = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
|
||||||
|
myCircles.SetCellSize ( aDeltaX / Max (theCellsCountU, aScaler),
|
||||||
|
aDeltaY / Max (theCellsCountV, aScaler));
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : perform
|
//function : perform
|
||||||
//purpose : Create super mesh and run triangulation procedure
|
//purpose : Create super mesh and run triangulation procedure
|
||||||
@@ -180,18 +264,8 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
|
|||||||
|
|
||||||
aBox.Enlarge (Precision);
|
aBox.Enlarge (Precision);
|
||||||
|
|
||||||
Standard_Integer aScaler = 2;
|
initCirclesTool (aBox, theCellsCountU, theCellsCountV);
|
||||||
if ( myMeshData->NbNodes() > 100 )
|
superMesh (aBox);
|
||||||
{
|
|
||||||
aScaler = 5;
|
|
||||||
}
|
|
||||||
else if( myMeshData->NbNodes() > 1000 )
|
|
||||||
{
|
|
||||||
aScaler = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
superMesh (aBox, Max (theCellsCountU, aScaler),
|
|
||||||
Max (theCellsCountV, aScaler));
|
|
||||||
|
|
||||||
ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
|
ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
|
||||||
std::make_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
|
std::make_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
|
||||||
@@ -204,9 +278,7 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
|
|||||||
//function : superMesh
|
//function : superMesh
|
||||||
//purpose : Build the super mesh
|
//purpose : Build the super mesh
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
|
||||||
const Standard_Integer theCellsCountU,
|
|
||||||
const Standard_Integer theCellsCountV)
|
|
||||||
{
|
{
|
||||||
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
|
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
|
||||||
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
|
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
|
||||||
@@ -217,17 +289,14 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
|||||||
Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
|
Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
|
||||||
Standard_Real aDelta = aDeltaX + aDeltaY;
|
Standard_Real aDelta = aDeltaX + aDeltaY;
|
||||||
|
|
||||||
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
|
mySupVert.Append (myMeshData->AddNode(
|
||||||
myCircles.SetCellSize( aDeltaX / theCellsCountU, aDeltaY / theCellsCountV);
|
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) ) );
|
||||||
|
|
||||||
mySupVert[0] = myMeshData->AddNode(
|
mySupVert.Append (myMeshData->AddNode(
|
||||||
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) );
|
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
|
||||||
|
|
||||||
mySupVert[1] = myMeshData->AddNode(
|
mySupVert.Append (myMeshData->AddNode(
|
||||||
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
|
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
|
||||||
|
|
||||||
mySupVert[2] = myMeshData->AddNode(
|
|
||||||
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
|
|
||||||
|
|
||||||
Standard_Integer e[3];
|
Standard_Integer e[3];
|
||||||
Standard_Boolean o[3];
|
Standard_Boolean o[3];
|
||||||
@@ -236,7 +305,7 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
|||||||
Standard_Integer aFirstNode = aNodeId;
|
Standard_Integer aFirstNode = aNodeId;
|
||||||
Standard_Integer aLastNode = (aNodeId + 1) % 3;
|
Standard_Integer aLastNode = (aNodeId + 1) % 3;
|
||||||
Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge(
|
Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge(
|
||||||
mySupVert[aFirstNode], mySupVert[aLastNode], BRepMesh_Free ) );
|
mySupVert (aFirstNode), mySupVert (aLastNode), BRepMesh_Free ) );
|
||||||
|
|
||||||
e[aNodeId] = Abs(aLinkIndex);
|
e[aNodeId] = Abs(aLinkIndex);
|
||||||
o[aNodeId] = (aLinkIndex > 0);
|
o[aNodeId] = (aLinkIndex > 0);
|
||||||
@@ -254,7 +323,10 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
|||||||
void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
|
void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
|
||||||
IMeshData::MapOfIntegerInteger& theLoopEdges )
|
IMeshData::MapOfIntegerInteger& theLoopEdges )
|
||||||
{
|
{
|
||||||
myCircles.Delete( theIndex );
|
if (!myCircles.IsEmpty())
|
||||||
|
{
|
||||||
|
myCircles.Delete (theIndex);
|
||||||
|
}
|
||||||
|
|
||||||
const BRepMesh_Triangle& aElement = GetTriangle(theIndex);
|
const BRepMesh_Triangle& aElement = GetTriangle(theIndex);
|
||||||
const Standard_Integer(&e)[3] = aElement.myEdges;
|
const Standard_Integer(&e)[3] = aElement.myEdges;
|
||||||
@@ -280,7 +352,10 @@ void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
|
|||||||
void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
|
void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
|
||||||
{
|
{
|
||||||
// Insertion of edges of super triangles in the list of free edges:
|
// Insertion of edges of super triangles in the list of free edges:
|
||||||
IMeshData::MapOfIntegerInteger aLoopEdges(10, myMeshData->Allocator());
|
Handle(NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator(
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
|
||||||
|
|
||||||
|
IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
|
||||||
const Standard_Integer(&e)[3] = mySupTrian.myEdges;
|
const Standard_Integer(&e)[3] = mySupTrian.myEdges;
|
||||||
|
|
||||||
aLoopEdges.Bind( e[0], Standard_True );
|
aLoopEdges.Bind( e[0], Standard_True );
|
||||||
@@ -297,28 +372,41 @@ void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
|
|||||||
createTrianglesOnNewVertices( theVertexIndexes );
|
createTrianglesOnNewVertices( theVertexIndexes );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destruction of triangles containing a top of the super triangle
|
RemoveAuxElements ();
|
||||||
BRepMesh_SelectorOfDataStructureOfDelaun aSelector( myMeshData );
|
}
|
||||||
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
|
|
||||||
aSelector.NeighboursOfNode( mySupVert[aSupVertId] );
|
|
||||||
|
|
||||||
aLoopEdges.Clear();
|
//=======================================================================
|
||||||
IMeshData::IteratorOfMapOfInteger aFreeTriangles( aSelector.Elements() );
|
//function : RemoveAuxElements
|
||||||
for ( ; aFreeTriangles.More(); aFreeTriangles.Next() )
|
//purpose :
|
||||||
deleteTriangle( aFreeTriangles.Key(), aLoopEdges );
|
//=======================================================================
|
||||||
|
void BRepMesh_Delaun::RemoveAuxElements ()
|
||||||
|
{
|
||||||
|
Handle (NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator (
|
||||||
|
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
|
||||||
|
|
||||||
|
IMeshData::MapOfIntegerInteger aLoopEdges (10, aAllocator);
|
||||||
|
|
||||||
|
// Destruction of triangles containing a top of the super triangle
|
||||||
|
BRepMesh_SelectorOfDataStructureOfDelaun aSelector (myMeshData);
|
||||||
|
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size(); ++aSupVertId)
|
||||||
|
aSelector.NeighboursOfNode (mySupVert (aSupVertId));
|
||||||
|
|
||||||
|
IMeshData::IteratorOfMapOfInteger aFreeTriangles (aSelector.Elements ());
|
||||||
|
for (; aFreeTriangles.More (); aFreeTriangles.Next ())
|
||||||
|
deleteTriangle (aFreeTriangles.Key (), aLoopEdges);
|
||||||
|
|
||||||
// All edges that remain free are removed from aLoopEdges;
|
// All edges that remain free are removed from aLoopEdges;
|
||||||
// only the boundary edges of the triangulation remain there
|
// only the boundary edges of the triangulation remain there
|
||||||
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges( aLoopEdges );
|
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges (aLoopEdges);
|
||||||
for ( ; aFreeEdges.More(); aFreeEdges.Next() )
|
for (; aFreeEdges.More (); aFreeEdges.Next ())
|
||||||
{
|
{
|
||||||
if ( myMeshData->ElementsConnectedTo( aFreeEdges.Key() ).IsEmpty() )
|
if (myMeshData->ElementsConnectedTo (aFreeEdges.Key ()).IsEmpty ())
|
||||||
myMeshData->RemoveLink( aFreeEdges.Key() );
|
myMeshData->RemoveLink (aFreeEdges.Key ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The tops of the super triangle are destroyed
|
// The tops of the super triangle are destroyed
|
||||||
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
|
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size (); ++aSupVertId)
|
||||||
myMeshData->RemoveNode( mySupVert[aSupVertId] );
|
myMeshData->RemoveNode (mySupVert (aSupVertId));
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -531,10 +619,7 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insertInternalEdges();
|
ProcessConstraints();
|
||||||
|
|
||||||
// Adjustment of meshes to boundary edges
|
|
||||||
frontierAdjust();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -704,9 +789,7 @@ void BRepMesh_Delaun::cleanupMesh()
|
|||||||
myMeshData->ElementNodes (aCurTriangle, v);
|
myMeshData->ElementNodes (aCurTriangle, v);
|
||||||
for (int aNodeIdx = 0; aNodeIdx < 3 && isCanNotBeRemoved; ++aNodeIdx)
|
for (int aNodeIdx = 0; aNodeIdx < 3 && isCanNotBeRemoved; ++aNodeIdx)
|
||||||
{
|
{
|
||||||
if (v[aNodeIdx] == mySupVert[0] ||
|
if (isSupVertex (v[aNodeIdx]))
|
||||||
v[aNodeIdx] == mySupVert[1] ||
|
|
||||||
v[aNodeIdx] == mySupVert[2])
|
|
||||||
{
|
{
|
||||||
isCanNotBeRemoved = Standard_False;
|
isCanNotBeRemoved = Standard_False;
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,12 @@ public:
|
|||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
DEFINE_STANDARD_ALLOC
|
||||||
|
|
||||||
|
//! Creates instance of triangulator, but do not run the algorithm automatically.
|
||||||
|
Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||||
|
const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV,
|
||||||
|
const Standard_Boolean isFillCircles);
|
||||||
|
|
||||||
//! Creates the triangulation with an empty Mesh data structure.
|
//! Creates the triangulation with an empty Mesh data structure.
|
||||||
Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
|
Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
|
||||||
|
|
||||||
@@ -61,6 +67,10 @@ public:
|
|||||||
//! Initializes the triangulation with an array of vertices.
|
//! Initializes the triangulation with an array of vertices.
|
||||||
Standard_EXPORT void Init (IMeshData::Array1OfVertexOfDelaun& theVertices);
|
Standard_EXPORT void Init (IMeshData::Array1OfVertexOfDelaun& theVertices);
|
||||||
|
|
||||||
|
//! Forces initialization of circles cell filter using working structure.
|
||||||
|
Standard_EXPORT void InitCirclesTool (const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV);
|
||||||
|
|
||||||
//! Removes a vertex from the triangulation.
|
//! Removes a vertex from the triangulation.
|
||||||
Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
|
Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
|
||||||
|
|
||||||
@@ -77,6 +87,15 @@ public:
|
|||||||
return myMeshData;
|
return myMeshData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Forces insertion of constraint edges into the base triangulation.
|
||||||
|
inline void ProcessConstraints()
|
||||||
|
{
|
||||||
|
insertInternalEdges();
|
||||||
|
|
||||||
|
// Adjustment of meshes to boundary edges
|
||||||
|
frontierAdjust();
|
||||||
|
}
|
||||||
|
|
||||||
//! Gives the list of frontier edges.
|
//! Gives the list of frontier edges.
|
||||||
inline Handle(IMeshData::MapOfInteger) Frontier() const
|
inline Handle(IMeshData::MapOfInteger) Frontier() const
|
||||||
{
|
{
|
||||||
@@ -128,6 +147,17 @@ public:
|
|||||||
const Standard_Real theSqTolerance,
|
const Standard_Real theSqTolerance,
|
||||||
Standard_Integer& theEdgeOn) const;
|
Standard_Integer& theEdgeOn) const;
|
||||||
|
|
||||||
|
//! Explicitly sets ids of auxiliary vertices used to build mesh and used by 3rd-party algorithms.
|
||||||
|
inline void SetAuxVertices (const IMeshData::VectorOfInteger& theSupVert)
|
||||||
|
{
|
||||||
|
mySupVert = theSupVert;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Destruction of auxiliary triangles containing the given vertices.
|
||||||
|
//! Removes auxiliary vertices also.
|
||||||
|
//! @param theAuxVertices auxiliary vertices to be cleaned up.
|
||||||
|
Standard_EXPORT void RemoveAuxElements ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum ReplaceFlag
|
enum ReplaceFlag
|
||||||
@@ -139,6 +169,11 @@ private:
|
|||||||
|
|
||||||
typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
|
typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
|
||||||
|
|
||||||
|
//! Performs initialization of circles cell filter tool.
|
||||||
|
void initCirclesTool (const Bnd_Box2d& theBox,
|
||||||
|
const Standard_Integer theCellsCountU,
|
||||||
|
const Standard_Integer theCellsCountV);
|
||||||
|
|
||||||
//! Add boundig box for edge defined by start & end point to
|
//! Add boundig box for edge defined by start & end point to
|
||||||
//! the given vector of bounding boxes for triangulation edges.
|
//! the given vector of bounding boxes for triangulation edges.
|
||||||
void fillBndBox (IMeshData::SequenceOfBndB2d& theBoxes,
|
void fillBndBox (IMeshData::SequenceOfBndB2d& theBoxes,
|
||||||
@@ -156,9 +191,7 @@ private:
|
|||||||
const Standard_Integer theCellsCountV = -1);
|
const Standard_Integer theCellsCountV = -1);
|
||||||
|
|
||||||
//! Build the super mesh.
|
//! Build the super mesh.
|
||||||
void superMesh (const Bnd_Box2d& theBox,
|
void superMesh (const Bnd_Box2d& theBox);
|
||||||
const Standard_Integer theCellsCountU,
|
|
||||||
const Standard_Integer theCellsCountV);
|
|
||||||
|
|
||||||
//! Computes the triangulation and adds the vertices,
|
//! Computes the triangulation and adds the vertices,
|
||||||
//! edges and triangles to the Mesh data structure.
|
//! edges and triangles to the Mesh data structure.
|
||||||
@@ -332,11 +365,25 @@ private:
|
|||||||
//! Performs insertion of internal edges into mesh.
|
//! Performs insertion of internal edges into mesh.
|
||||||
void insertInternalEdges();
|
void insertInternalEdges();
|
||||||
|
|
||||||
|
//! Checks whether the given vertex id relates to super contour.
|
||||||
|
inline Standard_Boolean isSupVertex (const Standard_Integer theVertexIdx)
|
||||||
|
{
|
||||||
|
for (IMeshData::VectorOfInteger::Iterator aIt (mySupVert); aIt.More (); aIt.Next ())
|
||||||
|
{
|
||||||
|
if (theVertexIdx == aIt.Value ())
|
||||||
|
{
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
|
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
|
||||||
BRepMesh_CircleTool myCircles;
|
BRepMesh_CircleTool myCircles;
|
||||||
Standard_Integer mySupVert[3];
|
IMeshData::VectorOfInteger mySupVert;
|
||||||
BRepMesh_Triangle mySupTrian;
|
BRepMesh_Triangle mySupTrian;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
||||||
#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
||||||
|
|
||||||
#include <BRepMesh_BaseMeshAlgo.hxx>
|
#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
|
||||||
#include <NCollection_Shared.hxx>
|
#include <NCollection_Shared.hxx>
|
||||||
#include <IMeshTools_Parameters.hxx>
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ class BRepMesh_Delaun;
|
|||||||
|
|
||||||
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
|
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
|
||||||
//! Performs generation of mesh using raw data from model.
|
//! Performs generation of mesh using raw data from model.
|
||||||
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
|
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -35,24 +35,12 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
|
Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Returns size of cell to be used by acceleration circles grid structure.
|
|
||||||
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer /*theVerticesNb*/)
|
|
||||||
{
|
|
||||||
return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Generates mesh for the contour stored in data structure.
|
//! Generates mesh for the contour stored in data structure.
|
||||||
Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
|
Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
|
||||||
|
|
||||||
//! Perfroms processing of generated mesh.
|
|
||||||
//! By default does nothing.
|
|
||||||
virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
//! Extends node insertion Delaunay meshing algo in order to control
|
//! Extends node insertion Delaunay meshing algo in order to control
|
||||||
//! deflection of generated trianges. Splits triangles failing the check.
|
//! deflection of generated trianges. Splits triangles failing the check.
|
||||||
template<class RangeSplitter>
|
template<class RangeSplitter, class BaseAlgo>
|
||||||
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter>
|
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Typedef for OCCT RTTI
|
// Typedef for OCCT RTTI
|
||||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> DelaunayInsertionBaseClass;
|
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> DelaunayInsertionBaseClass;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@@ -21,17 +21,18 @@
|
|||||||
|
|
||||||
//! Extends base Delaunay meshing algo in order to enable possibility
|
//! Extends base Delaunay meshing algo in order to enable possibility
|
||||||
//! of addition of free vertices and internal nodes into the mesh.
|
//! of addition of free vertices and internal nodes into the mesh.
|
||||||
template<class RangeSplitter>
|
template<class RangeSplitter, class BaseAlgo>
|
||||||
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo>
|
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Typedef for OCCT RTTI
|
// Typedef for OCCT RTTI
|
||||||
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> InsertionBaseClass;
|
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> InsertionBaseClass;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructor.
|
//! Constructor.
|
||||||
BRepMesh_DelaunayNodeInsertionMeshAlgo()
|
BRepMesh_DelaunayNodeInsertionMeshAlgo()
|
||||||
|
: myIsPreProcessSurfaceNodes (Standard_False)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,8 +41,41 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns PreProcessSurfaceNodes flag.
|
||||||
|
inline Standard_Boolean IsPreProcessSurfaceNodes () const
|
||||||
|
{
|
||||||
|
return myIsPreProcessSurfaceNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Sets PreProcessSurfaceNodes flag.
|
||||||
|
//! If TRUE, registers surface nodes before generation of base mesh.
|
||||||
|
//! If FALSE, inserts surface nodes after generation of base mesh.
|
||||||
|
inline void SetPreProcessSurfaceNodes (const Standard_Boolean isPreProcessSurfaceNodes)
|
||||||
|
{
|
||||||
|
myIsPreProcessSurfaceNodes = isPreProcessSurfaceNodes;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//! Performs initialization of data structure using existing model data.
|
||||||
|
virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
if (!InsertionBaseClass::initDataStructure())
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myIsPreProcessSurfaceNodes)
|
||||||
|
{
|
||||||
|
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
|
||||||
|
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
|
||||||
|
|
||||||
|
registerSurfaceNodes (aSurfaceNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
//! Returns size of cell to be used by acceleration circles grid structure.
|
//! Returns size of cell to be used by acceleration circles grid structure.
|
||||||
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
|
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
|
||||||
{
|
{
|
||||||
@@ -55,11 +89,14 @@ protected:
|
|||||||
{
|
{
|
||||||
InsertionBaseClass::postProcessMesh(theMesher);
|
InsertionBaseClass::postProcessMesh(theMesher);
|
||||||
|
|
||||||
|
if (!myIsPreProcessSurfaceNodes)
|
||||||
|
{
|
||||||
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
|
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
|
||||||
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
|
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
|
||||||
|
|
||||||
insertNodes(aSurfaceNodes, theMesher);
|
insertNodes(aSurfaceNodes, theMesher);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//! Inserts nodes into mesh.
|
//! Inserts nodes into mesh.
|
||||||
Standard_Boolean insertNodes(
|
Standard_Boolean insertNodes(
|
||||||
@@ -86,6 +123,37 @@ protected:
|
|||||||
theMesher.AddVertices(aVertexIndexes);
|
theMesher.AddVertices(aVertexIndexes);
|
||||||
return !aVertexIndexes.IsEmpty();
|
return !aVertexIndexes.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//! Registers surface nodes in data structure.
|
||||||
|
Standard_Boolean registerSurfaceNodes(
|
||||||
|
const Handle(IMeshData::ListOfPnt2d)& theNodes)
|
||||||
|
{
|
||||||
|
if (theNodes.IsNull() || theNodes->IsEmpty())
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
Standard_Boolean isAdded = Standard_False;
|
||||||
|
IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
|
||||||
|
for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
|
||||||
|
{
|
||||||
|
const gp_Pnt2d& aPnt2d = aNodesIt.Value();
|
||||||
|
if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
|
||||||
|
{
|
||||||
|
isAdded = Standard_True;
|
||||||
|
this->registerNode(this->getRangeSplitter().Point(aPnt2d),
|
||||||
|
aPnt2d, BRepMesh_Free, Standard_False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Standard_Boolean myIsPreProcessSurfaceNodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -83,7 +83,7 @@ Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellation
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_EdgeDiscret::Perform (
|
Standard_Boolean BRepMesh_EdgeDiscret::performInternal (
|
||||||
const Handle (IMeshData_Model)& theModel,
|
const Handle (IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
@@ -108,6 +108,10 @@ Standard_Boolean BRepMesh_EdgeDiscret::Perform (
|
|||||||
void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
|
void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
|
||||||
{
|
{
|
||||||
const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
|
const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
|
BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
|
||||||
|
|
||||||
Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
|
Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
|
||||||
@@ -172,6 +176,11 @@ void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
|
|||||||
{
|
{
|
||||||
Tessellate2d(aDEdge, Standard_True);
|
Tessellate2d(aDEdge, Standard_True);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const&)
|
||||||
|
{
|
||||||
|
aDEdge->SetStatus (IMeshData_Failure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -52,11 +52,6 @@ public:
|
|||||||
const IMeshData::IEdgeHandle& theDEdge,
|
const IMeshData::IEdgeHandle& theDEdge,
|
||||||
const IMeshData::IFaceHandle& theDFace);
|
const IMeshData::IFaceHandle& theDFace);
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform (
|
|
||||||
const Handle (IMeshData_Model)& theModel,
|
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
|
||||||
|
|
||||||
//! Functor API to discretize the given edge.
|
//! Functor API to discretize the given edge.
|
||||||
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
||||||
process (theEdgeIndex);
|
process (theEdgeIndex);
|
||||||
@@ -75,6 +70,13 @@ public:
|
|||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_EdgeDiscret, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Performs processing of edges of the given model.
|
||||||
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
|
const Handle (IMeshData_Model)& theModel,
|
||||||
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Checks existing discretization of the edge and updates data model.
|
//! Checks existing discretization of the edge and updates data model.
|
||||||
|
@@ -94,8 +94,6 @@ namespace
|
|||||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Selector.
|
|
||||||
//! Used to identify segments with overlapped bounding boxes.
|
|
||||||
//! Selector.
|
//! Selector.
|
||||||
//! Used to identify segments with overlapped bounding boxes.
|
//! Used to identify segments with overlapped bounding boxes.
|
||||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||||
|
@@ -43,7 +43,7 @@ BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret()
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_FaceDiscret::Perform(
|
Standard_Boolean BRepMesh_FaceDiscret::performInternal(
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
@@ -73,6 +73,10 @@ void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
Handle(IMeshTools_MeshAlgo) aMeshingAlgo =
|
Handle(IMeshTools_MeshAlgo) aMeshingAlgo =
|
||||||
myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
|
myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
|
||||||
|
|
||||||
@@ -83,4 +87,9 @@ void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
aMeshingAlgo->Perform(aDFace, myParameters);
|
aMeshingAlgo->Perform(aDFace, myParameters);
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const&)
|
||||||
|
{
|
||||||
|
aDFace->SetStatus (IMeshData_Failure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
//! Class implements functionality starting triangulation of model's faces.
|
//! Class implements functionality starting triangulation of model's faces.
|
||||||
//! Each face is processed separately and can be executed in parallel mode.
|
//! Each face is processed separately and can be executed in parallel mode.
|
||||||
//! Uses mesh algo factory passed as initializer to create instace of triangulation
|
//! Uses mesh algo factory passed as initializer to create instance of triangulation
|
||||||
//! algorithm according to type of surface of target face.
|
//! algorithm according to type of surface of target face.
|
||||||
class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
|
class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
|
||||||
{
|
{
|
||||||
@@ -36,11 +36,6 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_FaceDiscret();
|
Standard_EXPORT virtual ~BRepMesh_FaceDiscret();
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform(
|
|
||||||
const Handle(IMeshData_Model)& theModel,
|
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
|
||||||
|
|
||||||
//! Functor API to discretize the given edge.
|
//! Functor API to discretize the given edge.
|
||||||
inline void operator() (const Standard_Integer theFaceIndex) const {
|
inline void operator() (const Standard_Integer theFaceIndex) const {
|
||||||
process(theFaceIndex);
|
process(theFaceIndex);
|
||||||
@@ -48,6 +43,13 @@ public:
|
|||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo)
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_FaceDiscret, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Performs processing of faces of the given model.
|
||||||
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
|
const Handle(IMeshData_Model)& theModel,
|
||||||
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Checks existing discretization of the face and updates data model.
|
//! Checks existing discretization of the face and updates data model.
|
||||||
|
@@ -86,19 +86,28 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
|
|||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void BRepMesh_IncrementalMesh::Perform()
|
void BRepMesh_IncrementalMesh::Perform()
|
||||||
|
{
|
||||||
|
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
|
||||||
|
Perform (aContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Perform
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void BRepMesh_IncrementalMesh::Perform(const Handle(IMeshTools_Context)& theContext)
|
||||||
{
|
{
|
||||||
initParameters();
|
initParameters();
|
||||||
|
|
||||||
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
|
theContext->SetShape(Shape());
|
||||||
aContext->SetShape(Shape());
|
theContext->ChangeParameters() = myParameters;
|
||||||
aContext->ChangeParameters() = myParameters;
|
theContext->ChangeParameters().CleanModel = Standard_False;
|
||||||
aContext->ChangeParameters().CleanModel = Standard_False;
|
|
||||||
|
|
||||||
IMeshTools_MeshBuilder aIncMesh(aContext);
|
IMeshTools_MeshBuilder aIncMesh(theContext);
|
||||||
aIncMesh.Perform();
|
aIncMesh.Perform();
|
||||||
|
|
||||||
myStatus = IMeshData_NoError;
|
myStatus = IMeshData_NoError;
|
||||||
const Handle(IMeshData_Model)& aModel = aContext->GetModel();
|
const Handle(IMeshData_Model)& aModel = theContext->GetModel();
|
||||||
for (Standard_Integer aFaceIt = 0; aFaceIt < aModel->FacesNb(); ++aFaceIt)
|
for (Standard_Integer aFaceIt = 0; aFaceIt < aModel->FacesNb(); ++aFaceIt)
|
||||||
{
|
{
|
||||||
const IMeshData::IFaceHandle& aDFace = aModel->GetFace(aFaceIt);
|
const IMeshData::IFaceHandle& aDFace = aModel->GetFace(aFaceIt);
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <BRepMesh_DiscretRoot.hxx>
|
#include <BRepMesh_DiscretRoot.hxx>
|
||||||
#include <IMeshTools_Parameters.hxx>
|
#include <IMeshTools_Parameters.hxx>
|
||||||
|
#include <IMeshTools_Context.hxx>
|
||||||
|
|
||||||
//! Builds the mesh of a shape with respect of their
|
//! Builds the mesh of a shape with respect of their
|
||||||
//! correctly triangulated parts
|
//! correctly triangulated parts
|
||||||
@@ -51,9 +52,12 @@ public: //! @name mesher API
|
|||||||
Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
|
Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
|
||||||
const IMeshTools_Parameters& theParameters);
|
const IMeshTools_Parameters& theParameters);
|
||||||
|
|
||||||
//! Performs meshing ot the shape.
|
//! Performs meshing ot the shape.
|
||||||
Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
|
Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Performs meshing using custom context;
|
||||||
|
Standard_EXPORT void Perform(const Handle(IMeshTools_Context)& theContext);
|
||||||
|
|
||||||
public: //! @name accessing to parameters.
|
public: //! @name accessing to parameters.
|
||||||
|
|
||||||
//! Returns meshing parameters
|
//! Returns meshing parameters
|
||||||
|
@@ -35,13 +35,13 @@ namespace
|
|||||||
template<class RangeSplitter>
|
template<class RangeSplitter>
|
||||||
struct NodeInsertionMeshAlgo
|
struct NodeInsertionMeshAlgo
|
||||||
{
|
{
|
||||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> Type;
|
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class RangeSplitter>
|
template<class RangeSplitter>
|
||||||
struct DeflectionControlMeshAlgo
|
struct DeflectionControlMeshAlgo
|
||||||
{
|
{
|
||||||
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter> Type;
|
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,9 @@ Handle(IMeshTools_MeshAlgo) BRepMesh_MeshAlgoFactory::GetAlgo(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GeomAbs_Cylinder:
|
case GeomAbs_Cylinder:
|
||||||
return new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type;
|
return theParameters.InternalVerticesMode ?
|
||||||
|
new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
|
||||||
|
new BaseMeshAlgo::Type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GeomAbs_Cone:
|
case GeomAbs_Cone:
|
||||||
|
@@ -18,7 +18,6 @@
|
|||||||
#include <BRepMesh_ShapeVisitor.hxx>
|
#include <BRepMesh_ShapeVisitor.hxx>
|
||||||
#include <BRepMesh_ShapeTool.hxx>
|
#include <BRepMesh_ShapeTool.hxx>
|
||||||
#include <IMeshTools_ShapeExplorer.hxx>
|
#include <IMeshTools_ShapeExplorer.hxx>
|
||||||
#include <Standard_ErrorHandler.hxx>
|
|
||||||
|
|
||||||
#include <Bnd_Box.hxx>
|
#include <Bnd_Box.hxx>
|
||||||
#include <BRepBndLib.hxx>
|
#include <BRepBndLib.hxx>
|
||||||
@@ -43,16 +42,11 @@ BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder ()
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
|
Handle (IMeshData_Model) BRepMesh_ModelBuilder::performInternal (
|
||||||
const TopoDS_Shape& theShape,
|
const TopoDS_Shape& theShape,
|
||||||
const IMeshTools_Parameters& theParameters)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
ClearStatus ();
|
|
||||||
|
|
||||||
Handle (BRepMeshData_Model) aModel;
|
Handle (BRepMeshData_Model) aModel;
|
||||||
try
|
|
||||||
{
|
|
||||||
OCC_CATCH_SIGNALS
|
|
||||||
|
|
||||||
Bnd_Box aBox;
|
Bnd_Box aBox;
|
||||||
BRepBndLib::Add (theShape, aBox, Standard_False);
|
BRepBndLib::Add (theShape, aBox, Standard_False);
|
||||||
@@ -83,12 +77,7 @@ Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetStatus(Message_Fail1);
|
SetStatus (Message_Fail1);
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Standard_Failure&)
|
|
||||||
{
|
|
||||||
SetStatus (Message_Fail2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return aModel;
|
return aModel;
|
||||||
|
@@ -36,13 +36,15 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_ModelBuilder ();
|
Standard_EXPORT virtual ~BRepMesh_ModelBuilder ();
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
//! Creates discrete model for the given shape.
|
//! Creates discrete model for the given shape.
|
||||||
//! Returns nullptr in case of failure.
|
//! Returns nullptr in case of failure.
|
||||||
Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
|
Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
|
||||||
const TopoDS_Shape& theShape,
|
const TopoDS_Shape& theShape,
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@@ -115,7 +115,7 @@ BRepMesh_ModelHealer::~BRepMesh_ModelHealer()
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_ModelHealer::Perform(
|
Standard_Boolean BRepMesh_ModelHealer::performInternal(
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
@@ -226,6 +226,10 @@ Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate(
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
|
void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
|
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
|
||||||
aIntersections.Nullify();
|
aIntersections.Nullify();
|
||||||
|
|
||||||
@@ -242,6 +246,11 @@ void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
|
|||||||
aIntersections = aChecker.GetIntersectingEdges();
|
aIntersections = aChecker.GetIntersectingEdges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const&)
|
||||||
|
{
|
||||||
|
theDFace->SetStatus (IMeshData_Failure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@@ -44,11 +44,6 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_ModelHealer();
|
Standard_EXPORT virtual ~BRepMesh_ModelHealer();
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform(
|
|
||||||
const Handle(IMeshData_Model)& theModel,
|
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
|
||||||
|
|
||||||
//! Functor API to discretize the given edge.
|
//! Functor API to discretize the given edge.
|
||||||
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
||||||
process(theEdgeIndex);
|
process(theEdgeIndex);
|
||||||
@@ -61,6 +56,13 @@ public:
|
|||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelHealer, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//! Performs processing of edges of the given model.
|
||||||
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
|
const Handle(IMeshData_Model)& theModel,
|
||||||
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Checks existing discretization of the face and updates data model.
|
//! Checks existing discretization of the face and updates data model.
|
||||||
|
@@ -177,7 +177,7 @@ BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_ModelPostProcessor::Perform(
|
Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& /*theParameters*/)
|
const IMeshTools_Parameters& /*theParameters*/)
|
||||||
{
|
{
|
||||||
|
@@ -32,12 +32,14 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor();
|
Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor();
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
//! Performs processing of edges of the given model.
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform(
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -242,7 +242,7 @@ BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
|
|||||||
// Function: Perform
|
// Function: Perform
|
||||||
// Purpose :
|
// Purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Boolean BRepMesh_ModelPreProcessor::Perform(
|
Standard_Boolean BRepMesh_ModelPreProcessor::performInternal(
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters)
|
const IMeshTools_Parameters& theParameters)
|
||||||
{
|
{
|
||||||
|
@@ -33,12 +33,14 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor();
|
Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor();
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
//! Performs processing of edges of the given model.
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform(
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
const Handle(IMeshData_Model)& theModel,
|
const Handle(IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
const IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
22
src/BRepMesh/DELABELLA_LICENSE
Normal file
22
src/BRepMesh/DELABELLA_LICENSE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
DELABELLA - Delaunay triangulation library
|
||||||
|
Copyright (C) 2018 GUMIX - Marcin Sokalski
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
@@ -1,5 +1,6 @@
|
|||||||
BRepMesh_BaseMeshAlgo.cxx
|
BRepMesh_BaseMeshAlgo.cxx
|
||||||
BRepMesh_BaseMeshAlgo.hxx
|
BRepMesh_BaseMeshAlgo.hxx
|
||||||
|
BRepMesh_ConstrainedBaseMeshAlgo.hxx
|
||||||
BRepMesh_BoundaryParamsRangeSplitter.hxx
|
BRepMesh_BoundaryParamsRangeSplitter.hxx
|
||||||
BRepMesh_Circle.hxx
|
BRepMesh_Circle.hxx
|
||||||
BRepMesh_CircleInspector.hxx
|
BRepMesh_CircleInspector.hxx
|
||||||
@@ -83,3 +84,11 @@ BRepMesh_Vertex.hxx
|
|||||||
BRepMesh_VertexInspector.hxx
|
BRepMesh_VertexInspector.hxx
|
||||||
BRepMesh_VertexTool.cxx
|
BRepMesh_VertexTool.cxx
|
||||||
BRepMesh_VertexTool.hxx
|
BRepMesh_VertexTool.hxx
|
||||||
|
BRepMesh_CustomBaseMeshAlgo.hxx
|
||||||
|
BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
|
||||||
|
delabella.h
|
||||||
|
delabella.cpp
|
||||||
|
BRepMesh_DelabellaBaseMeshAlgo.hxx
|
||||||
|
BRepMesh_DelabellaBaseMeshAlgo.cxx
|
||||||
|
BRepMesh_DelabellaMeshAlgoFactory.hxx
|
||||||
|
BRepMesh_DelabellaMeshAlgoFactory.cxx
|
||||||
|
1021
src/BRepMesh/delabella.cpp
Normal file
1021
src/BRepMesh/delabella.cpp
Normal file
File diff suppressed because it is too large
Load Diff
68
src/BRepMesh/delabella.h
Normal file
68
src/BRepMesh/delabella.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
DELABELLA - Delaunay triangulation library
|
||||||
|
Copyright (C) 2018 GUMIX - Marcin Sokalski
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DELABELLA_H
|
||||||
|
#define DELABELLA_H
|
||||||
|
|
||||||
|
// returns: positive value: number of triangle indices, negative: number of line segment indices (degenerated input)
|
||||||
|
// triangle indices in abc array are always returned in clockwise order
|
||||||
|
// DEPRECIATED. move to new API either extern "C" or IDelaBella (C++)
|
||||||
|
int DelaBella(int points, const double* xy/*[points][2]*/, int* abc/*[2*points-5][3]*/, int (*errlog)(const char* fmt,...) = printf);
|
||||||
|
|
||||||
|
struct DelaBella_Vertex
|
||||||
|
{
|
||||||
|
int i; // index of original point
|
||||||
|
double x, y; // coordinates (input copy)
|
||||||
|
DelaBella_Vertex* next; // next silhouette vertex
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DelaBella_Triangle
|
||||||
|
{
|
||||||
|
DelaBella_Vertex* v[3]; // 3 vertices spanning this triangle
|
||||||
|
DelaBella_Triangle* f[3]; // 3 adjacent faces, f[i] is at the edge opposite to vertex v[i]
|
||||||
|
DelaBella_Triangle* next; // next triangle (of delaunay set or hull set)
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
struct IDelaBella
|
||||||
|
{
|
||||||
|
static IDelaBella* Create();
|
||||||
|
|
||||||
|
virtual void Destroy() = 0;
|
||||||
|
|
||||||
|
virtual void SetErrLog(int(*proc)(void* stream, const char* fmt, ...), void* stream) = 0;
|
||||||
|
|
||||||
|
// return 0: no output
|
||||||
|
// negative: all points are colinear, output hull vertices form colinear segment list, no triangles on output
|
||||||
|
// positive: output hull vertices form counter-clockwise ordered segment contour, delaunay and hull triangles are available
|
||||||
|
// if 'y' pointer is null, y coords are treated to be located immediately after every x
|
||||||
|
// if advance_bytes is less than 2*sizeof coordinate type, it is treated as 2*sizeof coordinate type
|
||||||
|
virtual int Triangulate(int points, const float* x, const float* y = 0, int advance_bytes = 0) = 0;
|
||||||
|
virtual int Triangulate(int points, const double* x, const double* y = 0, int advance_bytes = 0) = 0;
|
||||||
|
|
||||||
|
// num of points passed to last call to Triangulate()
|
||||||
|
virtual int GetNumInputPoints() const = 0;
|
||||||
|
|
||||||
|
// num of verts returned from last call to Triangulate()
|
||||||
|
virtual int GetNumOutputVerts() const = 0;
|
||||||
|
|
||||||
|
virtual const DelaBella_Triangle* GetFirstDelaunayTriangle() const = 0; // valid only if Triangulate() > 0
|
||||||
|
virtual const DelaBella_Triangle* GetFirstHullTriangle() const = 0; // valid only if Triangulate() > 0
|
||||||
|
virtual const DelaBella_Vertex* GetFirstHullVertex() const = 0; // if Triangulate() < 0 it is list, otherwise closed contour!
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
void* DelaBella_Create();
|
||||||
|
void DelaBella_Destroy(void* db);
|
||||||
|
void DelaBella_SetErrLog(void* db, int(*proc)(void* stream, const char* fmt, ...), void* stream);
|
||||||
|
int DelaBella_TriangulateFloat(void* db, int points, float* x, float* y = 0, int advance_bytes = 0);
|
||||||
|
int DelaBella_TriangulateDouble(void* db, int points, double* x, double* y = 0, int advance_bytes = 0);
|
||||||
|
int DelaBella_GetNumInputPoints(void* db);
|
||||||
|
int DelaBella_GetNumOutputVerts(void* db);
|
||||||
|
const DelaBella_Triangle* GetFirstDelaunayTriangle(void* db);
|
||||||
|
const DelaBella_Triangle* GetFirstHullTriangle(void* db);
|
||||||
|
const DelaBella_Vertex* GetFirstHullVertex(void* db);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@@ -17,6 +17,7 @@
|
|||||||
#include <gp_Pnt2d.hxx>
|
#include <gp_Pnt2d.hxx>
|
||||||
#include <BRepMesh_OrientedEdge.hxx>
|
#include <BRepMesh_OrientedEdge.hxx>
|
||||||
#include <BRepMesh_Vertex.hxx>
|
#include <BRepMesh_Vertex.hxx>
|
||||||
|
#include <Standard_OutOfRange.hxx>
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
// Function: Constructor
|
// Function: Constructor
|
||||||
@@ -74,6 +75,9 @@ void BRepMeshData_PCurve::AddPoint (
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
|
gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
|
||||||
{
|
{
|
||||||
|
Standard_OutOfRange_Raise_if (
|
||||||
|
theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myPoints2d.size()),
|
||||||
|
"BRepMeshData_PCurve::GetPoint");
|
||||||
return myPoints2d[theIndex];
|
return myPoints2d[theIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +87,9 @@ gp_Pnt2d& BRepMeshData_PCurve::GetPoint (const Standard_Integer theIndex)
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
|
Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
|
||||||
{
|
{
|
||||||
|
Standard_OutOfRange_Raise_if (
|
||||||
|
theIndex < 0 || theIndex >= static_cast<Standard_Integer>(myIndices.size()),
|
||||||
|
"BRepMeshData_PCurve::GetIndex");
|
||||||
return myIndices[theIndex];
|
return myIndices[theIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +99,9 @@ Standard_Integer& BRepMeshData_PCurve::GetIndex(const Standard_Integer theIndex)
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
|
Standard_Real& BRepMeshData_PCurve::GetParameter (const Standard_Integer theIndex)
|
||||||
{
|
{
|
||||||
|
Standard_OutOfRange_Raise_if (
|
||||||
|
theIndex < 0 || theIndex >= ParametersNb(),
|
||||||
|
"BRepMeshData_PCurve::GetParameter");
|
||||||
return myParameters[theIndex];
|
return myParameters[theIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1486,7 +1486,9 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
|
|||||||
"\n\t\t: -noTriangulation Force use of exact geometry for calculation"
|
"\n\t\t: -noTriangulation Force use of exact geometry for calculation"
|
||||||
"\n\t\t: even if triangulation is present."
|
"\n\t\t: even if triangulation is present."
|
||||||
"\n\t\t: -optimal Force calculation of optimal (more tight) AABB."
|
"\n\t\t: -optimal Force calculation of optimal (more tight) AABB."
|
||||||
"\n\t\t: In case of OBB, applies to initial AABB used in OBB calculation."
|
"\n\t\t: In case of OBB:"
|
||||||
|
"\n\t\t: - for PCA approach applies to initial AABB used in OBB calculation"
|
||||||
|
"\n\t\t: - for DiTo approach modifies the DiTo algorithm to check more axes."
|
||||||
"\n\t\t: -extToler Include tolerance of the shape in the resulting box."
|
"\n\t\t: -extToler Include tolerance of the shape in the resulting box."
|
||||||
"\n\t\t:"
|
"\n\t\t:"
|
||||||
"\n\t\t: Output options:"
|
"\n\t\t: Output options:"
|
||||||
|
@@ -14,11 +14,177 @@
|
|||||||
|
|
||||||
#include <Bnd_OBB.hxx>
|
#include <Bnd_OBB.hxx>
|
||||||
|
|
||||||
#include <Bnd_B3d.hxx>
|
#include <Bnd_Tools.hxx>
|
||||||
|
#include <Bnd_Range.hxx>
|
||||||
|
|
||||||
|
#include <BVH_BoxSet.hxx>
|
||||||
|
#include <BVH_LinearBuilder.hxx>
|
||||||
|
|
||||||
|
#include <BVH_Traverse.hxx>
|
||||||
|
|
||||||
#include <NCollection_Array1.hxx>
|
#include <NCollection_Array1.hxx>
|
||||||
#include <Precision.hxx>
|
#include <Precision.hxx>
|
||||||
#include <TColStd_Array1OfReal.hxx>
|
#include <TColStd_Array1OfReal.hxx>
|
||||||
|
|
||||||
|
//! Auxiliary class to select from the points stored in
|
||||||
|
//! BVH tree the two points giving the extreme projection
|
||||||
|
//! parameters on the axis
|
||||||
|
class OBB_ExtremePointsSelector :
|
||||||
|
public BVH_Traverse <Standard_Real, 3, BVH_BoxSet <Standard_Real, 3, gp_XYZ>, Bnd_Range>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor
|
||||||
|
OBB_ExtremePointsSelector() :
|
||||||
|
BVH_Traverse <Standard_Real, 3, BVH_BoxSet <Standard_Real, 3, gp_XYZ>, Bnd_Range>(),
|
||||||
|
myPrmMin (RealLast()),
|
||||||
|
myPrmMax (RealFirst())
|
||||||
|
{}
|
||||||
|
|
||||||
|
public: //! @name Set axis for projection
|
||||||
|
|
||||||
|
//! Sets the axis
|
||||||
|
void SetAxis (const gp_XYZ& theAxis) { myAxis = theAxis; }
|
||||||
|
|
||||||
|
public: //! @name Clears the points from previous runs
|
||||||
|
|
||||||
|
//! Clear
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
myPrmMin = RealLast();
|
||||||
|
myPrmMax = RealFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public: //! @name Getting the results
|
||||||
|
|
||||||
|
//! Returns the minimal projection parameter
|
||||||
|
Standard_Real MinPrm() const { return myPrmMin; }
|
||||||
|
|
||||||
|
//! Returns the maximal projection parameter
|
||||||
|
Standard_Real MaxPrm() const { return myPrmMax; }
|
||||||
|
|
||||||
|
//! Returns the minimal projection point
|
||||||
|
const gp_XYZ& MinPnt() const { return myPntMin; }
|
||||||
|
|
||||||
|
//! Returns the maximal projection point
|
||||||
|
const gp_XYZ& MaxPnt() const { return myPntMax; }
|
||||||
|
|
||||||
|
public: //! @name Definition of rejection/acceptance rules
|
||||||
|
|
||||||
|
//! Defines the rules for node rejection
|
||||||
|
virtual Standard_Boolean RejectNode (const BVH_Vec3d& theCMin,
|
||||||
|
const BVH_Vec3d& theCMax,
|
||||||
|
Bnd_Range& theMetric) const Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
if (myPrmMin > myPrmMax)
|
||||||
|
// No parameters computed yet
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
Standard_Real aPrmMin = myPrmMin, aPrmMax = myPrmMax;
|
||||||
|
Standard_Boolean isToReject = Standard_True;
|
||||||
|
|
||||||
|
// Check if the current node is between already found parameters
|
||||||
|
for (Standard_Integer i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
Standard_Real x = !i ? theCMin.x() : theCMax.x();
|
||||||
|
for (Standard_Integer j = 0; j < 2; ++j)
|
||||||
|
{
|
||||||
|
Standard_Real y = !j ? theCMin.y() : theCMax.y();
|
||||||
|
for (Standard_Integer k = 0; k < 2; ++k)
|
||||||
|
{
|
||||||
|
Standard_Real z = !k ? theCMin.z() : theCMax.z();
|
||||||
|
|
||||||
|
Standard_Real aPrm = myAxis.Dot (gp_XYZ (x, y, z));
|
||||||
|
if (aPrm < aPrmMin)
|
||||||
|
{
|
||||||
|
aPrmMin = aPrm;
|
||||||
|
isToReject = Standard_False;
|
||||||
|
}
|
||||||
|
else if (aPrm > aPrmMax)
|
||||||
|
{
|
||||||
|
aPrmMax = aPrm;
|
||||||
|
isToReject = Standard_False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theMetric = Bnd_Range (aPrmMin, aPrmMax);
|
||||||
|
|
||||||
|
return isToReject;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Rules for node rejection by the metric
|
||||||
|
virtual Standard_Boolean RejectMetric (const Bnd_Range& theMetric) const Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
if (myPrmMin > myPrmMax)
|
||||||
|
// no parameters computed
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
Standard_Real aMin, aMax;
|
||||||
|
if (!theMetric.GetBounds (aMin, aMax))
|
||||||
|
// void metric
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
// Check if the box of the branch is inside of the already computed parameters
|
||||||
|
return aMin > myPrmMin && aMax < myPrmMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Defines the rules for leaf acceptance
|
||||||
|
virtual Standard_Boolean Accept (const Standard_Integer theIndex,
|
||||||
|
const Bnd_Range&) Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
const gp_XYZ& theLeaf = myBVHSet->Element (theIndex);
|
||||||
|
Standard_Real aPrm = myAxis.Dot (theLeaf);
|
||||||
|
if (aPrm < myPrmMin)
|
||||||
|
{
|
||||||
|
myPrmMin = aPrm;
|
||||||
|
myPntMin = theLeaf;
|
||||||
|
}
|
||||||
|
if (aPrm > myPrmMax)
|
||||||
|
{
|
||||||
|
myPrmMax = aPrm;
|
||||||
|
myPntMax = theLeaf;
|
||||||
|
}
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
public: //! @name Choosing the best branch
|
||||||
|
|
||||||
|
//! Returns true if the metric of the left branch is better than the metric of the right
|
||||||
|
virtual Standard_Boolean IsMetricBetter (const Bnd_Range& theLeft,
|
||||||
|
const Bnd_Range& theRight) const Standard_OVERRIDE
|
||||||
|
{
|
||||||
|
if (myPrmMin > myPrmMax)
|
||||||
|
// no parameters computed
|
||||||
|
return Standard_True;
|
||||||
|
|
||||||
|
Standard_Real aMin[2], aMax[2];
|
||||||
|
if (!theLeft.GetBounds (aMin[0], aMax[0]) ||
|
||||||
|
!theRight.GetBounds (aMin[1], aMax[1]))
|
||||||
|
// void metrics
|
||||||
|
return Standard_True;
|
||||||
|
|
||||||
|
// Choose branch with larger extension over computed parameters
|
||||||
|
Standard_Real anExt[2] = {0.0, 0.0};
|
||||||
|
for (int i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
if (aMin[i] < myPrmMin) anExt[i] += myPrmMin - aMin[i];
|
||||||
|
if (aMax[i] > myPrmMax) anExt[i] += aMax[i] - myPrmMax;
|
||||||
|
}
|
||||||
|
return anExt[0] > anExt[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected: //! @name Fields
|
||||||
|
|
||||||
|
gp_XYZ myAxis; //!< Axis to project the points to
|
||||||
|
Standard_Real myPrmMin; //!< Minimal projection parameter
|
||||||
|
Standard_Real myPrmMax; //!< Maximal projection parameter
|
||||||
|
gp_XYZ myPntMin; //!< Minimal projection point
|
||||||
|
gp_XYZ myPntMax; //!< Maximal projection point
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Tool for OBB construction
|
||||||
class OBBTool
|
class OBBTool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -31,7 +197,8 @@ public:
|
|||||||
//! must be available during all time of OBB creation
|
//! must be available during all time of OBB creation
|
||||||
//! (i.e. while the object of OBBTool exists).
|
//! (i.e. while the object of OBBTool exists).
|
||||||
OBBTool(const TColgp_Array1OfPnt& theL,
|
OBBTool(const TColgp_Array1OfPnt& theL,
|
||||||
const TColStd_Array1OfReal *theLT = 0);
|
const TColStd_Array1OfReal *theLT = 0,
|
||||||
|
Standard_Boolean theIsOptimal = Standard_False);
|
||||||
|
|
||||||
//! DiTO algorithm for OBB construction
|
//! DiTO algorithm for OBB construction
|
||||||
//! (http://www.idt.mdh.se/~tla/publ/FastOBBs.pdf)
|
//! (http://www.idt.mdh.se/~tla/publ/FastOBBs.pdf)
|
||||||
@@ -41,6 +208,10 @@ public:
|
|||||||
void BuildBox(Bnd_OBB& theBox);
|
void BuildBox(Bnd_OBB& theBox);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
// Computes the extreme points on the set of Initial axes
|
||||||
|
void ComputeExtremePoints ();
|
||||||
|
|
||||||
//! Works with the triangle set by the points in myTriIdx.
|
//! Works with the triangle set by the points in myTriIdx.
|
||||||
//! If theIsBuiltTrg == TRUE, new set of triangles will be
|
//! If theIsBuiltTrg == TRUE, new set of triangles will be
|
||||||
//! recomputed.
|
//! recomputed.
|
||||||
@@ -71,6 +242,106 @@ protected:
|
|||||||
OBBTool& operator=(const OBBTool&);
|
OBBTool& operator=(const OBBTool&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//! Params structure stores the two values meaning
|
||||||
|
//! min and max parameters on the axis
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
Params() :
|
||||||
|
_ParamMin(RealLast()), _ParamMax(RealFirst())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Params(Standard_Real theMin, Standard_Real theMax)
|
||||||
|
: _ParamMin(theMin), _ParamMax(theMax)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Standard_Real _ParamMin;
|
||||||
|
Standard_Real _ParamMax;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Computes the Minimal and maximal parameters on the vector
|
||||||
|
//! connecting the points myLExtremalPoints[theId1] and myLExtremalPoints[theId2]
|
||||||
|
void ComputeParams (const Standard_Integer theId1,
|
||||||
|
const Standard_Integer theId2,
|
||||||
|
Standard_Real &theMin,
|
||||||
|
Standard_Real &theMax)
|
||||||
|
{
|
||||||
|
theMin = myParams[theId1][theId2]._ParamMin;
|
||||||
|
theMax = myParams[theId1][theId2]._ParamMax;
|
||||||
|
|
||||||
|
if (theMin > theMax)
|
||||||
|
{
|
||||||
|
FindMinMax ((myLExtremalPoints[theId1] - myLExtremalPoints[theId2]).Normalized(), theMin, theMax);
|
||||||
|
myParams[theId1][theId2]._ParamMin = myParams[theId2][theId1]._ParamMin = theMin;
|
||||||
|
myParams[theId1][theId2]._ParamMax = myParams[theId2][theId1]._ParamMax = theMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Looks for the min-max parameters on the axis.
|
||||||
|
//! For optimal case projects all the points on the axis,
|
||||||
|
//! for not optimal - only the set of extreme points.
|
||||||
|
void FindMinMax (const gp_XYZ& theAxis,
|
||||||
|
Standard_Real &theMin,
|
||||||
|
Standard_Real &theMax)
|
||||||
|
{
|
||||||
|
theMin = RealLast(), theMax = RealFirst();
|
||||||
|
|
||||||
|
if (myOptimal)
|
||||||
|
Project (theAxis, theMin, theMax);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = 0; i < myNbExtremalPoints; ++i)
|
||||||
|
{
|
||||||
|
Standard_Real aPrm = theAxis.Dot (myLExtremalPoints[i]);
|
||||||
|
if (aPrm < theMin) theMin = aPrm;
|
||||||
|
if (aPrm > theMax) theMax = aPrm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Projects the set of points on the axis
|
||||||
|
void Project (const gp_XYZ& theAxis,
|
||||||
|
Standard_Real& theMin, Standard_Real& theMax,
|
||||||
|
gp_XYZ* thePntMin = 0, gp_XYZ* thePntMax = 0)
|
||||||
|
{
|
||||||
|
theMin = RealLast(), theMax = RealFirst();
|
||||||
|
|
||||||
|
if (myOptimal)
|
||||||
|
{
|
||||||
|
// Project BVH
|
||||||
|
OBB_ExtremePointsSelector anExtremePointsSelector;
|
||||||
|
anExtremePointsSelector.SetBVHSet (myPointBoxSet.get());
|
||||||
|
anExtremePointsSelector.SetAxis (theAxis);
|
||||||
|
anExtremePointsSelector.Select();
|
||||||
|
theMin = anExtremePointsSelector.MinPrm();
|
||||||
|
theMax = anExtremePointsSelector.MaxPrm();
|
||||||
|
if (thePntMin) *thePntMin = anExtremePointsSelector.MinPnt();
|
||||||
|
if (thePntMax) *thePntMax = anExtremePointsSelector.MaxPnt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project all points
|
||||||
|
for (Standard_Integer iP = myPntsList.Lower(); iP <= myPntsList.Upper(); ++iP)
|
||||||
|
{
|
||||||
|
const gp_XYZ& aPoint = myPntsList(iP).XYZ();
|
||||||
|
const Standard_Real aPrm = theAxis.Dot (aPoint);
|
||||||
|
if (aPrm < theMin)
|
||||||
|
{
|
||||||
|
theMin = aPrm;
|
||||||
|
if (thePntMin)
|
||||||
|
*thePntMin = aPoint;
|
||||||
|
}
|
||||||
|
if (aPrm > theMax)
|
||||||
|
{
|
||||||
|
theMax = aPrm;
|
||||||
|
if (thePntMax)
|
||||||
|
*thePntMax = aPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
//! Number of the initial axes.
|
//! Number of the initial axes.
|
||||||
static const Standard_Integer myNbInitAxes = 7;
|
static const Standard_Integer myNbInitAxes = 7;
|
||||||
|
|
||||||
@@ -96,6 +367,16 @@ private:
|
|||||||
|
|
||||||
//! The surface area of the OBB
|
//! The surface area of the OBB
|
||||||
Standard_Real myQualityCriterion;
|
Standard_Real myQualityCriterion;
|
||||||
|
|
||||||
|
//! Defines if the OBB should be computed more tight.
|
||||||
|
//! Takes more time, but the volume is less.
|
||||||
|
Standard_Boolean myOptimal;
|
||||||
|
|
||||||
|
//! Point box set organized with BVH
|
||||||
|
opencascade::handle<BVH_BoxSet <Standard_Real, 3, gp_XYZ>> myPointBoxSet;
|
||||||
|
|
||||||
|
//! Stored min/max parameters for the axes between extremal points
|
||||||
|
Params myParams[myNbExtremalPoints][myNbExtremalPoints];
|
||||||
};
|
};
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -110,7 +391,7 @@ static inline void SetMinMax(Standard_Real* const thePrmArr,
|
|||||||
{
|
{
|
||||||
thePrmArr[0] = theNewParam;
|
thePrmArr[0] = theNewParam;
|
||||||
}
|
}
|
||||||
else if(theNewParam > thePrmArr[1])
|
if(theNewParam > thePrmArr[1])
|
||||||
{
|
{
|
||||||
thePrmArr[1] = theNewParam;
|
thePrmArr[1] = theNewParam;
|
||||||
}
|
}
|
||||||
@@ -122,68 +403,92 @@ static inline void SetMinMax(Standard_Real* const thePrmArr,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
OBBTool::
|
OBBTool::
|
||||||
OBBTool(const TColgp_Array1OfPnt& theL,
|
OBBTool(const TColgp_Array1OfPnt& theL,
|
||||||
const TColStd_Array1OfReal *theLT) :myPntsList(theL),
|
const TColStd_Array1OfReal *theLT,
|
||||||
|
const Standard_Boolean theIsOptimal) : myPntsList(theL),
|
||||||
myListOfTolers(theLT),
|
myListOfTolers(theLT),
|
||||||
myQualityCriterion(RealLast())
|
myQualityCriterion(RealLast()),
|
||||||
|
myOptimal (theIsOptimal)
|
||||||
{
|
{
|
||||||
const Standard_Real aSqrt3 = Sqrt(3);
|
if (myOptimal)
|
||||||
// Origin of all initial axis is (0,0,0).
|
|
||||||
// All axes must be normalized.
|
|
||||||
const gp_XYZ anInitialAxesArray[myNbInitAxes] = {gp_XYZ(1.0, 0.0, 0.0),
|
|
||||||
gp_XYZ(0.0, 1.0, 0.0),
|
|
||||||
gp_XYZ(0.0, 0.0, 1.0),
|
|
||||||
gp_XYZ(1.0, 1.0, 1.0) / aSqrt3,
|
|
||||||
gp_XYZ(1.0, 1.0, -1.0) / aSqrt3,
|
|
||||||
gp_XYZ(1.0, -1.0, 1.0) / aSqrt3,
|
|
||||||
gp_XYZ(1.0, -1.0, -1.0) / aSqrt3};
|
|
||||||
|
|
||||||
// Minimal and maximal point on every axis
|
|
||||||
const Standard_Integer aNbPoints = 2 * myNbInitAxes;
|
|
||||||
|
|
||||||
for(Standard_Integer i = 0; i < 5; i++)
|
|
||||||
{
|
{
|
||||||
myTriIdx[i] = INT_MAX;
|
// Use linear builder for BVH construction with 30 elements in the leaf
|
||||||
|
opencascade::handle<BVH_LinearBuilder<Standard_Real, 3> > aLBuilder =
|
||||||
|
new BVH_LinearBuilder<Standard_Real, 3> (30);
|
||||||
|
myPointBoxSet = new BVH_BoxSet <Standard_Real, 3, gp_XYZ> (aLBuilder);
|
||||||
|
myPointBoxSet->SetSize(myPntsList.Length());
|
||||||
|
|
||||||
|
// Add the points into Set
|
||||||
|
for (Standard_Integer iP = 0; iP < theL.Length(); ++iP)
|
||||||
|
{
|
||||||
|
const gp_Pnt& aP = theL (iP);
|
||||||
|
Standard_Real aTol = theLT ? theLT->Value(iP) : Precision::Confusion();
|
||||||
|
BVH_Box <Standard_Real, 3> aBox (BVH_Vec3d (aP.X() - aTol, aP.Y() - aTol, aP.Z() - aTol),
|
||||||
|
BVH_Vec3d (aP.X() + aTol, aP.Y() + aTol, aP.Z() + aTol));
|
||||||
|
myPointBoxSet->Add (aP.XYZ(), aBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myPointBoxSet->Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
ComputeExtremePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Function : ComputeExtremePoints
|
||||||
|
// purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void OBBTool::ComputeExtremePoints()
|
||||||
|
{
|
||||||
|
// Six initial axes show great quality on the Optimal OBB, plus
|
||||||
|
// the performance is better (due to the less number of operations).
|
||||||
|
// But they show worse quality for the not optimal approach.
|
||||||
|
//const Standard_Real a = (sqrt(5) - 1) / 2.;
|
||||||
|
//const gp_XYZ anInitialAxes6[myNbInitAxes] = { gp_XYZ (0, 1, a),
|
||||||
|
// gp_XYZ (0, 1, -a),
|
||||||
|
// gp_XYZ (1, a, 0),
|
||||||
|
// gp_XYZ (1, -a, 0),
|
||||||
|
// gp_XYZ (a, 0, 1),
|
||||||
|
// gp_XYZ (a, 0, -1) };
|
||||||
|
const Standard_Real aSqrt3 = Sqrt(3);
|
||||||
|
const gp_XYZ anInitialAxes7[myNbInitAxes] = { gp_XYZ (1.0, 0.0, 0.0),
|
||||||
|
gp_XYZ (0.0, 1.0, 0.0),
|
||||||
|
gp_XYZ (0.0, 0.0, 1.0),
|
||||||
|
gp_XYZ (1.0, 1.0, 1.0) / aSqrt3,
|
||||||
|
gp_XYZ (1.0, 1.0, -1.0) / aSqrt3,
|
||||||
|
gp_XYZ (1.0, -1.0, 1.0) / aSqrt3,
|
||||||
|
gp_XYZ (1.0, -1.0, -1.0) / aSqrt3 };
|
||||||
|
|
||||||
|
// Set of initial axes
|
||||||
|
const gp_XYZ *anInitialAxesArray = anInitialAxes7;
|
||||||
|
|
||||||
// Min and Max parameter
|
// Min and Max parameter
|
||||||
Standard_Real aParams[aNbPoints];
|
Standard_Real aParams[myNbExtremalPoints];
|
||||||
for(Standard_Integer i = 0; i < aNbPoints; i += 2)
|
|
||||||
{
|
|
||||||
aParams[i] = RealLast();
|
|
||||||
aParams[i + 1] = RealFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for the extremal points (myLExtremalPoints)
|
// Look for the extremal points (myLExtremalPoints)
|
||||||
for(Standard_Integer i = myPntsList.Lower() ; i <= myPntsList.Upper(); i++)
|
for (Standard_Integer anAxeInd = 0, aPrmInd = -1; anAxeInd < myNbInitAxes; ++anAxeInd)
|
||||||
{
|
{
|
||||||
const gp_XYZ &aCurrPoint = myPntsList(i).XYZ();
|
Standard_Integer aMinInd = ++aPrmInd, aMaxInd = ++aPrmInd;
|
||||||
for(Standard_Integer anAxeInd = 0, aPrmInd = 0; anAxeInd < myNbInitAxes; anAxeInd++, aPrmInd++)
|
aParams[aMinInd] = RealLast();
|
||||||
{
|
aParams[aMaxInd] = -RealLast();
|
||||||
const Standard_Real aParam = aCurrPoint.Dot(anInitialAxesArray[anAxeInd]);
|
Project (anInitialAxesArray[anAxeInd],
|
||||||
if(aParam < aParams[aPrmInd])
|
aParams[aMinInd], aParams[aMaxInd],
|
||||||
{
|
&myLExtremalPoints[aMinInd], &myLExtremalPoints[aMaxInd]);
|
||||||
myLExtremalPoints[aPrmInd] = aCurrPoint;
|
|
||||||
aParams[aPrmInd] = aParam;
|
|
||||||
}
|
}
|
||||||
aPrmInd++;
|
|
||||||
|
|
||||||
if(aParam > aParams[aPrmInd])
|
// For not optimal box it is necessary to compute the max axis
|
||||||
|
// created by the maximally distant extreme points
|
||||||
|
if (!myOptimal)
|
||||||
{
|
{
|
||||||
myLExtremalPoints[aPrmInd] = aCurrPoint;
|
for(Standard_Integer i = 0; i < 5; i++)
|
||||||
aParams[aPrmInd] = aParam;
|
myTriIdx[i] = INT_MAX;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute myTriIdx[0] and myTriIdx[1].
|
// Compute myTriIdx[0] and myTriIdx[1].
|
||||||
|
|
||||||
Standard_Real aMaxSqDist = -1.0;
|
Standard_Real aMaxSqDist = -1.0;
|
||||||
for(Standard_Integer aPrmInd = 0; aPrmInd < aNbPoints; aPrmInd += 2)
|
for (Standard_Integer aPrmInd = 0; aPrmInd < myNbExtremalPoints; aPrmInd += 2)
|
||||||
{
|
{
|
||||||
const gp_Pnt &aP1 = myLExtremalPoints[aPrmInd],
|
const gp_Pnt &aP1 = myLExtremalPoints[aPrmInd],
|
||||||
&aP2 = myLExtremalPoints[aPrmInd + 1];
|
&aP2 = myLExtremalPoints[aPrmInd + 1];
|
||||||
const Standard_Real aSqDist = aP1.SquareDistance(aP2);
|
const Standard_Real aSqDist = aP1.SquareDistance(aP2);
|
||||||
if(aSqDist > aMaxSqDist)
|
if (aSqDist > aMaxSqDist)
|
||||||
{
|
{
|
||||||
aMaxSqDist = aSqDist;
|
aMaxSqDist = aSqDist;
|
||||||
myTriIdx[0] = aPrmInd;
|
myTriIdx[0] = aPrmInd;
|
||||||
@@ -191,7 +496,9 @@ OBBTool::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the maximal axis orthogonal to the found one
|
||||||
FillToTriangle3();
|
FillToTriangle3();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -233,6 +540,7 @@ void OBBTool::FillToTriangle5(const gp_XYZ& theNormal,
|
|||||||
const gp_XYZ& theBarryCenter)
|
const gp_XYZ& theBarryCenter)
|
||||||
{
|
{
|
||||||
Standard_Real aParams[2] = {0.0, 0.0};
|
Standard_Real aParams[2] = {0.0, 0.0};
|
||||||
|
Standard_Integer id3 = -1, id4 = -1;
|
||||||
|
|
||||||
for(Standard_Integer aPtIdx = 0; aPtIdx < myNbExtremalPoints; aPtIdx++)
|
for(Standard_Integer aPtIdx = 0; aPtIdx < myNbExtremalPoints; aPtIdx++)
|
||||||
{
|
{
|
||||||
@@ -242,28 +550,24 @@ void OBBTool::FillToTriangle5(const gp_XYZ& theNormal,
|
|||||||
const gp_XYZ &aCurrPoint = myLExtremalPoints[aPtIdx];
|
const gp_XYZ &aCurrPoint = myLExtremalPoints[aPtIdx];
|
||||||
const Standard_Real aParam = theNormal.Dot(aCurrPoint - theBarryCenter);
|
const Standard_Real aParam = theNormal.Dot(aCurrPoint - theBarryCenter);
|
||||||
|
|
||||||
if(aParam < aParams[0])
|
if (aParam < aParams[0])
|
||||||
{
|
{
|
||||||
myTriIdx[3] = aPtIdx;
|
id3 = aPtIdx;
|
||||||
aParams[0] = aParam;
|
aParams[0] = aParam;
|
||||||
}
|
}
|
||||||
else if(aParam > aParams[1])
|
else if (aParam > aParams[1])
|
||||||
{
|
{
|
||||||
myTriIdx[4] = aPtIdx;
|
id4 = aPtIdx;
|
||||||
aParams[1] = aParam;
|
aParams[1] = aParam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The points must be in the different sides of the triangle plane.
|
// The points must be in the different sides of the triangle plane.
|
||||||
if(aParams[0] > -Precision::Confusion())
|
if (id3 >= 0 && aParams[0] < -Precision::Confusion())
|
||||||
{
|
myTriIdx[3] = id3;
|
||||||
myTriIdx[3] = INT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(aParams[1] < Precision::Confusion())
|
if (id4 >= 0 && aParams[1] > Precision::Confusion())
|
||||||
{
|
myTriIdx[4] = id4;
|
||||||
myTriIdx[4] = INT_MAX;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -279,71 +583,60 @@ void OBBTool::ProcessTriangle(const Standard_Integer theIdx1,
|
|||||||
{
|
{
|
||||||
const Standard_Integer aNbAxes = 3;
|
const Standard_Integer aNbAxes = 3;
|
||||||
|
|
||||||
//Some vertex of the triangle
|
|
||||||
const gp_XYZ aP0 = myLExtremalPoints[theIdx1];
|
|
||||||
|
|
||||||
// All axes must be normalized in order to provide correct area computation
|
// All axes must be normalized in order to provide correct area computation
|
||||||
// (see ComputeQuality(...) method).
|
// (see ComputeQuality(...) method).
|
||||||
gp_XYZ aYAxis[aNbAxes] = {(myLExtremalPoints[theIdx2] - myLExtremalPoints[theIdx1]),
|
int ID1[3] = { theIdx2, theIdx3, theIdx1 },
|
||||||
(myLExtremalPoints[theIdx3] - myLExtremalPoints[theIdx2]),
|
ID2[3] = { theIdx1, theIdx2, theIdx3 };
|
||||||
(myLExtremalPoints[theIdx1] - myLExtremalPoints[theIdx3])};
|
gp_XYZ aYAxis[aNbAxes] = {(myLExtremalPoints[ID1[0]] - myLExtremalPoints[ID2[0]]),
|
||||||
|
(myLExtremalPoints[ID1[1]] - myLExtremalPoints[ID2[1]]),
|
||||||
|
(myLExtremalPoints[ID1[2]] - myLExtremalPoints[ID2[2]])};
|
||||||
|
|
||||||
// Normal to the triangle plane
|
// Normal to the triangle plane
|
||||||
gp_XYZ aZAxis = aYAxis[0].Crossed(aYAxis[1]);
|
gp_XYZ aZAxis = aYAxis[0].Crossed(aYAxis[1]);
|
||||||
|
|
||||||
Standard_Real aSqMod = aZAxis.SquareModulus();
|
Standard_Real aSqMod = aZAxis.SquareModulus();
|
||||||
|
|
||||||
if(aSqMod < Precision::SquareConfusion())
|
if (aSqMod < Precision::SquareConfusion())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aZAxis /= Sqrt(aSqMod);
|
aZAxis /= Sqrt(aSqMod);
|
||||||
|
|
||||||
gp_XYZ aXAxis[aNbAxes];
|
gp_XYZ aXAxis[aNbAxes];
|
||||||
for(Standard_Integer i = 0; i < aNbAxes; i++)
|
for (Standard_Integer i = 0; i < aNbAxes; i++)
|
||||||
{
|
|
||||||
aXAxis[i] = aYAxis[i].Crossed(aZAxis).Normalized();
|
aXAxis[i] = aYAxis[i].Crossed(aZAxis).Normalized();
|
||||||
aYAxis[i].Normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(theIsBuiltTrg)
|
if (theIsBuiltTrg)
|
||||||
FillToTriangle5(aZAxis, aP0);
|
FillToTriangle5 (aZAxis, myLExtremalPoints[theIdx1]);
|
||||||
|
|
||||||
// Min and Max parameter
|
// Min and Max parameter
|
||||||
const Standard_Integer aNbPoints = 2 * aNbAxes;
|
const Standard_Integer aNbPoints = 2 * aNbAxes;
|
||||||
|
|
||||||
|
// Compute Min/Max params for ZAxis
|
||||||
|
Standard_Real aParams[aNbPoints];
|
||||||
|
FindMinMax (aZAxis, aParams[4], aParams[5]); // Compute params on ZAxis once
|
||||||
|
|
||||||
Standard_Integer aMinIdx = -1;
|
Standard_Integer aMinIdx = -1;
|
||||||
for(Standard_Integer anAxeInd = 0; anAxeInd < aNbAxes; anAxeInd++)
|
for(Standard_Integer anAxeInd = 0; anAxeInd < aNbAxes; anAxeInd++)
|
||||||
{
|
{
|
||||||
const gp_XYZ &aAX = aXAxis[anAxeInd],
|
const gp_XYZ &aAX = aXAxis[anAxeInd];
|
||||||
&aAY = aYAxis[anAxeInd];
|
// Compute params on XAxis
|
||||||
|
FindMinMax (aAX, aParams[0], aParams[1]);
|
||||||
Standard_Real aParams[aNbPoints] = {0.0, 0.0, 0.0,
|
// Compute params on YAxis checking for stored values
|
||||||
0.0, 0.0, 0.0};
|
ComputeParams (ID1[anAxeInd], ID2[anAxeInd], aParams[2], aParams[3]);
|
||||||
|
|
||||||
for(Standard_Integer aPtIdx = 0; aPtIdx < myNbExtremalPoints; aPtIdx++)
|
|
||||||
{
|
|
||||||
if(aPtIdx == theIdx1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const gp_XYZ aCurrPoint = myLExtremalPoints[aPtIdx] - aP0;
|
|
||||||
SetMinMax(&aParams[0], aAX.Dot(aCurrPoint));
|
|
||||||
SetMinMax(&aParams[2], aAY.Dot(aCurrPoint));
|
|
||||||
SetMinMax(&aParams[4], aZAxis.Dot(aCurrPoint));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Standard_Real anArea = ComputeQuality(aParams);
|
const Standard_Real anArea = ComputeQuality(aParams);
|
||||||
if(anArea < myQualityCriterion)
|
if (anArea < myQualityCriterion)
|
||||||
{
|
{
|
||||||
myQualityCriterion = anArea;
|
myQualityCriterion = anArea;
|
||||||
aMinIdx = anAxeInd;
|
aMinIdx = anAxeInd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(aMinIdx < 0)
|
if (aMinIdx < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
myAxes[0] = aXAxis[aMinIdx];
|
myAxes[0] = aXAxis[aMinIdx];
|
||||||
myAxes[1] = aYAxis[aMinIdx];
|
myAxes[1] = aYAxis[aMinIdx].Normalized();
|
||||||
myAxes[2] = aZAxis;
|
myAxes[2] = aZAxis;
|
||||||
}
|
}
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -352,21 +645,42 @@ void OBBTool::ProcessTriangle(const Standard_Integer theIdx1,
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
void OBBTool::ProcessDiTetrahedron()
|
void OBBTool::ProcessDiTetrahedron()
|
||||||
{
|
{
|
||||||
|
// To compute the optimal OBB it is necessary to check all possible
|
||||||
|
// axes created by the extremal points. It is also necessary to project
|
||||||
|
// all the points on the axis, as for each different axis there will be
|
||||||
|
// different extremal points.
|
||||||
|
if (myOptimal)
|
||||||
|
{
|
||||||
|
for (Standard_Integer i = 0; i < myNbExtremalPoints - 2; i++)
|
||||||
|
{
|
||||||
|
for (Standard_Integer j = i + 1; j < myNbExtremalPoints - 1; j++)
|
||||||
|
{
|
||||||
|
for (Standard_Integer k = j + 1; k < myNbExtremalPoints; k++)
|
||||||
|
{
|
||||||
|
ProcessTriangle (i, j, k, Standard_False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the standard DiTo approach
|
||||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[2], Standard_True);
|
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[2], Standard_True);
|
||||||
|
|
||||||
if(myTriIdx[3] <= myNbExtremalPoints)
|
if (myTriIdx[3] <= myNbExtremalPoints)
|
||||||
{
|
{
|
||||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[3], Standard_False);
|
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[3], Standard_False);
|
||||||
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[3], Standard_False);
|
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||||
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[3], Standard_False);
|
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(myTriIdx[4] <= myNbExtremalPoints)
|
if (myTriIdx[4] <= myNbExtremalPoints)
|
||||||
{
|
{
|
||||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[4], Standard_False);
|
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[4], Standard_False);
|
||||||
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[4], Standard_False);
|
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[4], Standard_False);
|
||||||
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[4], Standard_False);
|
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[4], Standard_False);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -452,7 +766,8 @@ void OBBTool::BuildBox(Bnd_OBB& theBox)
|
|||||||
// purpose : http://www.idt.mdh.se/~tla/publ/
|
// purpose : http://www.idt.mdh.se/~tla/publ/
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Bnd_OBB::ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
void Bnd_OBB::ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
||||||
const TColStd_Array1OfReal *theListOfTolerances)
|
const TColStd_Array1OfReal *theListOfTolerances,
|
||||||
|
const Standard_Boolean theIsOptimal)
|
||||||
{
|
{
|
||||||
switch(theListOfPoints.Length())
|
switch(theListOfPoints.Length())
|
||||||
{
|
{
|
||||||
@@ -504,7 +819,7 @@ void Bnd_OBB::ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBBTool aTool(theListOfPoints, theListOfTolerances);
|
OBBTool aTool(theListOfPoints, theListOfTolerances, theIsOptimal);
|
||||||
aTool.ProcessDiTetrahedron();
|
aTool.ProcessDiTetrahedron();
|
||||||
aTool.BuildBox(*this);
|
aTool.BuildBox(*this);
|
||||||
}
|
}
|
||||||
|
@@ -95,12 +95,17 @@ public:
|
|||||||
myCenter.SetCoord(0.5*(aX2 + aX1), 0.5*(aY2 + aY1), 0.5*(aZ2 + aZ1));
|
myCenter.SetCoord(0.5*(aX2 + aX1), 0.5*(aY2 + aY1), 0.5*(aZ2 + aZ1));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Created new OBB covering every point in theListOfPoints.
|
//! Creates new OBB covering every point in theListOfPoints.
|
||||||
//! Tolerance of every such point is set by *theListOfTolerances array.
|
//! Tolerance of every such point is set by *theListOfTolerances array.
|
||||||
//! If this array is not void (not null-pointer) then the resulted Bnd_OBB
|
//! If this array is not void (not null-pointer) then the resulted Bnd_OBB
|
||||||
//! will be enlarged using tolerances of points lying on the box surface.
|
//! will be enlarged using tolerances of points lying on the box surface.
|
||||||
|
//! <theIsOptimal> flag defines the mode in which the OBB will be built.
|
||||||
|
//! Constructing Optimal box takes more time, but the resulting box is usually
|
||||||
|
//! more tight. In case of construction of Optimal OBB more possible
|
||||||
|
//! axes are checked.
|
||||||
Standard_EXPORT void ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
Standard_EXPORT void ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
||||||
const TColStd_Array1OfReal *theListOfTolerances = 0);
|
const TColStd_Array1OfReal *theListOfTolerances = 0,
|
||||||
|
const Standard_Boolean theIsOptimal = Standard_False);
|
||||||
|
|
||||||
//! Sets the center of OBB
|
//! Sets the center of OBB
|
||||||
void SetCenter(const gp_Pnt& theCenter)
|
void SetCenter(const gp_Pnt& theCenter)
|
||||||
|
@@ -362,6 +362,11 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
|
|||||||
#else
|
#else
|
||||||
di << "OpenGL: desktop\n";
|
di << "OpenGL: desktop\n";
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_RAPIDJSON
|
||||||
|
di << "RapidJSON enabled (HAVE_RAPIDJSON)\n";
|
||||||
|
#else
|
||||||
|
di << "RapidJSON disabled\n";
|
||||||
|
#endif
|
||||||
#ifdef HAVE_VTK
|
#ifdef HAVE_VTK
|
||||||
di << "VTK enabled (HAVE_VTK)\n";
|
di << "VTK enabled (HAVE_VTK)\n";
|
||||||
#else
|
#else
|
||||||
|
@@ -310,6 +310,23 @@ proc checkreal {name value expected tol_abs tol_rel} {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Procedure to check equality of two 3D points with tolerance
|
||||||
|
help checkpoint {
|
||||||
|
Compare two 3D points with given tolerance
|
||||||
|
Use: checkpoint name {valueX valueY valueZ} {expectedX expectedY expectedZ} tolerance
|
||||||
|
}
|
||||||
|
proc checkpoint {theName theValue theExpected theTolerance} {
|
||||||
|
set e 0.0001
|
||||||
|
foreach i {0 1 2} {
|
||||||
|
if { [expr abs([lindex $theValue $i] - [lindex $theExpected $i])] > $theTolerance } {
|
||||||
|
puts "Error: $theName, ($theValue) is not equal to expected ($theExpected)"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts "Check of $theName OK: value = ($theValue), expected = ($theExpected)"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
help checkfreebounds {
|
help checkfreebounds {
|
||||||
Compare number of free edges with ref_value
|
Compare number of free edges with ref_value
|
||||||
|
|
||||||
|
@@ -1298,23 +1298,23 @@ proc _run_test {scriptsdir group gridname casefile echo} {
|
|||||||
# execute test scripts
|
# execute test scripts
|
||||||
if { [file exists $scriptsdir/$group/begin] } {
|
if { [file exists $scriptsdir/$group/begin] } {
|
||||||
puts "Executing $scriptsdir/$group/begin..."; flush stdout
|
puts "Executing $scriptsdir/$group/begin..."; flush stdout
|
||||||
uplevel source $scriptsdir/$group/begin
|
uplevel source -encoding utf-8 $scriptsdir/$group/begin
|
||||||
}
|
}
|
||||||
if { [file exists $scriptsdir/$group/$gridname/begin] } {
|
if { [file exists $scriptsdir/$group/$gridname/begin] } {
|
||||||
puts "Executing $scriptsdir/$group/$gridname/begin..."; flush stdout
|
puts "Executing $scriptsdir/$group/$gridname/begin..."; flush stdout
|
||||||
uplevel source $scriptsdir/$group/$gridname/begin
|
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/begin
|
||||||
}
|
}
|
||||||
|
|
||||||
puts "Executing $casefile..."; flush stdout
|
puts "Executing $casefile..."; flush stdout
|
||||||
uplevel source $casefile
|
uplevel source -encoding utf-8 $casefile
|
||||||
|
|
||||||
if { [file exists $scriptsdir/$group/$gridname/end] } {
|
if { [file exists $scriptsdir/$group/$gridname/end] } {
|
||||||
puts "Executing $scriptsdir/$group/$gridname/end..."; flush stdout
|
puts "Executing $scriptsdir/$group/$gridname/end..."; flush stdout
|
||||||
uplevel source $scriptsdir/$group/$gridname/end
|
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/end
|
||||||
}
|
}
|
||||||
if { [file exists $scriptsdir/$group/end] } {
|
if { [file exists $scriptsdir/$group/end] } {
|
||||||
puts "Executing $scriptsdir/$group/end..."; flush stdout
|
puts "Executing $scriptsdir/$group/end..."; flush stdout
|
||||||
uplevel source $scriptsdir/$group/end
|
uplevel source -encoding utf-8 $scriptsdir/$group/end
|
||||||
}
|
}
|
||||||
} res] {
|
} res] {
|
||||||
puts "Tcl Exception: $res"
|
puts "Tcl Exception: $res"
|
||||||
|
@@ -78,13 +78,19 @@ proc dftree { DDF_Browser } {
|
|||||||
## ]
|
## ]
|
||||||
|
|
||||||
set w .$DDF_Browser
|
set w .$DDF_Browser
|
||||||
toplevel $w -height 400 -width 700 -background bisque3
|
toplevel $w -width 700 -height 400 -background bisque3
|
||||||
|
wm minsize $w 700 400
|
||||||
|
|
||||||
########
|
########
|
||||||
# Tree #
|
# Tree #
|
||||||
########
|
########
|
||||||
|
|
||||||
set tree1 [ttk::treeview $w.tree -show tree]
|
#set tree1 [ttk::treeview $w.tree -show tree]
|
||||||
|
set tree1 [ttk::treeview $w.tree -show tree -xscrollcommand "$w.tree.xscroll set" -yscrollcommand "$w.tree.yscroll set"]
|
||||||
|
set aScrollX [ttk::scrollbar $w.tree.xscroll -command "$w.tree xview" -orient horizontal]
|
||||||
|
set aScrollY [ttk::scrollbar $w.tree.yscroll -command "$w.tree yview"]
|
||||||
|
pack $aScrollX -side bottom -fill x
|
||||||
|
pack $aScrollY -side right -fill y
|
||||||
$tree1 tag bind Label <<TreeviewOpen>> [list DFTREE:Tree:Open $DDF_Browser $w]
|
$tree1 tag bind Label <<TreeviewOpen>> [list DFTREE:Tree:Open $DDF_Browser $w]
|
||||||
$tree1 tag configure Label -font 9x15bold -foreground DarkGreen
|
$tree1 tag configure Label -font 9x15bold -foreground DarkGreen
|
||||||
#$tree1 tag configure Attribute -font 9x15 -background bisque3
|
#$tree1 tag configure Attribute -font 9x15 -background bisque3
|
||||||
|
@@ -17,3 +17,4 @@ Font_SystemFont.cxx
|
|||||||
Font_SystemFont.hxx
|
Font_SystemFont.hxx
|
||||||
Font_TextFormatter.hxx
|
Font_TextFormatter.hxx
|
||||||
Font_TextFormatter.cxx
|
Font_TextFormatter.cxx
|
||||||
|
Font_UnicodeSubset.hxx
|
||||||
|
@@ -407,7 +407,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
|||||||
{
|
{
|
||||||
theShape.Nullify();
|
theShape.Nullify();
|
||||||
if (!loadGlyph (theChar)
|
if (!loadGlyph (theChar)
|
||||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||||
{
|
{
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
}
|
}
|
||||||
@@ -416,8 +416,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
|||||||
return !theShape.IsNull();
|
return !theShape.IsNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Outline& anOutline = myFTFace->glyph->outline;
|
const FT_Outline& anOutline = myActiveFTFace->glyph->outline;
|
||||||
|
|
||||||
if (!anOutline.n_contours)
|
if (!anOutline.n_contours)
|
||||||
return Standard_False;
|
return Standard_False;
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Message_Messenger.hxx>
|
#include <Message_Messenger.hxx>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
@@ -33,9 +35,12 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
|
|||||||
Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
||||||
: myFTLib (theFTLib),
|
: myFTLib (theFTLib),
|
||||||
myFTFace (NULL),
|
myFTFace (NULL),
|
||||||
|
myActiveFTFace(NULL),
|
||||||
|
myFontAspect (Font_FontAspect_Regular),
|
||||||
myWidthScaling(1.0),
|
myWidthScaling(1.0),
|
||||||
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
||||||
myUChar (0U)
|
myUChar (0U),
|
||||||
|
myToUseUnicodeSubsetFallback (Font_FontMgr::ToUseUnicodeSubsetFallback())
|
||||||
{
|
{
|
||||||
if (myFTLib.IsNull())
|
if (myFTLib.IsNull())
|
||||||
{
|
{
|
||||||
@@ -66,6 +71,7 @@ void Font_FTFont::Release()
|
|||||||
FT_Done_Face (myFTFace);
|
FT_Done_Face (myFTFace);
|
||||||
myFTFace = NULL;
|
myFTFace = NULL;
|
||||||
}
|
}
|
||||||
|
myActiveFTFace = NULL;
|
||||||
myBuffer.Nullify();
|
myBuffer.Nullify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +141,7 @@ bool Font_FTFont::Init (const Handle(NCollection_Buffer)& theData,
|
|||||||
|
|
||||||
FT_Set_Transform (myFTFace, &aMat, 0);
|
FT_Set_Transform (myFTFace, &aMat, 0);
|
||||||
}
|
}
|
||||||
|
myActiveFTFace = myFTFace;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,6 +168,7 @@ Handle(Font_FTFont) Font_FTFont::FindAndCreate (const TCollection_AsciiString& t
|
|||||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||||
if (aFont->Init (aPath, aParams))
|
if (aFont->Init (aPath, aParams))
|
||||||
{
|
{
|
||||||
|
aFont->myFontAspect = aFontAspect;
|
||||||
return aFont;
|
return aFont;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,22 +185,61 @@ bool Font_FTFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
|||||||
Font_StrictLevel theStrictLevel)
|
Font_StrictLevel theStrictLevel)
|
||||||
{
|
{
|
||||||
Font_FTFontParams aParams = theParams;
|
Font_FTFontParams aParams = theParams;
|
||||||
Font_FontAspect aFontAspect = theFontAspect;
|
myFontAspect = theFontAspect;
|
||||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName.ToCString(), theStrictLevel, aFontAspect))
|
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName.ToCString(), theStrictLevel, myFontAspect))
|
||||||
{
|
{
|
||||||
if (aRequestedFont->IsSingleStrokeFont())
|
if (aRequestedFont->IsSingleStrokeFont())
|
||||||
{
|
{
|
||||||
aParams.IsSingleStrokeFont = true;
|
aParams.IsSingleStrokeFont = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (aFontAspect, aParams.ToSynthesizeItalic);
|
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||||
return Init (aPath, aParams);
|
return Init (aPath, aParams);
|
||||||
}
|
}
|
||||||
Release();
|
Release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : findAndInitFallback
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Font_FTFont::findAndInitFallback (Font_UnicodeSubset theSubset)
|
||||||
|
{
|
||||||
|
if (!myFallbackFaces[theSubset].IsNull())
|
||||||
|
{
|
||||||
|
return myFallbackFaces[theSubset]->IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
myFallbackFaces[theSubset] = new Font_FTFont (myFTLib);
|
||||||
|
myFallbackFaces[theSubset]->myToUseUnicodeSubsetFallback = false; // no recursion
|
||||||
|
|
||||||
|
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||||
|
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFallbackFont (theSubset, myFontAspect))
|
||||||
|
{
|
||||||
|
Font_FTFontParams aParams = myFontParams;
|
||||||
|
aParams.IsSingleStrokeFont = aRequestedFont->IsSingleStrokeFont();
|
||||||
|
|
||||||
|
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||||
|
if (myFallbackFaces[theSubset]->Init (aPath, aParams))
|
||||||
|
{
|
||||||
|
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Font_FTFont, using fallback font '") + aRequestedFont->FontName() + "'"
|
||||||
|
+ " for symbols unsupported by '" + myFTFace->family_name + "'", Message_Trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myFallbackFaces[theSubset]->IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : HasSymbol
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
bool Font_FTFont::HasSymbol (Standard_Utf32Char theUChar) const
|
||||||
|
{
|
||||||
|
return FT_Get_Char_Index (myFTFace, theUChar) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : loadGlyph
|
// function : loadGlyph
|
||||||
// purpose :
|
// purpose :
|
||||||
@@ -206,9 +253,26 @@ bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
|
|||||||
|
|
||||||
myGlyphImg.Clear();
|
myGlyphImg.Clear();
|
||||||
myUChar = 0;
|
myUChar = 0;
|
||||||
if (theUChar == 0
|
myActiveFTFace = myFTFace;
|
||||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
if (theUChar == 0)
|
||||||
|| myFTFace->glyph == NULL)
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myToUseUnicodeSubsetFallback
|
||||||
|
&& !HasSymbol (theUChar))
|
||||||
|
{
|
||||||
|
// try using fallback
|
||||||
|
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||||
|
if (findAndInitFallback (aSubset)
|
||||||
|
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||||
|
{
|
||||||
|
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||||
|
|| myActiveFTFace->glyph == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -225,26 +289,67 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
|||||||
{
|
{
|
||||||
myGlyphImg.Clear();
|
myGlyphImg.Clear();
|
||||||
myUChar = 0;
|
myUChar = 0;
|
||||||
|
myActiveFTFace = myFTFace;
|
||||||
|
|
||||||
|
if (theUChar != 0
|
||||||
|
&& myToUseUnicodeSubsetFallback
|
||||||
|
&& !HasSymbol (theUChar))
|
||||||
|
{
|
||||||
|
// try using fallback
|
||||||
|
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||||
|
if (findAndInitFallback (aSubset)
|
||||||
|
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||||
|
{
|
||||||
|
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (theUChar == 0
|
if (theUChar == 0
|
||||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
|| FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||||
|| myFTFace->glyph == NULL
|
|| myActiveFTFace->glyph == NULL
|
||||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
|
FT_Bitmap aBitmap = myActiveFTFace->glyph->bitmap;
|
||||||
if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
|
if (aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||||
|| aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aBitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||||
|
{
|
||||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||||
|
}
|
||||||
|
else if (aBitmap.pixel_mode == FT_PIXEL_MODE_MONO)
|
||||||
|
{
|
||||||
|
if (!myGlyphImg.InitTrash (Image_Format_Gray, aBitmap.width, aBitmap.rows))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||||
|
const int aNumOfBytesInRow = aBitmap.width / 8 + (aBitmap.width % 8 ? 1 : 0);
|
||||||
|
for (int aRow = 0; aRow < (int )aBitmap.rows; ++aRow)
|
||||||
|
{
|
||||||
|
for (int aCol = 0; aCol < (int )aBitmap.width; ++aCol)
|
||||||
|
{
|
||||||
|
const int aBitOn = aBitmap.buffer[aNumOfBytesInRow * aRow + aCol / 8] & (0x80 >> (aCol % 8));
|
||||||
|
*myGlyphImg.ChangeRawValue (aRow, aCol) = aBitOn ? 255 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
myUChar = theUChar;
|
myUChar = theUChar;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -253,24 +358,58 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
|||||||
// function : GlyphMaxSizeX
|
// function : GlyphMaxSizeX
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
unsigned int Font_FTFont::GlyphMaxSizeX() const
|
unsigned int Font_FTFont::GlyphMaxSizeX (bool theToIncludeFallback) const
|
||||||
{
|
{
|
||||||
|
if (!theToIncludeFallback)
|
||||||
|
{
|
||||||
float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
|
float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||||
? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
|
? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
|
||||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||||
return (unsigned int)(aWidth + 0.5f);
|
return (unsigned int)(aWidth + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int aWidth = GlyphMaxSizeX (false);
|
||||||
|
if (theToIncludeFallback)
|
||||||
|
{
|
||||||
|
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||||
|
{
|
||||||
|
if (!myFallbackFaces[aFontIter].IsNull()
|
||||||
|
&& myFallbackFaces[aFontIter]->IsValid())
|
||||||
|
{
|
||||||
|
aWidth = std::max (aWidth, myFallbackFaces[aFontIter]->GlyphMaxSizeX (false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : GlyphMaxSizeY
|
// function : GlyphMaxSizeY
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
unsigned int Font_FTFont::GlyphMaxSizeY() const
|
unsigned int Font_FTFont::GlyphMaxSizeY (bool theToIncludeFallback) const
|
||||||
{
|
{
|
||||||
|
if (!theToIncludeFallback)
|
||||||
|
{
|
||||||
float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
|
float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||||
? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
|
? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
|
||||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||||
return (unsigned int)(aHeight + 0.5f);
|
return (unsigned int)(aHeight + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int aHeight = GlyphMaxSizeY (false);
|
||||||
|
if (theToIncludeFallback)
|
||||||
|
{
|
||||||
|
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||||
|
{
|
||||||
|
if (!myFallbackFaces[aFontIter].IsNull()
|
||||||
|
&& myFallbackFaces[aFontIter]->IsValid())
|
||||||
|
{
|
||||||
|
aHeight = std::max (aHeight, myFallbackFaces[aFontIter]->GlyphMaxSizeY (false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -322,18 +461,22 @@ float Font_FTFont::AdvanceY (Standard_Utf32Char theUChar,
|
|||||||
return AdvanceY (theUCharNext);
|
return AdvanceY (theUCharNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : getKerning
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
bool Font_FTFont::getKerning (FT_Vector& theKern,
|
bool Font_FTFont::getKerning (FT_Vector& theKern,
|
||||||
Standard_Utf32Char theUCharCurr,
|
Standard_Utf32Char theUCharCurr,
|
||||||
Standard_Utf32Char theUCharNext) const
|
Standard_Utf32Char theUCharNext) const
|
||||||
{
|
{
|
||||||
theKern.x = 0;
|
theKern.x = 0;
|
||||||
theKern.y = 0;
|
theKern.y = 0;
|
||||||
if (theUCharNext != 0 && FT_HAS_KERNING(myFTFace) != 0)
|
if (theUCharNext != 0 && FT_HAS_KERNING(myActiveFTFace) != 0)
|
||||||
{
|
{
|
||||||
const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, theUCharCurr);
|
const FT_UInt aCharCurr = FT_Get_Char_Index (myActiveFTFace, theUCharCurr);
|
||||||
const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext);
|
const FT_UInt aCharNext = FT_Get_Char_Index (myActiveFTFace, theUCharNext);
|
||||||
if (aCharCurr == 0 || aCharNext == 0
|
if (aCharCurr == 0 || aCharNext == 0
|
||||||
|| FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0)
|
|| FT_Get_Kerning (myActiveFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0)
|
||||||
{
|
{
|
||||||
theKern.x = 0;
|
theKern.x = 0;
|
||||||
theKern.y = 0;
|
theKern.y = 0;
|
||||||
@@ -357,7 +500,7 @@ float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const
|
|||||||
|
|
||||||
FT_Vector aKern;
|
FT_Vector aKern;
|
||||||
getKerning (aKern, myUChar, theUCharNext);
|
getKerning (aKern, myUChar, theUCharNext);
|
||||||
return myWidthScaling * fromFTPoints<float> (myFTFace->glyph->advance.x + aKern.x);
|
return myWidthScaling * fromFTPoints<float> (myActiveFTFace->glyph->advance.x + aKern.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -373,29 +516,41 @@ float Font_FTFont::AdvanceY (Standard_Utf32Char theUCharNext) const
|
|||||||
|
|
||||||
FT_Vector aKern;
|
FT_Vector aKern;
|
||||||
getKerning (aKern, myUChar, theUCharNext);
|
getKerning (aKern, myUChar, theUCharNext);
|
||||||
return fromFTPoints<float> (myFTFace->glyph->advance.y + aKern.y);
|
return fromFTPoints<float> (myActiveFTFace->glyph->advance.y + aKern.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : GlyphsNumber
|
// function : GlyphsNumber
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Standard_Integer Font_FTFont::GlyphsNumber() const
|
Standard_Integer Font_FTFont::GlyphsNumber (bool theToIncludeFallback) const
|
||||||
{
|
{
|
||||||
return myFTFace->num_glyphs;
|
Standard_Integer aNbGlyphs = myFTFace->num_glyphs;
|
||||||
|
if (theToIncludeFallback)
|
||||||
|
{
|
||||||
|
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||||
|
{
|
||||||
|
if (!myFallbackFaces[aFontIter].IsNull()
|
||||||
|
&& myFallbackFaces[aFontIter]->IsValid())
|
||||||
|
{
|
||||||
|
aNbGlyphs += myFallbackFaces[aFontIter]->GlyphsNumber (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aNbGlyphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : theRect
|
// function : GlyphRect
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Font_FTFont::GlyphRect (Font_Rect& theRect) const
|
void Font_FTFont::GlyphRect (Font_Rect& theRect) const
|
||||||
{
|
{
|
||||||
const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
|
const FT_Bitmap& aBitmap = myActiveFTFace->glyph->bitmap;
|
||||||
theRect.Left = float(myFTFace->glyph->bitmap_left);
|
theRect.Left = float(myActiveFTFace->glyph->bitmap_left);
|
||||||
theRect.Top = float(myFTFace->glyph->bitmap_top);
|
theRect.Top = float(myActiveFTFace->glyph->bitmap_top);
|
||||||
theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
theRect.Right = float(myActiveFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||||
theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
theRect.Bottom = float(myActiveFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <Font_FontAspect.hxx>
|
#include <Font_FontAspect.hxx>
|
||||||
#include <Font_Rect.hxx>
|
#include <Font_Rect.hxx>
|
||||||
#include <Font_StrictLevel.hxx>
|
#include <Font_StrictLevel.hxx>
|
||||||
|
#include <Font_UnicodeSubset.hxx>
|
||||||
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
||||||
#include <Graphic3d_VerticalTextAlignment.hxx>
|
#include <Graphic3d_VerticalTextAlignment.hxx>
|
||||||
#include <Image_PixMap.hxx>
|
#include <Image_PixMap.hxx>
|
||||||
@@ -68,6 +69,69 @@ public:
|
|||||||
const Font_FTFontParams& theParams,
|
const Font_FTFontParams& theParams,
|
||||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||||
|
|
||||||
|
//! Return TRUE if specified character is within subset of modern CJK characters.
|
||||||
|
static bool IsCharFromCJK (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return (theUChar >= 0x03400 && theUChar <= 0x04DFF)
|
||||||
|
|| (theUChar >= 0x04E00 && theUChar <= 0x09FFF)
|
||||||
|
|| (theUChar >= 0x0F900 && theUChar <= 0x0FAFF)
|
||||||
|
|| (theUChar >= 0x20000 && theUChar <= 0x2A6DF)
|
||||||
|
|| (theUChar >= 0x2F800 && theUChar <= 0x2FA1F)
|
||||||
|
// Hiragana and Katakana (Japanese) are NOT part of CJK, but CJK fonts usually include these symbols
|
||||||
|
|| IsCharFromHiragana (theUChar)
|
||||||
|
|| IsCharFromKatakana (theUChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if specified character is within subset of Hiragana (Japanese).
|
||||||
|
static bool IsCharFromHiragana (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return (theUChar >= 0x03040 && theUChar <= 0x0309F);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if specified character is within subset of Katakana (Japanese).
|
||||||
|
static bool IsCharFromKatakana (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return (theUChar >= 0x030A0 && theUChar <= 0x030FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if specified character is within subset of modern Korean characters (Hangul).
|
||||||
|
static bool IsCharFromKorean (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return (theUChar >= 0x01100 && theUChar <= 0x011FF)
|
||||||
|
|| (theUChar >= 0x03130 && theUChar <= 0x0318F)
|
||||||
|
|| (theUChar >= 0x0AC00 && theUChar <= 0x0D7A3);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if specified character is within subset of Arabic characters.
|
||||||
|
static bool IsCharFromArabic (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return (theUChar >= 0x00600 && theUChar <= 0x006FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if specified character should be displayed in Right-to-Left order.
|
||||||
|
static bool IsCharRightToLeft (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
return IsCharFromArabic(theUChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Determine Unicode subset for specified character
|
||||||
|
static Font_UnicodeSubset CharSubset (Standard_Utf32Char theUChar)
|
||||||
|
{
|
||||||
|
if (IsCharFromCJK (theUChar))
|
||||||
|
{
|
||||||
|
return Font_UnicodeSubset_CJK;
|
||||||
|
}
|
||||||
|
else if (IsCharFromKorean (theUChar))
|
||||||
|
{
|
||||||
|
return Font_UnicodeSubset_Korean;
|
||||||
|
}
|
||||||
|
else if (IsCharFromArabic (theUChar))
|
||||||
|
{
|
||||||
|
return Font_UnicodeSubset_Arabic;
|
||||||
|
}
|
||||||
|
return Font_UnicodeSubset_Western;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Create uninitialized instance.
|
//! Create uninitialized instance.
|
||||||
@@ -119,6 +183,13 @@ public:
|
|||||||
const Font_FTFontParams& theParams,
|
const Font_FTFontParams& theParams,
|
||||||
Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||||
|
|
||||||
|
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||||
|
//! @sa Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||||
|
Standard_Boolean ToUseUnicodeSubsetFallback() const { return myToUseUnicodeSubsetFallback; }
|
||||||
|
|
||||||
|
//! Set if fallback fonts should be used in case if used font does not include symbols from specific Unicode subset.
|
||||||
|
void SetUseUnicodeSubsetFallback (Standard_Boolean theToFallback) { myToUseUnicodeSubsetFallback = theToFallback; }
|
||||||
|
|
||||||
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
||||||
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
||||||
bool IsSingleStrokeFont() const { return myFontParams.IsSingleStrokeFont; }
|
bool IsSingleStrokeFont() const { return myFontParams.IsSingleStrokeFont; }
|
||||||
@@ -136,10 +207,10 @@ public:
|
|||||||
Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
|
Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
|
||||||
|
|
||||||
//! @return maximal glyph width in pixels (rendered to bitmap).
|
//! @return maximal glyph width in pixels (rendered to bitmap).
|
||||||
Standard_EXPORT unsigned int GlyphMaxSizeX() const;
|
Standard_EXPORT unsigned int GlyphMaxSizeX (bool theToIncludeFallback = false) const;
|
||||||
|
|
||||||
//! @return maximal glyph height in pixels (rendered to bitmap).
|
//! @return maximal glyph height in pixels (rendered to bitmap).
|
||||||
Standard_EXPORT unsigned int GlyphMaxSizeY() const;
|
Standard_EXPORT unsigned int GlyphMaxSizeY (bool theToIncludeFallback = false) const;
|
||||||
|
|
||||||
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
|
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
|
||||||
Standard_EXPORT float Ascender() const;
|
Standard_EXPORT float Ascender() const;
|
||||||
@@ -163,6 +234,9 @@ public:
|
|||||||
myWidthScaling = theScaleFactor;
|
myWidthScaling = theScaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Return TRUE if font contains specified symbol (excluding fallback list).
|
||||||
|
Standard_EXPORT bool HasSymbol (Standard_Utf32Char theUChar) const;
|
||||||
|
|
||||||
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
||||||
//! Assuming text rendered horizontally.
|
//! Assuming text rendered horizontally.
|
||||||
//! @param theUCharNext the next character to compute advance from current one
|
//! @param theUCharNext the next character to compute advance from current one
|
||||||
@@ -187,8 +261,9 @@ public:
|
|||||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar,
|
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar,
|
||||||
Standard_Utf32Char theUCharNext);
|
Standard_Utf32Char theUCharNext);
|
||||||
|
|
||||||
//! @return glyphs number in this font.
|
//! Return glyphs number in this font.
|
||||||
Standard_EXPORT Standard_Integer GlyphsNumber() const;
|
//! @param theToIncludeFallback if TRUE then the number will include fallback list
|
||||||
|
Standard_EXPORT Standard_Integer GlyphsNumber (bool theToIncludeFallback = false) const;
|
||||||
|
|
||||||
//! Retrieve glyph bitmap rectangle
|
//! Retrieve glyph bitmap rectangle
|
||||||
Standard_EXPORT void GlyphRect (Font_Rect& theRect) const;
|
Standard_EXPORT void GlyphRect (Font_Rect& theRect) const;
|
||||||
@@ -262,18 +337,25 @@ protected:
|
|||||||
Standard_Utf32Char theUCharCurr,
|
Standard_Utf32Char theUCharCurr,
|
||||||
Standard_Utf32Char theUCharNext) const;
|
Standard_Utf32Char theUCharNext) const;
|
||||||
|
|
||||||
|
//! Initialize fallback font.
|
||||||
|
Standard_EXPORT bool findAndInitFallback (Font_UnicodeSubset theSubset);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
||||||
Handle(NCollection_Buffer) myBuffer; //!< memory buffer
|
Handle(NCollection_Buffer) myBuffer; //!< memory buffer
|
||||||
|
Handle(Font_FTFont) myFallbackFaces[Font_UnicodeSubset_NB]; //!< fallback fonts
|
||||||
FT_Face myFTFace; //!< FT face object
|
FT_Face myFTFace; //!< FT face object
|
||||||
|
FT_Face myActiveFTFace; //!< active FT face object (the main of fallback)
|
||||||
TCollection_AsciiString myFontPath; //!< font path
|
TCollection_AsciiString myFontPath; //!< font path
|
||||||
Font_FTFontParams myFontParams; //!< font initialization parameters
|
Font_FTFontParams myFontParams; //!< font initialization parameters
|
||||||
|
Font_FontAspect myFontAspect; //!< font initialization aspect
|
||||||
float myWidthScaling; //!< scale glyphs along X-axis
|
float myWidthScaling; //!< scale glyphs along X-axis
|
||||||
int32_t myLoadFlags; //!< default load flags
|
int32_t myLoadFlags; //!< default load flags
|
||||||
|
|
||||||
Image_PixMap myGlyphImg; //!< cached glyph plane
|
Image_PixMap myGlyphImg; //!< cached glyph plane
|
||||||
Standard_Utf32Char myUChar; //!< currently loaded unicode character
|
Standard_Utf32Char myUChar; //!< currently loaded unicode character
|
||||||
|
Standard_Boolean myToUseUnicodeSubsetFallback; //!< use default fallback fonts for extended Unicode sub-sets (Korean, CJK, etc.)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -88,6 +88,10 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
|
|||||||
"/usr/X11/lib/X11/fs/config",
|
"/usr/X11/lib/X11/fs/config",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Although fontconfig library can be built for various platforms,
|
||||||
|
// practically it is useful only on desktop Linux distributions, where it is always packaged.
|
||||||
|
#include <fontconfig/fontconfig.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -193,6 +197,16 @@ Handle(Font_FontMgr) Font_FontMgr::GetInstance()
|
|||||||
return _mgr;
|
return _mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : ToUseUnicodeSubsetFallback
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean& Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||||
|
{
|
||||||
|
static Standard_Boolean TheToUseUnicodeSubsetFallback = true;
|
||||||
|
return TheToUseUnicodeSubsetFallback;
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : addFontAlias
|
// function : addFontAlias
|
||||||
// purpose :
|
// purpose :
|
||||||
@@ -239,6 +253,7 @@ Font_FontMgr::Font_FontMgr()
|
|||||||
Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
|
Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
|
||||||
Handle(Font_FontAliasSequence) aCJK = new Font_FontAliasSequence();
|
Handle(Font_FontAliasSequence) aCJK = new Font_FontAliasSequence();
|
||||||
Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
|
Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
|
||||||
|
Handle(Font_FontAliasSequence) anArab = new Font_FontAliasSequence();
|
||||||
|
|
||||||
// best matches - pre-installed on Windows, some of them are pre-installed on macOS,
|
// best matches - pre-installed on Windows, some of them are pre-installed on macOS,
|
||||||
// and sometimes them can be found installed on other systems (by user)
|
// and sometimes them can be found installed on other systems (by user)
|
||||||
@@ -289,6 +304,15 @@ Font_FontMgr::Font_FontMgr()
|
|||||||
aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
|
aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
|
||||||
aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
|
aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
anArab->Append (Font_FontAlias ("times new roman"));
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
anArab->Append (Font_FontAlias ("decotype naskh"));
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
anArab->Append (Font_FontAlias ("droid arabic naskh"));
|
||||||
|
anArab->Append (Font_FontAlias ("noto naskh arabic"));
|
||||||
|
#endif
|
||||||
|
|
||||||
addFontAlias ("mono", aMono);
|
addFontAlias ("mono", aMono);
|
||||||
addFontAlias ("courier", aMono); // Font_NOF_ASCII_MONO
|
addFontAlias ("courier", aMono); // Font_NOF_ASCII_MONO
|
||||||
addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
|
addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
|
||||||
@@ -308,6 +332,7 @@ Font_FontMgr::Font_FontMgr()
|
|||||||
addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
|
addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
|
||||||
addFontAlias ("cjk", aCJK); // Font_NOF_CJK
|
addFontAlias ("cjk", aCJK); // Font_NOF_CJK
|
||||||
addFontAlias ("nsimsun", aCJK);
|
addFontAlias ("nsimsun", aCJK);
|
||||||
|
addFontAlias ("arabic", anArab); // Font_NOF_ARABIC
|
||||||
addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
|
addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
|
||||||
addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
|
addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
|
||||||
|
|
||||||
@@ -372,7 +397,7 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
|
|||||||
void Font_FontMgr::InitFontDataBase()
|
void Font_FontMgr::InitFontDataBase()
|
||||||
{
|
{
|
||||||
myFontMap.Clear();
|
myFontMap.Clear();
|
||||||
Handle(Font_FTLibrary) aFtLibrary;
|
Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
|
||||||
|
|
||||||
#if defined(OCCT_UWP)
|
#if defined(OCCT_UWP)
|
||||||
// system font files are not accessible
|
// system font files are not accessible
|
||||||
@@ -407,7 +432,6 @@ void Font_FontMgr::InitFontDataBase()
|
|||||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||||
}
|
}
|
||||||
|
|
||||||
aFtLibrary = new Font_FTLibrary();
|
|
||||||
static const DWORD aBufferSize = 256;
|
static const DWORD aBufferSize = 256;
|
||||||
char aNameBuff[aBufferSize];
|
char aNameBuff[aBufferSize];
|
||||||
char aPathBuff[aBufferSize];
|
char aPathBuff[aBufferSize];
|
||||||
@@ -450,7 +474,31 @@ void Font_FontMgr::InitFontDataBase()
|
|||||||
|
|
||||||
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
|
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
|
||||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||||
|
if (FcConfig* aFcCfg = FcInitLoadConfig())
|
||||||
|
{
|
||||||
|
if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
|
||||||
|
if (aFcFolder == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCollection_AsciiString aPathStr ((const char* )aFcFolder);
|
||||||
|
OSD_Path aPath (aPathStr);
|
||||||
|
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||||
|
}
|
||||||
|
FcStrListDone (aFcFontDir);
|
||||||
|
}
|
||||||
|
FcConfigDestroy (aFcCfg);
|
||||||
|
}
|
||||||
|
|
||||||
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
||||||
|
if (aMapOfFontsDirs.IsEmpty())
|
||||||
|
{
|
||||||
|
Message::DefaultMessenger()->Send ("Font_FontMgr, fontconfig library returns an empty folder list", Message_Alarm);
|
||||||
|
|
||||||
// read fonts directories from font service config file (obsolete)
|
// read fonts directories from font service config file (obsolete)
|
||||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||||
@@ -506,6 +554,7 @@ void Font_FontMgr::InitFontDataBase()
|
|||||||
}
|
}
|
||||||
aFile.Close();
|
aFile.Close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// append default directories
|
// append default directories
|
||||||
@@ -524,7 +573,6 @@ void Font_FontMgr::InitFontDataBase()
|
|||||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||||
}
|
}
|
||||||
|
|
||||||
aFtLibrary = new Font_FTLibrary();
|
|
||||||
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
|
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
|
||||||
anIter.More(); anIter.Next())
|
anIter.More(); anIter.Next())
|
||||||
{
|
{
|
||||||
@@ -686,6 +734,24 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& th
|
|||||||
return myFontMap.Find (theFontName);
|
return myFontMap.Find (theFontName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : FindFallbackFont
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Handle(Font_SystemFont) Font_FontMgr::FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||||
|
Font_FontAspect theFontAspect) const
|
||||||
|
{
|
||||||
|
Font_FontAspect aFontAspect = theFontAspect;
|
||||||
|
switch (theSubset)
|
||||||
|
{
|
||||||
|
case Font_UnicodeSubset_Western: return FindFont (Font_NOF_SANS_SERIF, Font_StrictLevel_Aliases, aFontAspect);
|
||||||
|
case Font_UnicodeSubset_Korean: return FindFont (Font_NOF_KOREAN, Font_StrictLevel_Aliases, aFontAspect);
|
||||||
|
case Font_UnicodeSubset_CJK: return FindFont (Font_NOF_CJK, Font_StrictLevel_Aliases, aFontAspect);
|
||||||
|
case Font_UnicodeSubset_Arabic: return FindFont (Font_NOF_ARABIC, Font_StrictLevel_Aliases, aFontAspect);
|
||||||
|
}
|
||||||
|
return Handle(Font_SystemFont)();
|
||||||
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : FindFont
|
// function : FindFont
|
||||||
// purpose :
|
// purpose :
|
||||||
@@ -770,7 +836,8 @@ Handle(Font_SystemFont) Font_FontMgr::FindFont (const TCollection_AsciiString& t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aFont.IsNull())
|
if (aFont.IsNull()
|
||||||
|
&& theStrictLevel == Font_StrictLevel_Any)
|
||||||
{
|
{
|
||||||
// try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
|
// try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
|
||||||
aFont = myFontMap.Find (TCollection_AsciiString());
|
aFont = myFontMap.Find (TCollection_AsciiString());
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include <Font_FontAspect.hxx>
|
#include <Font_FontAspect.hxx>
|
||||||
#include <Font_NListOfSystemFont.hxx>
|
#include <Font_NListOfSystemFont.hxx>
|
||||||
#include <Font_StrictLevel.hxx>
|
#include <Font_StrictLevel.hxx>
|
||||||
|
#include <Font_UnicodeSubset.hxx>
|
||||||
#include <NCollection_DataMap.hxx>
|
#include <NCollection_DataMap.hxx>
|
||||||
#include <NCollection_IndexedMap.hxx>
|
#include <NCollection_IndexedMap.hxx>
|
||||||
#include <NCollection_Shared.hxx>
|
#include <NCollection_Shared.hxx>
|
||||||
@@ -55,6 +56,9 @@ public:
|
|||||||
return "invalid";
|
return "invalid";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||||
|
Standard_EXPORT static Standard_Boolean& ToUseUnicodeSubsetFallback();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Return the list of available fonts.
|
//! Return the list of available fonts.
|
||||||
@@ -107,6 +111,13 @@ public:
|
|||||||
return FindFont (theFontName, Font_StrictLevel_Any, theFontAspect);
|
return FindFont (theFontName, Font_StrictLevel_Any, theFontAspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Tries to find fallback font for specified Unicode subset.
|
||||||
|
//! Returns NULL in case when fallback font is not found in the system.
|
||||||
|
//! @param theSubset [in] Unicode subset
|
||||||
|
//! @param theFontAspect [in] font aspect to find
|
||||||
|
Standard_EXPORT Handle(Font_SystemFont) FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||||
|
Font_FontAspect theFontAspect) const;
|
||||||
|
|
||||||
//! Read font file and retrieve information from it.
|
//! Read font file and retrieve information from it.
|
||||||
Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
|
Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
|
||||||
|
|
||||||
|
@@ -16,8 +16,9 @@
|
|||||||
#define Font_NOF_MONOSPACE "monospace"
|
#define Font_NOF_MONOSPACE "monospace"
|
||||||
#define Font_NOF_SERIF "serif"
|
#define Font_NOF_SERIF "serif"
|
||||||
#define Font_NOF_SANS_SERIF "sans-serif"
|
#define Font_NOF_SANS_SERIF "sans-serif"
|
||||||
#define Font_NOF_CJK "cjk"
|
#define Font_NOF_CJK "cjk" // Font_UnicodeSubset_CJK
|
||||||
#define Font_NOF_KOREAN "korean"
|
#define Font_NOF_KOREAN "korean" // Font_UnicodeSubset_Korean
|
||||||
|
#define Font_NOF_ARABIC "arabic" // Font_UnicodeSubset_Arabic
|
||||||
|
|
||||||
#define Font_NOF_ASCII_MONO "Courier"
|
#define Font_NOF_ASCII_MONO "Courier"
|
||||||
#define Font_NOF_ASCII_SIMPLEX "Times-Roman"
|
#define Font_NOF_ASCII_SIMPLEX "Times-Roman"
|
||||||
|
28
src/Font/Font_UnicodeSubset.hxx
Normal file
28
src/Font/Font_UnicodeSubset.hxx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#ifndef _Font_UnicodeSubset_HeaderFile
|
||||||
|
#define _Font_UnicodeSubset_HeaderFile
|
||||||
|
|
||||||
|
//! Enumeration defining Unicode subsets.
|
||||||
|
enum Font_UnicodeSubset
|
||||||
|
{
|
||||||
|
Font_UnicodeSubset_Western, //!< western letters
|
||||||
|
Font_UnicodeSubset_Korean, //!< modern Korean letters
|
||||||
|
Font_UnicodeSubset_CJK, //!< Chinese characters (Chinese, Japanese, Korean and Vietnam)
|
||||||
|
Font_UnicodeSubset_Arabic, //!< Arabic characters
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { Font_UnicodeSubset_NB = Font_UnicodeSubset_Arabic };
|
||||||
|
|
||||||
|
#endif // _Font_UnicodeSubset_HeaderFile
|
@@ -26,6 +26,7 @@
|
|||||||
#include <DrawTrSurf_Curve2d.hxx>
|
#include <DrawTrSurf_Curve2d.hxx>
|
||||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||||
#include <Geom2dAPI_ExtremaCurveCurve.hxx>
|
#include <Geom2dAPI_ExtremaCurveCurve.hxx>
|
||||||
|
#include <Geom2dAPI_Interpolate.hxx>
|
||||||
#include <Geom2dAPI_PointsToBSpline.hxx>
|
#include <Geom2dAPI_PointsToBSpline.hxx>
|
||||||
#include <Geom2dAPI_InterCurveCurve.hxx>
|
#include <Geom2dAPI_InterCurveCurve.hxx>
|
||||||
#include <Geom2d_Line.hxx>
|
#include <Geom2d_Line.hxx>
|
||||||
@@ -178,7 +179,6 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
// test points ou ordonnees
|
// test points ou ordonnees
|
||||||
hasPoints = Standard_False;
|
|
||||||
Standard_Integer nc = n - 3;
|
Standard_Integer nc = n - 3;
|
||||||
if (nc == 2 * Nb) {
|
if (nc == 2 * Nb) {
|
||||||
// points
|
// points
|
||||||
@@ -190,6 +190,7 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
|
|||||||
}
|
}
|
||||||
else if (nc - 2 == Nb) {
|
else if (nc - 2 == Nb) {
|
||||||
// YValues
|
// YValues
|
||||||
|
hasPoints = Standard_False;
|
||||||
nc = 5;
|
nc = 5;
|
||||||
X0 = Draw::Atof(a[3]);
|
X0 = Draw::Atof(a[3]);
|
||||||
DX = Draw::Atof(a[4]);
|
DX = Draw::Atof(a[4]);
|
||||||
@@ -214,9 +215,44 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
|
|||||||
|
|
||||||
Handle(Geom2d_BSplineCurve) TheCurve;
|
Handle(Geom2d_BSplineCurve) TheCurve;
|
||||||
if (hasPoints)
|
if (hasPoints)
|
||||||
TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
|
{
|
||||||
|
if (!strcmp (a[0], "2dinterpole"))
|
||||||
|
{
|
||||||
|
Geom2dAPI_Interpolate anInterpol (new TColgp_HArray1OfPnt2d(Points), Standard_False, Tol2d);
|
||||||
|
anInterpol.Perform();
|
||||||
|
if (!anInterpol.IsDone())
|
||||||
|
{
|
||||||
|
di << "not done";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TheCurve = anInterpol.Curve();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
|
{
|
||||||
|
Geom2dAPI_PointsToBSpline anApprox (Points, Dmin, Dmax, GeomAbs_C2, Tol2d);
|
||||||
|
if (!anApprox.IsDone())
|
||||||
|
{
|
||||||
|
di << "not done";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TheCurve = anApprox.Curve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!strcmp (a[0], "2dinterpole"))
|
||||||
|
{
|
||||||
|
di << "incorrect usage";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Geom2dAPI_PointsToBSpline anApprox (YValues, X0, DX, Dmin, Dmax, GeomAbs_C2, Tol2d);
|
||||||
|
if (!anApprox.IsDone())
|
||||||
|
{
|
||||||
|
di << "not done";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TheCurve = anApprox.Curve();
|
||||||
|
}
|
||||||
|
|
||||||
DrawTrSurf::Set(a[1], TheCurve);
|
DrawTrSurf::Set(a[1], TheCurve);
|
||||||
di << a[1];
|
di << a[1];
|
||||||
|
@@ -15,8 +15,6 @@ Graphic3d_Aspects.cxx
|
|||||||
Graphic3d_Aspects.hxx
|
Graphic3d_Aspects.hxx
|
||||||
Graphic3d_AspectFillArea3d.cxx
|
Graphic3d_AspectFillArea3d.cxx
|
||||||
Graphic3d_AspectFillArea3d.hxx
|
Graphic3d_AspectFillArea3d.hxx
|
||||||
Graphic3d_AspectFillCapping.cxx
|
|
||||||
Graphic3d_AspectFillCapping.hxx
|
|
||||||
Graphic3d_AspectLine3d.cxx
|
Graphic3d_AspectLine3d.cxx
|
||||||
Graphic3d_AspectLine3d.hxx
|
Graphic3d_AspectLine3d.hxx
|
||||||
Graphic3d_AspectMarker3d.cxx
|
Graphic3d_AspectMarker3d.cxx
|
||||||
|
@@ -1,110 +0,0 @@
|
|||||||
// Created on: 2017-04-14
|
|
||||||
// Created by: Anton POLETAEV
|
|
||||||
// Copyright (c) 2017 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// This file is part of Open CASCADE Technology software library.
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
||||||
// by the Free Software Foundation, with special exception defined in the file
|
|
||||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
||||||
// distribution for complete text of the license and disclaimer of any warranty.
|
|
||||||
//
|
|
||||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
||||||
// commercial license or contractual agreement.
|
|
||||||
|
|
||||||
#include <Graphic3d_AspectFillCapping.hxx>
|
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AspectFillCapping, Standard_Transient)
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : Graphic3d_AspectFillCapping
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
Graphic3d_AspectFillCapping::Graphic3d_AspectFillCapping()
|
|
||||||
: myFlags (Flags_None),
|
|
||||||
myHatchingState (0)
|
|
||||||
{
|
|
||||||
Graphic3d_MaterialAspect aMaterial;
|
|
||||||
aMaterial.SetColor (Quantity_NOC_BLACK);
|
|
||||||
aMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
|
|
||||||
aMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
|
|
||||||
aMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
|
|
||||||
aMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
|
|
||||||
aMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
|
|
||||||
SetHatchStyle (Aspect_HS_HORIZONTAL);
|
|
||||||
SetHatchMaterial (aMaterial);
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchStyle
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchStyle (const Aspect_HatchStyle theStyle)
|
|
||||||
{
|
|
||||||
myStippleHatch = new Graphic3d_HatchStyle (theStyle);
|
|
||||||
myTextureHatch.Nullify();
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchStyle
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
|
|
||||||
{
|
|
||||||
myStippleHatch = theStyle;
|
|
||||||
myTextureHatch.Nullify();
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchStyle
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchStyle (const Handle(Graphic3d_TextureMap)& theTexture)
|
|
||||||
{
|
|
||||||
myStippleHatch.Nullify();
|
|
||||||
myTextureHatch = theTexture;
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchMaterial
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchMaterial (const Graphic3d_MaterialAspect& theMaterial)
|
|
||||||
{
|
|
||||||
myHatchMaterial = theMaterial;
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetToDrawHatch
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetToDrawHatch (const Standard_Boolean theToDraw)
|
|
||||||
{
|
|
||||||
setFlag (theToDraw, Flags_DrawHatching);
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchZoomPeristent
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchZoomPeristent (const Standard_Boolean theToSet)
|
|
||||||
{
|
|
||||||
setFlag (theToSet, Flags_HatchZoomPersistent);
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : SetHatchRotationPeristent
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
void Graphic3d_AspectFillCapping::SetHatchRotationPeristent (const Standard_Boolean theToSet)
|
|
||||||
{
|
|
||||||
setFlag (theToSet, Flags_HatchRotationPersistent);
|
|
||||||
myHatchingState++;
|
|
||||||
}
|
|
@@ -1,164 +0,0 @@
|
|||||||
// Created on: 2017-04-14
|
|
||||||
// Created by: Anton POLETAEV
|
|
||||||
// Copyright (c) 2017 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// This file is part of Open CASCADE Technology software library.
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
||||||
// by the Free Software Foundation, with special exception defined in the file
|
|
||||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
||||||
// distribution for complete text of the license and disclaimer of any warranty.
|
|
||||||
//
|
|
||||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
||||||
// commercial license or contractual agreement.
|
|
||||||
|
|
||||||
#ifndef _Graphic3d_AspectFillCapping_HeaderFile
|
|
||||||
#define _Graphic3d_AspectFillCapping_HeaderFile
|
|
||||||
|
|
||||||
#include <Aspect_HatchStyle.hxx>
|
|
||||||
#include <Graphic3d_Aspects.hxx>
|
|
||||||
#include <Graphic3d_HatchStyle.hxx>
|
|
||||||
#include <Graphic3d_MaterialAspect.hxx>
|
|
||||||
#include <Graphic3d_ShaderProgram.hxx>
|
|
||||||
#include <Graphic3d_TextureMap.hxx>
|
|
||||||
#include <Standard_Transient.hxx>
|
|
||||||
|
|
||||||
//! Defines graphical attributes for drawing section planes on solids resulted from clipping (cutting) planes.
|
|
||||||
class Graphic3d_AspectFillCapping : public Graphic3d_Aspects
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Default constructor.
|
|
||||||
Standard_EXPORT Graphic3d_AspectFillCapping();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Sets material for filling section created by clipping.
|
|
||||||
void SetMaterial (const Graphic3d_MaterialAspect& theMaterial) { myMaterial = theMaterial; }
|
|
||||||
|
|
||||||
//! Returns material for filling section created by clipping.
|
|
||||||
const Graphic3d_MaterialAspect& Material() const { return myMaterial; }
|
|
||||||
|
|
||||||
//! Sets flag indicating whether object's material (instead of defined by this aspect) should be used for filling section.
|
|
||||||
void SetUseObjectMaterial (const Standard_Boolean theToUse) { setFlag (theToUse, Flags_UseObjectMaterial); }
|
|
||||||
|
|
||||||
//! Returns flag indicating whether object's material (instead of defined by this aspect) should be used for filling section.
|
|
||||||
Standard_Boolean ToUseObjectMaterial() const { return (myFlags & Flags_UseObjectMaterial) != 0; }
|
|
||||||
|
|
||||||
//! Sets texture for filling section created by clipping.
|
|
||||||
void SetTexture (const Handle(Graphic3d_TextureMap)& theTexture) { myTexture = theTexture; }
|
|
||||||
|
|
||||||
//! Returns texture for filling section created by clipping.
|
|
||||||
const Handle(Graphic3d_TextureMap)& Texture() const { return myTexture; }
|
|
||||||
|
|
||||||
//! Sets flag indicating whether object's texture (instead of defined by this aspect) should be used for filling section.
|
|
||||||
void SetUseObjectTexture (const Standard_Boolean theToUse) { setFlag (theToUse, Flags_UseObjectTexture); }
|
|
||||||
|
|
||||||
//! Returns flag indicating whether object's texture (instead of defined by this aspect) should be used for filling section.
|
|
||||||
Standard_Boolean ToUseObjectTexture() const { return (myFlags & Flags_UseObjectTexture) != 0; }
|
|
||||||
|
|
||||||
//! Sets OpenGL/GLSL shader program.
|
|
||||||
void SetShader (const Handle(Graphic3d_ShaderProgram)& theShader) { myShader = theShader; }
|
|
||||||
|
|
||||||
//! Returns OpenGL/GLSL shader program.
|
|
||||||
const Handle(Graphic3d_ShaderProgram)& Shader() const { return myShader; }
|
|
||||||
|
|
||||||
//! Sets flag indicating whether object's shader (instead of defined by this aspect) should be used for filling section.
|
|
||||||
void SetUseObjectShader (const Standard_Boolean theToUse) { setFlag (theToUse, Flags_UseObjectShader); }
|
|
||||||
|
|
||||||
//! Returns flag indicating whether object's shader (instead of defined by this aspect) should be used for filling section.
|
|
||||||
Standard_Boolean ToUseObjectShader() const { return (myFlags & Flags_UseObjectShader) != 0; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Sets style of hatch defined by predefined stipple mask.
|
|
||||||
Standard_EXPORT void SetHatchStyle (const Aspect_HatchStyle theStyle);
|
|
||||||
|
|
||||||
//! Sets style of hatch defined by custom stipple mask.
|
|
||||||
Standard_EXPORT void SetHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle);
|
|
||||||
|
|
||||||
//! Sets style of hatch defined by texture map (decal texture with alpha channel should be used).
|
|
||||||
Standard_EXPORT void SetHatchStyle (const Handle(Graphic3d_TextureMap)& theTexture);
|
|
||||||
|
|
||||||
//! Sets material style for hatch lines (texture).
|
|
||||||
Standard_EXPORT void SetHatchMaterial (const Graphic3d_MaterialAspect& theMaterial);
|
|
||||||
|
|
||||||
//! Returns material style for hatch lines (texture).
|
|
||||||
const Graphic3d_MaterialAspect& HatchMaterial() const { return myHatchMaterial; }
|
|
||||||
|
|
||||||
//! Sets boolean flag indicating whether the hatch layer should be drawn or not.
|
|
||||||
Standard_EXPORT void SetToDrawHatch (const Standard_Boolean theToDraw);
|
|
||||||
|
|
||||||
//! Returns boolean flag indicating whether the hatch layer should be drawn or not.
|
|
||||||
Standard_Boolean ToDrawHatch() const { return (myFlags & Flags_DrawHatching) != 0; }
|
|
||||||
|
|
||||||
//! Sets flag controlling behavior of hatch texture mapping on zooming.
|
|
||||||
//! @param theToSet [in] if passed TRUE the texture will keep constant screen-scale independent of zooming.
|
|
||||||
Standard_EXPORT void SetHatchZoomPeristent (const Standard_Boolean theToSet);
|
|
||||||
|
|
||||||
//! Returns value of flag controlling behavior of hatch texture mapping on zooming.
|
|
||||||
Standard_Boolean IsHatchZoomPersistent() { return (myFlags & Flags_HatchZoomPersistent) != 0; }
|
|
||||||
|
|
||||||
//! Sets flag controlling behavior of hatch texture mapping on camera rotation around heading vector.
|
|
||||||
Standard_EXPORT void SetHatchRotationPeristent (const Standard_Boolean theToSet);
|
|
||||||
|
|
||||||
//! Returns value of flag controlling behavior of hatch texture mapping on camera rotation around heading vector.
|
|
||||||
Standard_Boolean IsHatchRotationPersistent() { return (myFlags & Flags_HatchRotationPersistent) != 0; }
|
|
||||||
|
|
||||||
//! Returns true if hatch is defined by texture.
|
|
||||||
Standard_Boolean IsTextureHatch() const { return !myTextureHatch.IsNull(); }
|
|
||||||
|
|
||||||
//! Returns texture map defining the hatch.
|
|
||||||
const Handle(Graphic3d_TextureMap)& TextureHatch() const { return myTextureHatch; }
|
|
||||||
|
|
||||||
//! Returns true if hatch is defined by stipple mask.
|
|
||||||
Standard_Boolean IsStippleHatch() const { return !myStippleHatch.IsNull(); }
|
|
||||||
|
|
||||||
//! Returns the stipple mask.
|
|
||||||
const Handle(Graphic3d_HatchStyle)& StippleHatch() const { return myStippleHatch; }
|
|
||||||
|
|
||||||
//! Returns modification counter for hatching state.
|
|
||||||
Standard_Size HatchingState() const { return myHatchingState; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
enum Flags
|
|
||||||
{
|
|
||||||
Flags_None = 0x00, //!< no flags
|
|
||||||
Flags_UseObjectMaterial = 0x01, //!< use object material
|
|
||||||
Flags_UseObjectTexture = 0x02, //!< use object texture
|
|
||||||
Flags_UseObjectShader = 0x04, //!< use object GLSL program
|
|
||||||
Flags_HatchZoomPersistent = 0x08, //!< zoom-persistent texturing
|
|
||||||
Flags_HatchRotationPersistent = 0x10, //!< rotation-persistent texturing
|
|
||||||
Flags_DrawHatching = 0x20, //!< draw hatching
|
|
||||||
Flags_UseObjectProperties = //!< use entire fill area aspect from object
|
|
||||||
Flags_UseObjectMaterial
|
|
||||||
| Flags_UseObjectTexture
|
|
||||||
| Flags_UseObjectShader
|
|
||||||
};
|
|
||||||
|
|
||||||
void setFlag (const Standard_Boolean theToUse, const unsigned int theFlag)
|
|
||||||
{
|
|
||||||
myFlags = theToUse ? myFlags | theFlag : myFlags & ~theFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Graphic3d_MaterialAspect myMaterial;
|
|
||||||
Handle(Graphic3d_TextureMap) myTexture;
|
|
||||||
Handle(Graphic3d_ShaderProgram) myShader;
|
|
||||||
Handle(Graphic3d_HatchStyle) myStippleHatch;
|
|
||||||
Handle(Graphic3d_TextureMap) myTextureHatch;
|
|
||||||
Graphic3d_MaterialAspect myHatchMaterial;
|
|
||||||
unsigned int myFlags;
|
|
||||||
Standard_Size myHatchingState;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTIEXT(Graphic3d_AspectFillCapping, Graphic3d_Aspects)
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFINE_STANDARD_HANDLE (Graphic3d_AspectFillCapping, Graphic3d_Aspects)
|
|
||||||
|
|
||||||
#endif // _Graphic3d_AspectFillCapping_HeaderFile
|
|
@@ -24,6 +24,19 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0;
|
static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0;
|
||||||
|
|
||||||
|
static Handle(Graphic3d_AspectFillArea3d) defaultAspect()
|
||||||
|
{
|
||||||
|
const Graphic3d_MaterialAspect aMaterial (Graphic3d_NOM_DEFAULT);
|
||||||
|
Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
|
||||||
|
anAspect->SetDistinguishOff();
|
||||||
|
anAspect->SetFrontMaterial (aMaterial);
|
||||||
|
anAspect->SetHatchStyle (Aspect_HS_HORIZONTAL);
|
||||||
|
anAspect->SetInteriorStyle (Aspect_IS_SOLID);
|
||||||
|
anAspect->SetInteriorColor (aMaterial.Color());
|
||||||
|
anAspect->SetSuppressBackFaces (false);
|
||||||
|
return anAspect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -31,8 +44,19 @@ namespace
|
|||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane()
|
Graphic3d_ClipPlane::Graphic3d_ClipPlane()
|
||||||
|
: myAspect (defaultAspect()),
|
||||||
|
myPrevInChain(NULL),
|
||||||
|
myPlane (0.0, 0.0, 1.0, 0.0),
|
||||||
|
myEquation (0.0, 0.0, 1.0, 0.0),
|
||||||
|
myEquationRev(0.0, 0.0,-1.0, 0.0),
|
||||||
|
myChainLenFwd(1),
|
||||||
|
myFlags (Graphic3d_CappingFlags_None),
|
||||||
|
myEquationMod(0),
|
||||||
|
myAspectMod (0),
|
||||||
|
myIsOn (Standard_True),
|
||||||
|
myIsCapping (Standard_False)
|
||||||
{
|
{
|
||||||
init();
|
makeId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -40,8 +64,19 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane()
|
|||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
|
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
|
||||||
|
: myAspect (defaultAspect()),
|
||||||
|
myPrevInChain(NULL),
|
||||||
|
myPlane (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w()),
|
||||||
|
myEquation (theEquation),
|
||||||
|
myEquationRev(0.0, 0.0,-1.0, 0.0),
|
||||||
|
myChainLenFwd(1),
|
||||||
|
myFlags (Graphic3d_CappingFlags_None),
|
||||||
|
myEquationMod(0),
|
||||||
|
myAspectMod (0),
|
||||||
|
myIsOn (Standard_True),
|
||||||
|
myIsCapping (Standard_False)
|
||||||
{
|
{
|
||||||
init (gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.a()));
|
makeId();
|
||||||
updateInversedPlane();
|
updateInversedPlane();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,27 +84,42 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
|
|||||||
// function : Graphic3d_ClipPlane
|
// function : Graphic3d_ClipPlane
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_ClipPlane& theOther)
|
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
|
||||||
: Standard_Transient (theOther)
|
: Standard_Transient(theOther),
|
||||||
|
myAspect (defaultAspect()),
|
||||||
|
myPrevInChain(NULL),
|
||||||
|
myPlane (theOther.myPlane),
|
||||||
|
myEquation (theOther.myEquation),
|
||||||
|
myEquationRev(theOther.myEquationRev),
|
||||||
|
myChainLenFwd(1),
|
||||||
|
myFlags (theOther.myFlags),
|
||||||
|
myEquationMod(0),
|
||||||
|
myAspectMod (0),
|
||||||
|
myIsOn (theOther.myIsOn),
|
||||||
|
myIsCapping (theOther.myIsCapping)
|
||||||
{
|
{
|
||||||
*mySectionStyle = *theOther.CappingSectionStyle();
|
makeId();
|
||||||
init (theOther.myPlane,
|
*myAspect = *theOther.CappingAspect();
|
||||||
theOther.myEquationRev,
|
|
||||||
theOther.myIsOn,
|
|
||||||
theOther.myIsCapping,
|
|
||||||
theOther.ToOverrideCappingAspect(),
|
|
||||||
theOther.CappingSectionStyle());
|
|
||||||
updateInversedPlane();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : Graphic3d_ClipPlane
|
// function : Graphic3d_ClipPlane
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const gp_Pln& thePlane)
|
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
|
||||||
|
: myAspect (defaultAspect()),
|
||||||
|
myPrevInChain(NULL),
|
||||||
|
myPlane (thePlane),
|
||||||
|
myChainLenFwd(1),
|
||||||
|
myFlags (Graphic3d_CappingFlags_None),
|
||||||
|
myEquationMod(0),
|
||||||
|
myAspectMod (0),
|
||||||
|
myIsOn (Standard_True),
|
||||||
|
myIsCapping (Standard_False)
|
||||||
{
|
{
|
||||||
init (thePlane);
|
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
||||||
updateInversedPlane();
|
updateInversedPlane();
|
||||||
|
makeId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -81,7 +131,7 @@ void Graphic3d_ClipPlane::SetEquation (const Graphic3d_Vec4d& theEquation)
|
|||||||
myPlane = gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w());
|
myPlane = gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w());
|
||||||
myEquation = theEquation;
|
myEquation = theEquation;
|
||||||
updateInversedPlane();
|
updateInversedPlane();
|
||||||
myOrientationDirty = Standard_True;
|
myEquationMod++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -93,7 +143,7 @@ void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
|
|||||||
myPlane = thePlane;
|
myPlane = thePlane;
|
||||||
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
||||||
updateInversedPlane();
|
updateInversedPlane();
|
||||||
myOrientationDirty = Standard_True;
|
myEquationMod++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -128,106 +178,119 @@ Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane::Clone() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : SetCappingSectionStyle
|
// function : SetCappingMaterial
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Graphic3d_ClipPlane::SetCappingSectionStyle (const Handle(Graphic3d_AspectFillCapping)& theStyle)
|
void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& theMat)
|
||||||
{
|
{
|
||||||
mySectionStyle = theStyle;
|
myAspect->SetFrontMaterial (theMat);
|
||||||
|
myAspect->SetInteriorColor (theMat.Color());
|
||||||
|
++myAspectMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : OrientationMatrix
|
// function : SetCappingTexture
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
const Graphic3d_Mat4& Graphic3d_ClipPlane::OrientationMatrix() const
|
void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture)
|
||||||
{
|
{
|
||||||
if (myOrientationDirty)
|
if (!theTexture.IsNull())
|
||||||
{
|
{
|
||||||
const Standard_ShortReal aDirection[] = {
|
myAspect->SetTextureMapOn();
|
||||||
static_cast<Standard_ShortReal> (myEquation[0]),
|
Handle(Graphic3d_TextureSet) aTextureSet = myAspect->TextureSet();
|
||||||
static_cast<Standard_ShortReal> (myEquation[1]),
|
if (aTextureSet.IsNull() || aTextureSet->Size() != 1)
|
||||||
static_cast<Standard_ShortReal> (myEquation[2])
|
|
||||||
};
|
|
||||||
|
|
||||||
const Standard_ShortReal aTranslate[] = {
|
|
||||||
static_cast<Standard_ShortReal> (myEquation[0] * -myEquation[3]),
|
|
||||||
static_cast<Standard_ShortReal> (myEquation[1] * -myEquation[3]),
|
|
||||||
static_cast<Standard_ShortReal> (myEquation[2] * -myEquation[3])
|
|
||||||
};
|
|
||||||
|
|
||||||
Standard_ShortReal aSide1[] = { 0.0f, 0.0f, 0.0f };
|
|
||||||
Standard_ShortReal aSide2[] = { 0.0f, 0.0f, 0.0f };
|
|
||||||
|
|
||||||
const Standard_ShortReal aMagintude = static_cast<Standard_ShortReal> (Sqrt (myEquation[0] * myEquation[0] + myEquation[2] * myEquation[2]));
|
|
||||||
|
|
||||||
if (aMagintude < ShortRealSmall())
|
|
||||||
{
|
{
|
||||||
aSide1[0] = 1.0f;
|
aTextureSet = new Graphic3d_TextureSet (theTexture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aSide1[0] = aDirection[2] / aMagintude;
|
aTextureSet->SetFirst (theTexture);
|
||||||
aSide1[2] = -aDirection[0] / aMagintude;
|
|
||||||
}
|
}
|
||||||
|
myAspect->SetTextureSet (aTextureSet);
|
||||||
aSide2[0] = (-aSide1[1] * aDirection[2]) - (-aSide1[2] * aDirection[1]);
|
|
||||||
aSide2[1] = (-aSide1[2] * aDirection[0]) - (-aSide1[0] * aDirection[2]);
|
|
||||||
aSide2[2] = (-aSide1[0] * aDirection[1]) - (-aSide1[1] * aDirection[0]);
|
|
||||||
|
|
||||||
myOrientationMat.SetValue (0, 0, aSide1[0]);
|
|
||||||
myOrientationMat.SetValue (1, 0, aSide1[1]);
|
|
||||||
myOrientationMat.SetValue (2, 0, aSide1[2]);
|
|
||||||
myOrientationMat.SetValue (3, 0, 0.0F);
|
|
||||||
|
|
||||||
myOrientationMat.SetValue (0, 1, aDirection[0]);
|
|
||||||
myOrientationMat.SetValue (1, 1, aDirection[1]);
|
|
||||||
myOrientationMat.SetValue (2, 1, aDirection[2]);
|
|
||||||
myOrientationMat.SetValue (3, 1, 0.0F);
|
|
||||||
|
|
||||||
myOrientationMat.SetValue (0, 2, aSide2[0]);
|
|
||||||
myOrientationMat.SetValue (1, 2, aSide2[1]);
|
|
||||||
myOrientationMat.SetValue (2, 2, aSide2[2]);
|
|
||||||
myOrientationMat.SetValue (3, 2, 0.0F);
|
|
||||||
|
|
||||||
myOrientationMat.SetValue (0, 3, aTranslate[0]);
|
|
||||||
myOrientationMat.SetValue (1, 3, aTranslate[1]);
|
|
||||||
myOrientationMat.SetValue (2, 3, aTranslate[2]);
|
|
||||||
myOrientationMat.SetValue (3, 3, 1.0F);
|
|
||||||
|
|
||||||
myOrientationDirty = Standard_False;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return myOrientationMat;
|
{
|
||||||
|
myAspect->SetTextureMapOff();
|
||||||
|
myAspect->SetTextureSet (Handle(Graphic3d_TextureSet)());
|
||||||
|
}
|
||||||
|
++myAspectMod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : init
|
// function : SetCappingHatch
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Graphic3d_ClipPlane::init (const gp_Pln& thePlane,
|
void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle)
|
||||||
const Graphic3d_Vec4d& theEquationRev,
|
|
||||||
const Standard_Boolean theIsOn,
|
|
||||||
const Standard_Boolean theIsCapping,
|
|
||||||
const Standard_Boolean theOverrideStyle,
|
|
||||||
const Handle(Graphic3d_AspectFillCapping)& theStyle)
|
|
||||||
{
|
{
|
||||||
if (myEntityUID.IsEmpty())
|
myAspect->SetHatchStyle (theStyle);
|
||||||
{
|
++myAspectMod;
|
||||||
myEntityUID = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
|
}
|
||||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
myPrevInChain = NULL;
|
// =======================================================================
|
||||||
myEquationRev = theEquationRev;
|
// function : SetCappingCustomHatch
|
||||||
myChainLenFwd = 1;
|
// purpose :
|
||||||
myPlane = thePlane;
|
// =======================================================================
|
||||||
myPlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
void Graphic3d_ClipPlane::SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle)
|
||||||
myIsOn = theIsOn;
|
{
|
||||||
myIsCapping = theIsCapping;
|
myAspect->SetHatchStyle (theStyle);
|
||||||
myOverrideObjectStyle = theOverrideStyle;
|
++myAspectMod;
|
||||||
mySectionStyle = theStyle.IsNull() ? new Graphic3d_AspectFillCapping() : theStyle;
|
}
|
||||||
myOrientationDirty = Standard_True;
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SetCappingHatchOn
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Graphic3d_ClipPlane::SetCappingHatchOn()
|
||||||
|
{
|
||||||
|
myAspect->SetInteriorStyle (Aspect_IS_HATCH);
|
||||||
|
++myAspectMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SetCappingHatchOff
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Graphic3d_ClipPlane::SetCappingHatchOff()
|
||||||
|
{
|
||||||
|
myAspect->SetInteriorStyle (Aspect_IS_SOLID);
|
||||||
|
++myAspectMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : SetCappingAspect
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Graphic3d_ClipPlane::SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
|
||||||
|
{
|
||||||
|
myAspect = theAspect;
|
||||||
|
++myAspectMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : setCappingFlag
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Graphic3d_ClipPlane::setCappingFlag (bool theToUse, int theFlag)
|
||||||
|
{
|
||||||
|
if (theToUse)
|
||||||
|
{
|
||||||
|
myFlags |= theFlag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
myFlags &= ~(theFlag);
|
||||||
|
}
|
||||||
|
++myAspectMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : makeId
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
void Graphic3d_ClipPlane::makeId()
|
||||||
|
{
|
||||||
|
myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
|
||||||
|
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -249,7 +312,7 @@ void Graphic3d_ClipPlane::updateChainLen()
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Graphic3d_ClipPlane::SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
|
void Graphic3d_ClipPlane::SetChainNextPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
|
||||||
{
|
{
|
||||||
myOrientationDirty = Standard_True;
|
++myEquationMod;
|
||||||
if (!myNextInChain.IsNull())
|
if (!myNextInChain.IsNull())
|
||||||
{
|
{
|
||||||
myNextInChain->myPrevInChain = NULL;
|
myNextInChain->myPrevInChain = NULL;
|
||||||
|
@@ -19,12 +19,9 @@
|
|||||||
#include <Aspect_HatchStyle.hxx>
|
#include <Aspect_HatchStyle.hxx>
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||||
#include <Graphic3d_AspectFillCapping.hxx>
|
|
||||||
#include <Graphic3d_BndBox3d.hxx>
|
#include <Graphic3d_BndBox3d.hxx>
|
||||||
#include <Graphic3d_CappingFlags.hxx>
|
#include <Graphic3d_CappingFlags.hxx>
|
||||||
#include <Graphic3d_Mat4.hxx>
|
|
||||||
#include <Graphic3d_TextureMap.hxx>
|
#include <Graphic3d_TextureMap.hxx>
|
||||||
#include <NCollection_Handle.hxx>
|
|
||||||
#include <NCollection_Vec4.hxx>
|
#include <NCollection_Vec4.hxx>
|
||||||
#include <Standard_Macro.hxx>
|
#include <Standard_Macro.hxx>
|
||||||
#include <Standard_TypeDef.hxx>
|
#include <Standard_TypeDef.hxx>
|
||||||
@@ -169,6 +166,44 @@ public:
|
|||||||
|
|
||||||
public: // @name user-defined graphical attributes
|
public: // @name user-defined graphical attributes
|
||||||
|
|
||||||
|
//! Set material for rendering capping surface.
|
||||||
|
//! @param theMat [in] the material.
|
||||||
|
Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat);
|
||||||
|
|
||||||
|
//! @return capping material.
|
||||||
|
const Graphic3d_MaterialAspect& CappingMaterial() const { return myAspect->FrontMaterial(); }
|
||||||
|
|
||||||
|
//! Set texture to be applied on capping surface.
|
||||||
|
//! @param theTexture [in] the texture.
|
||||||
|
Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture);
|
||||||
|
|
||||||
|
//! @return capping texture map.
|
||||||
|
Handle(Graphic3d_TextureMap) CappingTexture() const { return !myAspect->TextureSet().IsNull() && !myAspect->TextureSet()->IsEmpty()
|
||||||
|
? myAspect->TextureSet()->First()
|
||||||
|
: Handle(Graphic3d_TextureMap)(); }
|
||||||
|
|
||||||
|
//! Set hatch style (stipple) and turn hatching on.
|
||||||
|
//! @param theStyle [in] the hatch style.
|
||||||
|
Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle);
|
||||||
|
|
||||||
|
//! @return hatching style.
|
||||||
|
Aspect_HatchStyle CappingHatch() const { return (Aspect_HatchStyle)myAspect->HatchStyle()->HatchType(); }
|
||||||
|
|
||||||
|
//! Set custom hatch style (stipple) and turn hatching on.
|
||||||
|
//! @param theStyle [in] the hatch pattern.
|
||||||
|
Standard_EXPORT void SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle);
|
||||||
|
|
||||||
|
//! @return hatching style.
|
||||||
|
const Handle(Graphic3d_HatchStyle)& CappingCustomHatch() const { return myAspect->HatchStyle(); }
|
||||||
|
|
||||||
|
//! Turn on hatching.
|
||||||
|
Standard_EXPORT void SetCappingHatchOn();
|
||||||
|
|
||||||
|
//! Turn off hatching.
|
||||||
|
Standard_EXPORT void SetCappingHatchOff();
|
||||||
|
|
||||||
|
//! @return True if hatching mask is turned on.
|
||||||
|
Standard_Boolean IsHatchOn() const { return myAspect->InteriorStyle() == Aspect_IS_HATCH; }
|
||||||
|
|
||||||
//! This ID is used for managing associated resources in graphical driver.
|
//! This ID is used for managing associated resources in graphical driver.
|
||||||
//! The clip plane can be assigned within a range of IO which can be
|
//! The clip plane can be assigned within a range of IO which can be
|
||||||
@@ -179,18 +214,41 @@ public: // @name user-defined graphical attributes
|
|||||||
//! @return clip plane resource identifier string.
|
//! @return clip plane resource identifier string.
|
||||||
const TCollection_AsciiString& GetId() const
|
const TCollection_AsciiString& GetId() const
|
||||||
{
|
{
|
||||||
return myEntityUID;
|
return myId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Returns style used for drawing capping section.
|
//! Return capping aspect.
|
||||||
//! @return capping surface rendering aspect.
|
//! @return capping surface rendering aspect.
|
||||||
const Handle(Graphic3d_AspectFillCapping)& CappingSectionStyle() const { return mySectionStyle; }
|
const Handle(Graphic3d_AspectFillArea3d)& CappingAspect() const { return myAspect; }
|
||||||
|
|
||||||
//! Sets clipping section filling aspect.
|
//! Assign capping aspect.
|
||||||
Standard_EXPORT void SetCappingSectionStyle (const Handle(Graphic3d_AspectFillCapping)& theStyle);
|
Standard_EXPORT void SetCappingAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect);
|
||||||
|
|
||||||
|
//! Flag indicating whether material for capping plane should be taken from object.
|
||||||
|
//! Default value: FALSE (use dedicated capping plane material).
|
||||||
|
bool ToUseObjectMaterial() const { return (myFlags & Graphic3d_CappingFlags_ObjectMaterial) != 0; }
|
||||||
|
|
||||||
|
//! Set flag for controlling the source of capping plane material.
|
||||||
|
void SetUseObjectMaterial (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectMaterial); }
|
||||||
|
|
||||||
|
//! Flag indicating whether texture for capping plane should be taken from object.
|
||||||
|
//! Default value: FALSE.
|
||||||
|
bool ToUseObjectTexture() const { return (myFlags & Graphic3d_CappingFlags_ObjectTexture) != 0; }
|
||||||
|
|
||||||
|
//! Set flag for controlling the source of capping plane texture.
|
||||||
|
void SetUseObjectTexture (bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectTexture); }
|
||||||
|
|
||||||
|
//! Flag indicating whether shader program for capping plane should be taken from object.
|
||||||
|
//! Default value: FALSE.
|
||||||
|
bool ToUseObjectShader() const { return (myFlags & Graphic3d_CappingFlags_ObjectShader) != 0; }
|
||||||
|
|
||||||
|
//! Set flag for controlling the source of capping plane shader program.
|
||||||
|
void SetUseObjectShader(bool theToUse) { setCappingFlag (theToUse, Graphic3d_CappingFlags_ObjectShader); }
|
||||||
|
|
||||||
|
//! Return true if some fill area aspect properties should be taken from object.
|
||||||
|
bool ToUseObjectProperties() const { return myFlags != Graphic3d_CappingFlags_None; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -294,25 +352,14 @@ public: // @name modification counters
|
|||||||
{
|
{
|
||||||
return myAspectMod;
|
return myAspectMod;
|
||||||
}
|
}
|
||||||
//! Flag indicating whether section style of the plane should overrides similar property of object presentation.
|
|
||||||
//! Default value: FALSE (use dedicated presentation aspect style).
|
|
||||||
bool ToOverrideCappingAspect() const { return myOverrideObjectStyle; }
|
|
||||||
|
|
||||||
//! Sets flag for controlling the preference of using section style between clip plane and object.
|
|
||||||
void SetToOverrideCappingAspect (const bool theToOverride) { myOverrideObjectStyle = theToOverride; }
|
|
||||||
|
|
||||||
//! Returns plane's orientation matrix.
|
|
||||||
Standard_EXPORT const Graphic3d_Mat4& OrientationMatrix() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Initializes plane and makes unique identifier (UID) to differentiate clipping plane entities.
|
//! Generate unique object id for OpenGL graphic resource manager.
|
||||||
void init (const gp_Pln& thePlane = gp_Pln(),
|
void makeId();
|
||||||
const Graphic3d_Vec4d& theEquationRev = Graphic3d_Vec4d(0.0, 0.0,-1.0, 0.0),
|
|
||||||
const Standard_Boolean theIsOn = Standard_True,
|
//! Set capping flag.
|
||||||
const Standard_Boolean theIsCapping = Standard_False,
|
Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
|
||||||
const Standard_Boolean theOverrideStyle = Standard_False,
|
|
||||||
const Handle(Graphic3d_AspectFillCapping)& theStyle = Handle(Graphic3d_AspectFillCapping)());
|
|
||||||
|
|
||||||
//! Update chain length in backward direction.
|
//! Update chain length in backward direction.
|
||||||
void updateChainLen();
|
void updateChainLen();
|
||||||
@@ -327,10 +374,10 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Handle(Graphic3d_AspectFillCapping) mySectionStyle; //!< Style set for drawing capped solid section.
|
Handle(Graphic3d_AspectFillArea3d) myAspect; //!< fill area aspect
|
||||||
Handle(Graphic3d_ClipPlane) myNextInChain; //!< next plane in a chain of planes defining logical AND operation
|
Handle(Graphic3d_ClipPlane) myNextInChain; //!< next plane in a chain of planes defining logical AND operation
|
||||||
Graphic3d_ClipPlane* myPrevInChain; //!< previous plane in a chain of planes defining logical AND operation
|
Graphic3d_ClipPlane* myPrevInChain; //!< previous plane in a chain of planes defining logical AND operation
|
||||||
TCollection_AsciiString myEntityUID; //!< Unique identifier for the plane
|
TCollection_AsciiString myId; //!< resource id
|
||||||
gp_Pln myPlane; //!< plane definition
|
gp_Pln myPlane; //!< plane definition
|
||||||
Graphic3d_Vec4d myEquation; //!< plane equation vector
|
Graphic3d_Vec4d myEquation; //!< plane equation vector
|
||||||
Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
|
Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
|
||||||
@@ -340,9 +387,6 @@ private:
|
|||||||
unsigned int myAspectMod; //!< modification counter of aspect
|
unsigned int myAspectMod; //!< modification counter of aspect
|
||||||
Standard_Boolean myIsOn; //!< state of the clipping plane
|
Standard_Boolean myIsOn; //!< state of the clipping plane
|
||||||
Standard_Boolean myIsCapping; //!< state of graphic driver capping
|
Standard_Boolean myIsCapping; //!< state of graphic driver capping
|
||||||
Standard_Boolean myOverrideObjectStyle; //!< Flag forcing to use plane's section style rather than section style defined for object
|
|
||||||
mutable Standard_Boolean myOrientationDirty; //!< Boolean flag indicating whether orientation matrix is dirty or not.
|
|
||||||
mutable Graphic3d_Mat4 myOrientationMat; //!< Plane orientation matrix (for visualization purposes).
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
class Graphic3d_Structure;
|
class Graphic3d_Structure;
|
||||||
class Graphic3d_ArrayOfPrimitives;
|
class Graphic3d_ArrayOfPrimitives;
|
||||||
class Graphic3d_AspectFillCapping;
|
|
||||||
|
|
||||||
//! This class allows the definition of groups
|
//! This class allows the definition of groups
|
||||||
//! of primitives inside of graphic objects (presentations).
|
//! of primitives inside of graphic objects (presentations).
|
||||||
@@ -105,9 +104,6 @@ public:
|
|||||||
//! Modifies the current context of the group to give another aspect for all the primitives created after this call in the group.
|
//! Modifies the current context of the group to give another aspect for all the primitives created after this call in the group.
|
||||||
virtual void SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) = 0;
|
virtual void SetPrimitivesAspect (const Handle(Graphic3d_Aspects)& theAspect) = 0;
|
||||||
|
|
||||||
//! Returns style of filling clipping sections on closed shell primitives.
|
|
||||||
virtual Handle(Graphic3d_AspectFillCapping) FillCappingAspect() const = 0;
|
|
||||||
|
|
||||||
//! Update presentation aspects after their modification.
|
//! Update presentation aspects after their modification.
|
||||||
virtual void SynchronizeAspects() = 0;
|
virtual void SynchronizeAspects() = 0;
|
||||||
|
|
||||||
|
@@ -21,15 +21,13 @@
|
|||||||
//! - ASPECT_LINE: aspect for line primitives;
|
//! - ASPECT_LINE: aspect for line primitives;
|
||||||
//! - ASPECT_TEXT: aspect for text primitives;
|
//! - ASPECT_TEXT: aspect for text primitives;
|
||||||
//! - ASPECT_MARKER: aspect for marker primitives;
|
//! - ASPECT_MARKER: aspect for marker primitives;
|
||||||
//! - ASPECT_FILL_AREA: aspect for face primitives;
|
//! - ASPECT_FILL_AREA: aspect for face primitives.
|
||||||
//! - Graphic3d_ASPECT_FILL_CAPPING: aspect for filling clipping sections.
|
|
||||||
enum Graphic3d_GroupAspect
|
enum Graphic3d_GroupAspect
|
||||||
{
|
{
|
||||||
Graphic3d_ASPECT_LINE,
|
Graphic3d_ASPECT_LINE,
|
||||||
Graphic3d_ASPECT_TEXT,
|
Graphic3d_ASPECT_TEXT,
|
||||||
Graphic3d_ASPECT_MARKER,
|
Graphic3d_ASPECT_MARKER,
|
||||||
Graphic3d_ASPECT_FILL_AREA,
|
Graphic3d_ASPECT_FILL_AREA
|
||||||
Graphic3d_ASPECT_FILL_CAPPING
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _Graphic3d_GroupAspect_HeaderFile
|
#endif // _Graphic3d_GroupAspect_HeaderFile
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#ifndef _IMeshTools_ModelAlgo_HeaderFile
|
#ifndef _IMeshTools_ModelAlgo_HeaderFile
|
||||||
#define _IMeshTools_ModelAlgo_HeaderFile
|
#define _IMeshTools_ModelAlgo_HeaderFile
|
||||||
|
|
||||||
|
#include <Standard_ErrorHandler.hxx>
|
||||||
|
#include <Standard_Failure.hxx>
|
||||||
#include <Standard_Transient.hxx>
|
#include <Standard_Transient.hxx>
|
||||||
#include <Standard_Type.hxx>
|
#include <Standard_Type.hxx>
|
||||||
|
|
||||||
@@ -32,10 +34,22 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Performs processing of edges of the given model.
|
//! Exceptions protected processing of the given model.
|
||||||
Standard_EXPORT virtual Standard_Boolean Perform (
|
Standard_Boolean Perform (
|
||||||
const Handle (IMeshData_Model)& theModel,
|
const Handle (IMeshData_Model)& theModel,
|
||||||
const IMeshTools_Parameters& theParameters) = 0;
|
const IMeshTools_Parameters& theParameters)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
|
return performInternal (theModel, theParameters);
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const&)
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
|
DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelAlgo, Standard_Transient)
|
||||||
|
|
||||||
@@ -45,6 +59,11 @@ protected:
|
|||||||
Standard_EXPORT IMeshTools_ModelAlgo()
|
Standard_EXPORT IMeshTools_ModelAlgo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Performs processing of the given model.
|
||||||
|
Standard_EXPORT virtual Standard_Boolean performInternal (
|
||||||
|
const Handle (IMeshData_Model)& theModel,
|
||||||
|
const IMeshTools_Parameters& theParameters) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@@ -17,6 +17,8 @@
|
|||||||
#define _IMeshTools_ModelBuilder_HeaderFile
|
#define _IMeshTools_ModelBuilder_HeaderFile
|
||||||
|
|
||||||
#include <Message_Algorithm.hxx>
|
#include <Message_Algorithm.hxx>
|
||||||
|
#include <Standard_ErrorHandler.hxx>
|
||||||
|
#include <Standard_Failure.hxx>
|
||||||
#include <Standard_Type.hxx>
|
#include <Standard_Type.hxx>
|
||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
|
|
||||||
@@ -38,11 +40,26 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Creates discrete model for the given shape.
|
//! Exceptions protected method to create discrete model for the given shape.
|
||||||
//! Returns nullptr in case of failure.
|
//! Returns nullptr in case of failure.
|
||||||
Standard_EXPORT virtual Handle (IMeshData_Model) Perform (
|
Handle (IMeshData_Model) Perform (
|
||||||
const TopoDS_Shape& theShape,
|
const TopoDS_Shape& theShape,
|
||||||
const IMeshTools_Parameters& theParameters) = 0;
|
const IMeshTools_Parameters& theParameters)
|
||||||
|
{
|
||||||
|
ClearStatus ();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
|
return performInternal (theShape, theParameters);
|
||||||
|
}
|
||||||
|
catch (Standard_Failure const&)
|
||||||
|
{
|
||||||
|
SetStatus (Message_Fail2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
|
DEFINE_STANDARD_RTTI_INLINE(IMeshTools_ModelBuilder, Message_Algorithm)
|
||||||
|
|
||||||
@@ -52,6 +69,12 @@ protected:
|
|||||||
Standard_EXPORT IMeshTools_ModelBuilder()
|
Standard_EXPORT IMeshTools_ModelBuilder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Creates discrete model for the given shape.
|
||||||
|
//! Returns nullptr in case of failure.
|
||||||
|
Standard_EXPORT virtual Handle (IMeshData_Model) performInternal (
|
||||||
|
const TopoDS_Shape& theShape,
|
||||||
|
const IMeshTools_Parameters& theParameters) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@@ -33,7 +33,8 @@ struct IMeshTools_Parameters {
|
|||||||
Relative (Standard_False),
|
Relative (Standard_False),
|
||||||
InternalVerticesMode (Standard_True),
|
InternalVerticesMode (Standard_True),
|
||||||
ControlSurfaceDeflection (Standard_True),
|
ControlSurfaceDeflection (Standard_True),
|
||||||
CleanModel(Standard_True)
|
CleanModel (Standard_True),
|
||||||
|
AdjustMinSize (Standard_False)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +79,10 @@ struct IMeshTools_Parameters {
|
|||||||
|
|
||||||
//! Cleans temporary data model when algorithm is finished.
|
//! Cleans temporary data model when algorithm is finished.
|
||||||
Standard_Boolean CleanModel;
|
Standard_Boolean CleanModel;
|
||||||
|
|
||||||
|
//! Enables/disables local adjustment of min size depending on edge size.
|
||||||
|
//! Disabled by default.
|
||||||
|
Standard_Boolean AdjustMinSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -304,7 +304,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
{
|
{
|
||||||
Standard_Boolean bIsClosed2;
|
Standard_Boolean bIsClosed2;
|
||||||
Standard_Real aT11, aT12, aT21, aT22;
|
Standard_Real aT11, aT12, aT21, aT22;
|
||||||
Bnd_Box aB2;
|
Bnd_Box aB1, aB2;
|
||||||
//
|
//
|
||||||
bSplit2 = Standard_False;
|
bSplit2 = Standard_False;
|
||||||
myRange1.Range(aT11, aT12);
|
myRange1.Range(aT11, aT12);
|
||||||
@@ -313,7 +313,6 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
|
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
|
||||||
//
|
//
|
||||||
if (bIsClosed2) {
|
if (bIsClosed2) {
|
||||||
Bnd_Box aB1;
|
|
||||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
//
|
//
|
||||||
gp_Pnt aP = myGeom2->Value(aT21);
|
gp_Pnt aP = myGeom2->Value(aT21);
|
||||||
@@ -321,8 +320,9 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (!bIsClosed2) {
|
if (!bIsClosed2) {
|
||||||
|
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||||
FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
|
FindSolutions(myRange1, aB1, myRange2, aB2, theRanges1, theRanges2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -343,10 +343,11 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
//
|
//
|
||||||
for (i = 1; i <= aNb1; ++i) {
|
for (i = 1; i <= aNb1; ++i) {
|
||||||
const IntTools_Range& aR1 = aSegments1(i);
|
const IntTools_Range& aR1 = aSegments1(i);
|
||||||
|
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
|
||||||
for (j = 1; j <= aNb2; ++j) {
|
for (j = 1; j <= aNb2; ++j) {
|
||||||
const IntTools_Range& aR2 = aSegments2(j);
|
const IntTools_Range& aR2 = aSegments2(j);
|
||||||
BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
|
BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
|
||||||
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
|
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -358,6 +359,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
|
|||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
||||||
|
const Bnd_Box& theBox1,
|
||||||
const IntTools_Range& theR2,
|
const IntTools_Range& theR2,
|
||||||
const Bnd_Box& theBox2,
|
const Bnd_Box& theBox2,
|
||||||
IntTools_SequenceOfRanges& theRanges1,
|
IntTools_SequenceOfRanges& theRanges1,
|
||||||
@@ -373,6 +375,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
theR1.Range(aT11, aT12);
|
theR1.Range(aT11, aT12);
|
||||||
theR2.Range(aT21, aT22);
|
theR2.Range(aT21, aT22);
|
||||||
//
|
//
|
||||||
|
aB1 = theBox1;
|
||||||
aB2 = theBox2;
|
aB2 = theBox2;
|
||||||
//
|
//
|
||||||
bThin = Standard_False;
|
bThin = Standard_False;
|
||||||
@@ -385,9 +388,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
aTB21 = aT21;
|
aTB21 = aT21;
|
||||||
aTB22 = aT22;
|
aTB22 = aT22;
|
||||||
//
|
//
|
||||||
//1. Build box for first edge and find parameters
|
//1. Find parameters of the second edge in the box of first one
|
||||||
// of the second one in that box
|
|
||||||
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
|
||||||
bOut = aB1.IsOut(aB2);
|
bOut = aB1.IsOut(aB2);
|
||||||
if (bOut) {
|
if (bOut) {
|
||||||
break;
|
break;
|
||||||
@@ -435,7 +436,9 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
|
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
|
||||||
bStop = Standard_True;
|
bStop = Standard_True;
|
||||||
}
|
}
|
||||||
//
|
else
|
||||||
|
BndBuildBox (myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
|
|
||||||
} while (!bStop);
|
} while (!bStop);
|
||||||
//
|
//
|
||||||
if (bOut) {
|
if (bOut) {
|
||||||
@@ -498,13 +501,20 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
|
|||||||
Standard_Integer i, aNb1;
|
Standard_Integer i, aNb1;
|
||||||
IntTools_SequenceOfRanges aSegments1;
|
IntTools_SequenceOfRanges aSegments1;
|
||||||
//
|
//
|
||||||
|
// Build box for first curve to compare
|
||||||
|
// the boxes of the splits with this one
|
||||||
|
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
|
||||||
|
const Standard_Real aB1SqExtent = aB1.SquareExtent();
|
||||||
|
//
|
||||||
IntTools_Range aR2(aT21, aT22);
|
IntTools_Range aR2(aT21, aT22);
|
||||||
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
|
||||||
//
|
//
|
||||||
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
|
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
|
||||||
for (i = 1; i <= aNb1; ++i) {
|
for (i = 1; i <= aNb1; ++i) {
|
||||||
const IntTools_Range& aR1 = aSegments1(i);
|
const IntTools_Range& aR1 = aSegments1(i);
|
||||||
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
|
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
|
||||||
|
if (!aB1.IsOut(aB2) && (aNb1 == 1 || aB1.SquareExtent() < aB1SqExtent))
|
||||||
|
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -146,7 +146,8 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
//! Looking for the exact intersection ranges
|
//! Looking for the exact intersection ranges
|
||||||
Standard_EXPORT void FindSolutions (const IntTools_Range& theR1,
|
Standard_EXPORT void FindSolutions (
|
||||||
|
const IntTools_Range& theR1, const Bnd_Box& theBox1,
|
||||||
const IntTools_Range& theR2, const Bnd_Box& theBox2,
|
const IntTools_Range& theR2, const Bnd_Box& theBox2,
|
||||||
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges2);
|
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges2);
|
||||||
|
|
||||||
|
@@ -88,7 +88,7 @@ options:\n\
|
|||||||
-surf_def_off disables control of deflection of mesh from real\n\
|
-surf_def_off disables control of deflection of mesh from real\n\
|
||||||
surface (enabled by default)\n\
|
surface (enabled by default)\n\
|
||||||
-parallel enables parallel execution (switched off by default)\n\
|
-parallel enables parallel execution (switched off by default)\n\
|
||||||
-adaptive enables adaptive computation of minimal value in parametric space\n";
|
-adjust_min enables local adjustment of min size depending on edge size (switched off by default)\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +121,8 @@ options:\n\
|
|||||||
aMeshParams.InternalVerticesMode = Standard_False;
|
aMeshParams.InternalVerticesMode = Standard_False;
|
||||||
else if (aOpt == "-surf_def_off")
|
else if (aOpt == "-surf_def_off")
|
||||||
aMeshParams.ControlSurfaceDeflection = Standard_False;
|
aMeshParams.ControlSurfaceDeflection = Standard_False;
|
||||||
|
else if (aOpt == "-adjust_min")
|
||||||
|
aMeshParams.AdjustMinSize = Standard_True;
|
||||||
else if (i < nbarg)
|
else if (i < nbarg)
|
||||||
{
|
{
|
||||||
Standard_Real aVal = Draw::Atof(argv[i++]);
|
Standard_Real aVal = Draw::Atof(argv[i++]);
|
||||||
|
@@ -21,16 +21,11 @@
|
|||||||
#include <OpenGl_PrimitiveArray.hxx>
|
#include <OpenGl_PrimitiveArray.hxx>
|
||||||
#include <OpenGl_CappingPlaneResource.hxx>
|
#include <OpenGl_CappingPlaneResource.hxx>
|
||||||
#include <OpenGl_Vec.hxx>
|
#include <OpenGl_Vec.hxx>
|
||||||
#include <OpenGl_View.hxx>
|
|
||||||
#include <OpenGl_Structure.hxx>
|
#include <OpenGl_Structure.hxx>
|
||||||
#include <OpenGl_ShaderManager.hxx>
|
#include <OpenGl_ShaderManager.hxx>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static const OpenGl_CappingPlaneResource THE_DEFAULT_ASPECT = OpenGl_CappingPlaneResource (new Graphic3d_AspectFillCapping);
|
|
||||||
static const TCollection_AsciiString THE_QUAD_PARRAY = "OpenGl_CappingAlgo_Quad";
|
|
||||||
static const TCollection_AsciiString THE_PLANE_STYLE = "OpenGl_CappingAlgo_CappingStyle_";
|
|
||||||
|
|
||||||
//! Auxiliary sentry object managing stencil test.
|
//! Auxiliary sentry object managing stencil test.
|
||||||
struct StencilTestSentry
|
struct StencilTestSentry
|
||||||
{
|
{
|
||||||
@@ -63,113 +58,21 @@ namespace
|
|||||||
GLint myDepthFuncPrev;
|
GLint myDepthFuncPrev;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenGl_SharedElement : public OpenGl_Resource
|
//! Render infinite capping plane.
|
||||||
{
|
//! @param theWorkspace [in] the GL workspace, context state.
|
||||||
public:
|
//! @param thePlane [in] the graphical plane, for which the capping surface is rendered.
|
||||||
OpenGl_SharedElement (OpenGl_Element* theGlElement) : myGlElement (theGlElement) {}
|
static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||||
virtual void Release (OpenGl_Context* theGlCtx) Standard_OVERRIDE
|
const Handle(OpenGl_CappingPlaneResource)& thePlane)
|
||||||
{
|
|
||||||
OpenGl_Element::Destroy (theGlCtx, myGlElement);
|
|
||||||
}
|
|
||||||
OpenGl_Element* GlElement() const { return myGlElement; }
|
|
||||||
|
|
||||||
//! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
|
|
||||||
Standard_Size EstimatedDataSize() const Standard_OVERRIDE { return 0; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
OpenGl_Element* myGlElement;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DEFINE_STANDARD_RTTI_INLINE (OpenGl_SharedElement, OpenGl_Resource)
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Iitializes and returns vertex buffer for plane section
|
|
||||||
OpenGl_PrimitiveArray* initQuad (const Handle(OpenGl_Context)& theContext)
|
|
||||||
{
|
|
||||||
Handle(OpenGl_SharedElement) aSharedResource;
|
|
||||||
|
|
||||||
if (!theContext->GetResource (THE_QUAD_PARRAY, aSharedResource))
|
|
||||||
{
|
|
||||||
aSharedResource = new OpenGl_SharedElement (OpenGl_CappingPlaneResource::BuildInfinitPlaneVertices());
|
|
||||||
theContext->ShareResource (THE_QUAD_PARRAY, aSharedResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dynamic_cast<OpenGl_PrimitiveArray*> (aSharedResource->GlElement());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Render section plane using the given aspects.
|
|
||||||
void renderSection (const Handle(OpenGl_Workspace)& theWorkspace,
|
|
||||||
const OpenGl_PrimitiveArray* theQuad,
|
|
||||||
const OpenGl_Aspects* theCappingAspect,
|
|
||||||
const OpenGl_Aspects* theHatchAspect,
|
|
||||||
const OpenGl_Mat4& theCappingMatrix,
|
|
||||||
const Standard_ShortReal theHatchScale,
|
|
||||||
const Standard_ShortReal theHatchRotate)
|
|
||||||
{
|
{
|
||||||
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
||||||
const bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
|
const bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
|
||||||
|
|
||||||
const Standard_Boolean isTextureHatch =
|
// set identity model matrix
|
||||||
theHatchAspect != NULL
|
|
||||||
&& theHatchAspect->Aspect()->TextureMapState();
|
|
||||||
|
|
||||||
aContext->ModelWorldState.Push();
|
aContext->ModelWorldState.Push();
|
||||||
aContext->ModelWorldState.SetCurrent (theCappingMatrix);
|
aContext->ModelWorldState.SetCurrent (OpenGl_Mat4::Map (*thePlane->Orientation()->mat));
|
||||||
aContext->ApplyModelViewMatrix();
|
aContext->ApplyModelViewMatrix();
|
||||||
|
|
||||||
theWorkspace->SetAspects (theCappingAspect);
|
thePlane->Primitives().Render (theWorkspace);
|
||||||
theWorkspace->ApplyAspects();
|
|
||||||
|
|
||||||
theQuad->Render (theWorkspace);
|
|
||||||
|
|
||||||
if (theHatchAspect != NULL)
|
|
||||||
{
|
|
||||||
Graphic3d_Vec2 aPrevScale;
|
|
||||||
Standard_ShortReal aPrevRotate = 0.0;
|
|
||||||
|
|
||||||
if (isTextureHatch)
|
|
||||||
{
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
if ((theHatchScale != 1.0 || theHatchRotate != 0.0) && !theHatchAspect->TextureSet(aContext)->IsEmpty())
|
|
||||||
{
|
|
||||||
Handle(OpenGl_Texture) aTexture = theHatchAspect->TextureSet(aContext)->First();
|
|
||||||
const Handle(Graphic3d_TextureParams)& aTexParams = aTexture->Sampler()->Parameters();
|
|
||||||
|
|
||||||
aPrevScale = aTexParams->Scale();
|
|
||||||
aPrevRotate = aTexParams->Rotation();
|
|
||||||
|
|
||||||
const Standard_Boolean isMirror = aPrevScale.x() * aPrevScale.y() < 0.0;
|
|
||||||
aTexParams->SetScale (aPrevScale * theHatchScale);
|
|
||||||
aTexParams->SetRotation (isMirror ? aPrevRotate - theHatchRotate : aPrevRotate + theHatchRotate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
theWorkspace->SetAspects (theHatchAspect);
|
|
||||||
theWorkspace->ApplyAspects();
|
|
||||||
|
|
||||||
glDepthFunc (GL_LEQUAL);
|
|
||||||
|
|
||||||
theQuad->Render (theWorkspace);
|
|
||||||
|
|
||||||
glDepthFunc (GL_LESS);
|
|
||||||
|
|
||||||
if (isTextureHatch)
|
|
||||||
{
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
|
|
||||||
if (theHatchScale != 1.0 || theHatchRotate != 0.0)
|
|
||||||
{
|
|
||||||
Handle(OpenGl_Texture) aTexture = theHatchAspect->TextureSet(aContext)->First();
|
|
||||||
const Handle(Graphic3d_TextureParams)& aTexParams = aTexture->Sampler()->Parameters();
|
|
||||||
|
|
||||||
aTexParams->SetScale (aPrevScale);
|
|
||||||
aTexParams->SetRotation (aPrevRotate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aContext->ModelWorldState.Pop();
|
aContext->ModelWorldState.Pop();
|
||||||
aContext->ApplyModelViewMatrix();
|
aContext->ApplyModelViewMatrix();
|
||||||
@@ -183,23 +86,13 @@ namespace
|
|||||||
const OpenGl_Structure& theStructure,
|
const OpenGl_Structure& theStructure,
|
||||||
const Handle(Graphic3d_ClipPlane)& theClipChain,
|
const Handle(Graphic3d_ClipPlane)& theClipChain,
|
||||||
const Standard_Integer theSubPlaneIndex,
|
const Standard_Integer theSubPlaneIndex,
|
||||||
const Handle(OpenGl_CappingPlaneResource)& thePlane,
|
const Handle(OpenGl_CappingPlaneResource)& thePlane)
|
||||||
const OpenGl_PrimitiveArray* theQuad)
|
|
||||||
{
|
{
|
||||||
const Standard_Integer aPrevFilter = theWorkspace->RenderFilter();
|
const Standard_Integer aPrevFilter = theWorkspace->RenderFilter();
|
||||||
const Standard_Integer anAnyFilter = aPrevFilter & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
|
const Standard_Integer anAnyFilter = aPrevFilter & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
|
||||||
|
|
||||||
const Handle(Graphic3d_ClipPlane)& aPlane = theClipChain;
|
|
||||||
|
|
||||||
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
||||||
const Handle(Graphic3d_Camera) aCamera = theWorkspace->View() != NULL
|
const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane();
|
||||||
? theWorkspace->View()->Camera()
|
|
||||||
: Handle(Graphic3d_Camera)();
|
|
||||||
const OpenGl_Mat4& aPlaneMat = OpenGl_Mat4::Map (aPlane->OrientationMatrix());
|
|
||||||
Standard_ShortReal aRotateAngle = 0.0;
|
|
||||||
Standard_ShortReal aViewScale = ShortRealLast();
|
|
||||||
OpenGl_Mat4 aRotateZoomMat;
|
|
||||||
|
|
||||||
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next())
|
for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next())
|
||||||
{
|
{
|
||||||
if (!aGroupIter.Value()->IsClosed())
|
if (!aGroupIter.Value()->IsClosed())
|
||||||
@@ -210,6 +103,16 @@ namespace
|
|||||||
// clear stencil only if something has been actually drawn
|
// clear stencil only if something has been actually drawn
|
||||||
theStencilSentry.Init();
|
theStencilSentry.Init();
|
||||||
|
|
||||||
|
// check if capping plane should be rendered within current pass (only opaque / only transparent)
|
||||||
|
const OpenGl_Aspects* anObjAspectFace = aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->GlAspects() : NULL;
|
||||||
|
thePlane->Update (aContext, anObjAspectFace != NULL ? anObjAspectFace->Aspect() : Handle(Graphic3d_Aspects)());
|
||||||
|
theWorkspace->SetAspects (thePlane->AspectFace());
|
||||||
|
theWorkspace->SetRenderFilter (aPrevFilter);
|
||||||
|
if (!theWorkspace->ShouldRender (&thePlane->Primitives()))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// suppress only opaque/transparent filter since for filling stencil the whole geometry should be drawn
|
// suppress only opaque/transparent filter since for filling stencil the whole geometry should be drawn
|
||||||
theWorkspace->SetRenderFilter (anAnyFilter);
|
theWorkspace->SetRenderFilter (anAnyFilter);
|
||||||
|
|
||||||
@@ -218,7 +121,7 @@ namespace
|
|||||||
aContext->ShaderManager()->UpdateClippingState();
|
aContext->ShaderManager()->UpdateClippingState();
|
||||||
|
|
||||||
glClear (GL_STENCIL_BUFFER_BIT);
|
glClear (GL_STENCIL_BUFFER_BIT);
|
||||||
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
const bool aColorMaskBack = aContext->SetColorMask (false);
|
||||||
|
|
||||||
// override aspects, disable culling
|
// override aspects, disable culling
|
||||||
theWorkspace->SetAspects (&theWorkspace->NoneCulling());
|
theWorkspace->SetAspects (&theWorkspace->NoneCulling());
|
||||||
@@ -237,7 +140,20 @@ namespace
|
|||||||
glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
|
glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
|
||||||
|
|
||||||
// render closed primitives
|
// render closed primitives
|
||||||
|
if (aRenderPlane->ToUseObjectProperties())
|
||||||
|
{
|
||||||
aGroupIter.Value()->Render (theWorkspace);
|
aGroupIter.Value()->Render (theWorkspace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; aGroupIter.More(); aGroupIter.Next())
|
||||||
|
{
|
||||||
|
if (aGroupIter.Value()->IsClosed())
|
||||||
|
{
|
||||||
|
aGroupIter.Value()->Render (theWorkspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// override material, cull back faces
|
// override material, cull back faces
|
||||||
theWorkspace->SetAspects (&theWorkspace->FrontCulling());
|
theWorkspace->SetAspects (&theWorkspace->FrontCulling());
|
||||||
@@ -248,7 +164,7 @@ namespace
|
|||||||
aContext->ShaderManager()->UpdateClippingState();
|
aContext->ShaderManager()->UpdateClippingState();
|
||||||
|
|
||||||
// render capping plane using the generated stencil mask
|
// render capping plane using the generated stencil mask
|
||||||
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
aContext->SetColorMask (aColorMaskBack);
|
||||||
if (theWorkspace->UseDepthWrite())
|
if (theWorkspace->UseDepthWrite())
|
||||||
{
|
{
|
||||||
glDepthMask (GL_TRUE);
|
glDepthMask (GL_TRUE);
|
||||||
@@ -260,66 +176,8 @@ namespace
|
|||||||
glEnable (GL_DEPTH_TEST);
|
glEnable (GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
const OpenGl_Aspects* aGroupAspectFace = aGroupIter.Value()->GlAspects();
|
theWorkspace->SetAspects (thePlane->AspectFace());
|
||||||
const OpenGl_CappingPlaneResource* aGroupAspectCapping = aGroupIter.Value()->AspectFillCapping();
|
renderPlane (theWorkspace, thePlane);
|
||||||
const OpenGl_CappingPlaneResource* anAspectCapping =
|
|
||||||
thePlane && (!aGroupAspectCapping || aGroupAspectCapping->Aspect().IsNull() || aPlane->ToOverrideCappingAspect())
|
|
||||||
? thePlane.get()
|
|
||||||
: aGroupAspectCapping;
|
|
||||||
|
|
||||||
if (anAspectCapping == NULL)
|
|
||||||
{
|
|
||||||
anAspectCapping = &THE_DEFAULT_ASPECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OpenGl_Aspects* anAspectFace = anAspectCapping->CappingFaceAspect (aGroupAspectFace);
|
|
||||||
const Standard_Boolean hasHatch = anAspectCapping->Aspect()->ToDrawHatch();
|
|
||||||
const OpenGl_Aspects* anAspectHatching = hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL;
|
|
||||||
const Standard_Boolean hasTextureHatch = hasHatch && !anAspectCapping->Aspect()->TextureHatch().IsNull();
|
|
||||||
const Standard_Boolean isRotatePers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchRotationPersistent();
|
|
||||||
const Standard_Boolean isZoomPers = hasTextureHatch && !aCamera.IsNull() && anAspectCapping->Aspect()->IsHatchZoomPersistent();
|
|
||||||
|
|
||||||
Standard_ShortReal aHatchScale = 1.0;
|
|
||||||
Standard_ShortReal aHatchAngle = 0.0;
|
|
||||||
|
|
||||||
if (isRotatePers || isZoomPers)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (isRotatePers)
|
|
||||||
{
|
|
||||||
if (aRotateAngle == 0.0)
|
|
||||||
{
|
|
||||||
const gp_Dir aPlaneSide (aPlaneMat.GetValue (0, 0), aPlaneMat.GetValue (1, 0), aPlaneMat.GetValue (2, 0));
|
|
||||||
const gp_Dir aPlaneUp (aPlaneMat.GetValue (0, 2), aPlaneMat.GetValue (1, 2), aPlaneMat.GetValue (2, 2));
|
|
||||||
const gp_Dir& aCameraUp = aCamera->Up();
|
|
||||||
const gp_Vec aCameraPln = aPlaneSide.Dot (aCameraUp) * aPlaneSide + aPlaneUp.Dot (aCameraUp) * aPlaneUp;
|
|
||||||
const gp_Dir& aCameraDir = aCamera->Direction();
|
|
||||||
aRotateAngle = static_cast<Standard_ShortReal> (aCameraPln.AngleWithRef (aPlaneUp, aCameraDir) / M_PI * 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
aHatchAngle = aRotateAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isZoomPers)
|
|
||||||
{
|
|
||||||
if (aViewScale == ShortRealLast())
|
|
||||||
{
|
|
||||||
const Standard_Real aFocus = aCamera->IsOrthographic()
|
|
||||||
? aCamera->Distance()
|
|
||||||
: (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative
|
|
||||||
? Standard_Real(aCamera->ZFocus() * aCamera->Distance())
|
|
||||||
: Standard_Real(aCamera->ZFocus()));
|
|
||||||
|
|
||||||
const gp_XYZ aViewDim = aCamera->ViewDimensions (aFocus);
|
|
||||||
aViewScale = static_cast<Standard_ShortReal> (aViewDim.Y() / aContext->Viewport()[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!anAspectHatching->TextureSet(aContext)->IsEmpty())
|
|
||||||
aHatchScale = 1.0f / (aViewScale * anAspectHatching->TextureSet(aContext)->First()->SizeY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSection (theWorkspace, theQuad, anAspectFace, hasHatch ? anAspectCapping->HatchingFaceAspect() : NULL, aPlaneMat, aHatchScale, aHatchAngle);
|
|
||||||
|
|
||||||
// turn on the current plane to restore initial state
|
// turn on the current plane to restore initial state
|
||||||
aContext->ChangeClipping().ResetCappingFilter();
|
aContext->ChangeClipping().ResetCappingFilter();
|
||||||
@@ -329,7 +187,7 @@ namespace
|
|||||||
|
|
||||||
if (theStructure.InstancedStructure() != NULL)
|
if (theStructure.InstancedStructure() != NULL)
|
||||||
{
|
{
|
||||||
renderCappingForStructure (theStencilSentry, theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane, theQuad);
|
renderCappingForStructure (theStencilSentry, theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,12 +206,6 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OpenGl_PrimitiveArray* aCappingQuad = initQuad (aContext);
|
|
||||||
if (!aCappingQuad)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember current aspect face defined in workspace
|
// remember current aspect face defined in workspace
|
||||||
const OpenGl_Aspects* aFaceAsp = theWorkspace->Aspects();
|
const OpenGl_Aspects* aFaceAsp = theWorkspace->Aspects();
|
||||||
|
|
||||||
@@ -362,16 +214,6 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
|
|||||||
theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_FillModeOnly);
|
theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_FillModeOnly);
|
||||||
StencilTestSentry aStencilSentry;
|
StencilTestSentry aStencilSentry;
|
||||||
|
|
||||||
GLboolean aPrevBlend = glIsEnabled (GL_BLEND);
|
|
||||||
GLint aPrevBlendSrc = GL_ONE;
|
|
||||||
GLint aPrevBlendDst = GL_ZERO;
|
|
||||||
if (aPrevBlend == GL_TRUE)
|
|
||||||
{
|
|
||||||
glGetIntegerv (GL_BLEND_SRC_ALPHA, &aPrevBlendSrc);
|
|
||||||
glGetIntegerv (GL_BLEND_DST_ALPHA, &aPrevBlendDst);
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate capping for every clip plane
|
// generate capping for every clip plane
|
||||||
for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next())
|
for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next())
|
||||||
{
|
{
|
||||||
@@ -387,32 +229,22 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
|
|||||||
for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
|
for (const Graphic3d_ClipPlane* aSubPlaneIter = aClipChain.get(); aSubPlaneIter != NULL; aSubPlaneIter = aSubPlaneIter->ChainNextPlane().get(), ++aSubPlaneIndex)
|
||||||
{
|
{
|
||||||
// get resource for the plane
|
// get resource for the plane
|
||||||
const TCollection_AsciiString& aResId = THE_PLANE_STYLE + aSubPlaneIter->GetId();
|
const TCollection_AsciiString& aResId = aSubPlaneIter->GetId();
|
||||||
Handle(OpenGl_CappingPlaneResource) aPlaneRes;
|
Handle(OpenGl_CappingPlaneResource) aPlaneRes;
|
||||||
if (!aContext->GetResource (aResId, aPlaneRes))
|
if (!aContext->GetResource (aResId, aPlaneRes))
|
||||||
{
|
{
|
||||||
// share and register for release once the resource is no longer used
|
// share and register for release once the resource is no longer used
|
||||||
aPlaneRes = new OpenGl_CappingPlaneResource (aSubPlaneIter->CappingSectionStyle());
|
aPlaneRes = new OpenGl_CappingPlaneResource (aSubPlaneIter);
|
||||||
aContext->ShareResource (aResId, aPlaneRes);
|
aContext->ShareResource (aResId, aPlaneRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCappingForStructure (aStencilSentry, theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes, aCappingQuad);
|
renderCappingForStructure (aStencilSentry, theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes);
|
||||||
|
|
||||||
// set delayed resource release
|
// set delayed resource release
|
||||||
aPlaneRes.Nullify();
|
aPlaneRes.Nullify();
|
||||||
if (!aResId.IsEmpty())
|
|
||||||
{
|
|
||||||
// schedule release of resource if not used
|
|
||||||
aContext->ReleaseResource (aResId, Standard_True);
|
aContext->ReleaseResource (aResId, Standard_True);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (aPrevBlend == GL_TRUE)
|
|
||||||
{
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
glBlendFunc (aPrevBlendSrc, aPrevBlendDst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore rendering aspects
|
// restore rendering aspects
|
||||||
theWorkspace->SetAspects (aFaceAsp);
|
theWorkspace->SetAspects (aFaceAsp);
|
||||||
|
@@ -56,28 +56,21 @@ namespace
|
|||||||
{ 0.0f, 0.0f, 0.0f, 1.0f } }
|
{ 0.0f, 0.0f, 0.0f, 1.0f } }
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle(Graphic3d_Aspects) defaultMaterial()
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_AspectFillArea3d) anAspect;
|
|
||||||
const Graphic3d_MaterialAspect aMaterial (Graphic3d_NOM_DEFAULT);
|
|
||||||
anAspect = new Graphic3d_AspectFillArea3d();
|
|
||||||
anAspect->SetDistinguishOff();
|
|
||||||
anAspect->SetFrontMaterial (aMaterial);
|
|
||||||
anAspect->SetInteriorStyle (Aspect_IS_SOLID);
|
|
||||||
anAspect->SetInteriorColor (aMaterial.Color());
|
|
||||||
anAspect->SetSuppressBackFaces (false);
|
|
||||||
return anAspect;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : BuildInfinitPlaneVertices
|
// function : OpenGl_CappingPlaneResource
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
OpenGl_PrimitiveArray* OpenGl_CappingPlaneResource::BuildInfinitPlaneVertices()
|
OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
|
||||||
|
: myPrimitives (NULL),
|
||||||
|
myOrientation (OpenGl_IdentityMatrix),
|
||||||
|
myAspect (NULL),
|
||||||
|
myPlaneRoot (thePlane),
|
||||||
|
myEquationMod ((unsigned int )-1),
|
||||||
|
myAspectMod ((unsigned int )-1)
|
||||||
{
|
{
|
||||||
OpenGl_PrimitiveArray* aPrimitives = NULL;
|
|
||||||
// Fill primitive array
|
// Fill primitive array
|
||||||
Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
|
Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
|
||||||
Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
|
Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc);
|
||||||
@@ -90,26 +83,8 @@ OpenGl_PrimitiveArray* OpenGl_CappingPlaneResource::BuildInfinitPlaneVertices()
|
|||||||
if (anAttribs->Init (12, anAttribInfo, 3))
|
if (anAttribs->Init (12, anAttribInfo, 3))
|
||||||
{
|
{
|
||||||
memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
|
memcpy (anAttribs->ChangeData(), THE_CAPPING_PLN_VERTS, sizeof(THE_CAPPING_PLN_VERTS));
|
||||||
|
myPrimitives.InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
|
||||||
aPrimitives = new OpenGl_PrimitiveArray (NULL);
|
|
||||||
aPrimitives->InitBuffers (NULL, Graphic3d_TOPA_TRIANGLES, NULL, anAttribs, NULL);
|
|
||||||
}
|
}
|
||||||
return aPrimitives;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================================================================
|
|
||||||
// function : OpenGl_CappingPlaneResource
|
|
||||||
// purpose :
|
|
||||||
// =======================================================================
|
|
||||||
OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_AspectFillCapping)& theAspect)
|
|
||||||
: myCappingAspect(),//defaultMaterial()),
|
|
||||||
myHatchingAspect(),//defaultMaterial()),
|
|
||||||
myHatchingState (0)
|
|
||||||
{
|
|
||||||
myCappingAspect.SetAspect (defaultMaterial());
|
|
||||||
myHatchingAspect.SetAspect (defaultMaterial());
|
|
||||||
|
|
||||||
SetAspect (theAspect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -118,83 +93,18 @@ OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
|
OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
|
||||||
{
|
{
|
||||||
|
Release (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : SetAspect
|
// function : Update
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_CappingPlaneResource::SetAspect (const Handle(Graphic3d_AspectFillCapping)& theAspect)
|
void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theCtx,
|
||||||
|
const Handle(Graphic3d_Aspects)& theObjAspect)
|
||||||
{
|
{
|
||||||
myAspect = theAspect;
|
updateTransform (theCtx);
|
||||||
|
updateAspect (theObjAspect);
|
||||||
if (theAspect.IsNull())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!theAspect->ToUseObjectMaterial()
|
|
||||||
|| !theAspect->ToUseObjectTexture()
|
|
||||||
|| !theAspect->ToUseObjectShader())
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_Aspects) aFillAspect = myCappingAspect.Aspect();
|
|
||||||
|
|
||||||
if (!theAspect->ToUseObjectMaterial())
|
|
||||||
{
|
|
||||||
aFillAspect->SetFrontMaterial (theAspect->Material());
|
|
||||||
aFillAspect->SetInteriorColor (theAspect->Material().Color());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!theAspect->ToUseObjectTexture())
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMap (theAspect->Texture());
|
|
||||||
|
|
||||||
if (!theAspect->Texture().IsNull())
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOff();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMap (Handle(Graphic3d_TextureMap)());
|
|
||||||
aFillAspect->SetTextureMapOff();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!theAspect->ToUseObjectShader())
|
|
||||||
{
|
|
||||||
aFillAspect->SetShaderProgram (theAspect->Shader());
|
|
||||||
}
|
|
||||||
|
|
||||||
myCappingAspect.SetAspect (aFillAspect);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theAspect->ToDrawHatch()
|
|
||||||
&& (theAspect->IsTextureHatch()
|
|
||||||
|| theAspect->IsStippleHatch()))
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_Aspects) aFillAspect = myHatchingAspect.Aspect();
|
|
||||||
|
|
||||||
aFillAspect->SetInteriorStyle (theAspect->IsStippleHatch() ? Aspect_IS_HATCH : Aspect_IS_SOLID);
|
|
||||||
aFillAspect->SetHatchStyle (theAspect->IsStippleHatch() ? theAspect->StippleHatch() : Handle(Graphic3d_HatchStyle)());
|
|
||||||
aFillAspect->SetTextureMap (theAspect->IsTextureHatch() ? theAspect->TextureHatch() : Handle(Graphic3d_TextureMap)());
|
|
||||||
aFillAspect->SetFrontMaterial (theAspect->HatchMaterial());
|
|
||||||
aFillAspect->SetInteriorColor (theAspect->HatchMaterial().Color());
|
|
||||||
if (theAspect->IsTextureHatch())
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOff();
|
|
||||||
}
|
|
||||||
|
|
||||||
myHatchingAspect.SetAspect (aFillAspect);
|
|
||||||
myHatchingState = theAspect->HatchingState();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -203,109 +113,123 @@ void OpenGl_CappingPlaneResource::SetAspect (const Handle(Graphic3d_AspectFillCa
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
|
void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
|
||||||
{
|
{
|
||||||
myCappingAspect .Release (theContext);
|
OpenGl_Element::Destroy (theContext, myAspect);
|
||||||
myHatchingAspect.Release (theContext);
|
myPrimitives.Release (theContext);
|
||||||
|
myEquationMod = (unsigned int )-1;
|
||||||
|
myAspectMod = (unsigned int )-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : CappingFaceAspect
|
// function : updateAspect
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
const OpenGl_Aspects* OpenGl_CappingPlaneResource::CappingFaceAspect (const OpenGl_Aspects* theObjectAspect) const
|
void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_Aspects)& theObjAspect)
|
||||||
{
|
{
|
||||||
if (myAspect.IsNull())
|
if (myAspect == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
myAspect = new OpenGl_Aspects();
|
||||||
|
myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle(Graphic3d_Aspects) aFillAspect = myCappingAspect.Aspect();
|
if (theObjAspect.IsNull())
|
||||||
|
{
|
||||||
|
if (myAspectMod != myPlaneRoot->MCountAspect())
|
||||||
|
{
|
||||||
|
myAspect->SetAspect (myPlaneRoot->CappingAspect());
|
||||||
|
myAspectMod = myPlaneRoot->MCountAspect();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (myAspect->ToUseObjectMaterial() && theObjectAspect != NULL)
|
if (myFillAreaAspect.IsNull())
|
||||||
|
{
|
||||||
|
myFillAreaAspect = new Graphic3d_AspectFillArea3d();
|
||||||
|
}
|
||||||
|
if (myAspectMod != myPlaneRoot->MCountAspect())
|
||||||
|
{
|
||||||
|
*myFillAreaAspect = *myPlaneRoot->CappingAspect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myPlaneRoot->ToUseObjectMaterial())
|
||||||
{
|
{
|
||||||
// only front material currently supported by capping rendering
|
// only front material currently supported by capping rendering
|
||||||
aFillAspect->SetFrontMaterial (theObjectAspect->Aspect()->FrontMaterial());
|
myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial());
|
||||||
aFillAspect->SetInteriorColor (theObjectAspect->Aspect()->InteriorColor());
|
myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor());
|
||||||
|
}
|
||||||
|
if (myPlaneRoot->ToUseObjectTexture())
|
||||||
|
{
|
||||||
|
myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
|
||||||
|
if (theObjAspect->ToMapTexture())
|
||||||
|
{
|
||||||
|
myFillAreaAspect->SetTextureMapOn();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aFillAspect->SetFrontMaterial (myAspect->Material());
|
myFillAreaAspect->SetTextureMapOff();
|
||||||
aFillAspect->SetInteriorColor (myAspect->Material().Color());
|
}
|
||||||
|
}
|
||||||
|
if (myPlaneRoot->ToUseObjectShader())
|
||||||
|
{
|
||||||
|
myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myAspect->ToUseObjectTexture() && theObjectAspect != NULL)
|
myAspect->SetAspect (myFillAreaAspect);
|
||||||
{
|
|
||||||
if (theObjectAspect->Aspect()->ToMapTexture())
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMap (theObjectAspect->Aspect()->TextureMap());
|
|
||||||
aFillAspect->SetTextureMapOn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOff();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMap (myAspect->Texture());
|
|
||||||
if (!myAspect->Texture().IsNull())
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetTextureMapOff();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myAspect->ToUseObjectShader() && theObjectAspect != NULL)
|
|
||||||
{
|
|
||||||
aFillAspect->SetShaderProgram (theObjectAspect->Aspect()->ShaderProgram());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aFillAspect->SetShaderProgram (myAspect->Shader());
|
|
||||||
}
|
|
||||||
|
|
||||||
myCappingAspect.SetAspect (aFillAspect);
|
|
||||||
|
|
||||||
return &myCappingAspect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : HatchingFaceAspect
|
// function : updateTransform
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
const OpenGl_Aspects* OpenGl_CappingPlaneResource::HatchingFaceAspect() const
|
void OpenGl_CappingPlaneResource::updateTransform (const Handle(OpenGl_Context)& theCtx)
|
||||||
{
|
{
|
||||||
if (myAspect.IsNull())
|
if (myEquationMod == myPlaneRoot->MCountEquation()
|
||||||
|
&& myLocalOrigin.IsEqual (theCtx->ShaderManager()->LocalOrigin(), gp::Resolution()))
|
||||||
{
|
{
|
||||||
return NULL;
|
return; // nothing to update
|
||||||
}
|
}
|
||||||
|
|
||||||
const Standard_Size aHatchingState = myAspect->HatchingState();
|
myEquationMod = myPlaneRoot->MCountEquation();
|
||||||
if (myHatchingState != aHatchingState)
|
myLocalOrigin = theCtx->ShaderManager()->LocalOrigin();
|
||||||
{
|
|
||||||
if (myAspect->ToDrawHatch())
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_Aspects) aFillAspect = myHatchingAspect.Aspect();
|
|
||||||
|
|
||||||
aFillAspect->SetInteriorStyle (myAspect->IsStippleHatch() ? Aspect_IS_HATCH : Aspect_IS_SOLID);
|
const Graphic3d_ClipPlane::Equation& anEq = myPlaneRoot->GetEquation();
|
||||||
aFillAspect->SetHatchStyle (myAspect->IsStippleHatch() ? myAspect->StippleHatch() : Handle(Graphic3d_HatchStyle)());
|
const Standard_Real anEqW = theCtx->ShaderManager()->LocalClippingPlaneW (*myPlaneRoot);
|
||||||
aFillAspect->SetTextureMap (myAspect->IsTextureHatch() ? myAspect->TextureHatch() : Handle(Graphic3d_TextureMap)());
|
|
||||||
aFillAspect->SetFrontMaterial (myAspect->HatchMaterial());
|
// re-evaluate infinite plane transformation matrix
|
||||||
aFillAspect->SetInteriorColor (myAspect->HatchMaterial().Color());
|
const Graphic3d_Vec3 aNorm (anEq.xyz());
|
||||||
if (myAspect->IsTextureHatch())
|
const Graphic3d_Vec3 T (anEq.xyz() * -anEqW);
|
||||||
|
|
||||||
|
// project plane normal onto OX to find left vector
|
||||||
|
const Standard_ShortReal aProjLen = sqrt ((Standard_ShortReal)anEq.xz().SquareModulus());
|
||||||
|
Graphic3d_Vec3 aLeft;
|
||||||
|
if (aProjLen < ShortRealSmall())
|
||||||
{
|
{
|
||||||
aFillAspect->SetTextureMapOn();
|
aLeft[0] = 1.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aFillAspect->SetTextureMapOff();
|
aLeft[0] = aNorm[2] / aProjLen;
|
||||||
}
|
aLeft[2] = -aNorm[0] / aProjLen;
|
||||||
myHatchingAspect.SetAspect (aFillAspect);
|
|
||||||
myHatchingState = aHatchingState;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &myHatchingAspect;
|
const Graphic3d_Vec3 F = Graphic3d_Vec3::Cross (-aLeft, aNorm);
|
||||||
|
|
||||||
|
myOrientation.mat[0][0] = aLeft[0];
|
||||||
|
myOrientation.mat[0][1] = aLeft[1];
|
||||||
|
myOrientation.mat[0][2] = aLeft[2];
|
||||||
|
myOrientation.mat[0][3] = 0.0f;
|
||||||
|
|
||||||
|
myOrientation.mat[1][0] = aNorm[0];
|
||||||
|
myOrientation.mat[1][1] = aNorm[1];
|
||||||
|
myOrientation.mat[1][2] = aNorm[2];
|
||||||
|
myOrientation.mat[1][3] = 0.0f;
|
||||||
|
|
||||||
|
myOrientation.mat[2][0] = F[0];
|
||||||
|
myOrientation.mat[2][1] = F[1];
|
||||||
|
myOrientation.mat[2][2] = F[2];
|
||||||
|
myOrientation.mat[2][3] = 0.0f;
|
||||||
|
|
||||||
|
myOrientation.mat[3][0] = T[0];
|
||||||
|
myOrientation.mat[3][1] = T[1];
|
||||||
|
myOrientation.mat[3][2] = T[2];
|
||||||
|
myOrientation.mat[3][3] = 1.0f;
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
#include <OpenGl_Resource.hxx>
|
#include <OpenGl_Resource.hxx>
|
||||||
#include <OpenGl_Aspects.hxx>
|
#include <OpenGl_Aspects.hxx>
|
||||||
#include <OpenGl_Matrix.hxx>
|
#include <OpenGl_Matrix.hxx>
|
||||||
#include <Graphic3d_AspectFillCapping.hxx>
|
#include <Graphic3d_ClipPlane.hxx>
|
||||||
|
|
||||||
class OpenGl_CappingPlaneResource;
|
class OpenGl_CappingPlaneResource;
|
||||||
DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
|
DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
|
||||||
@@ -30,23 +30,25 @@ DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
|
|||||||
//! This resource holds data necessary for OpenGl_CappingAlgo.
|
//! This resource holds data necessary for OpenGl_CappingAlgo.
|
||||||
//! This object is implemented as OpenGl resource for the following reasons:
|
//! This object is implemented as OpenGl resource for the following reasons:
|
||||||
//! - one instance should be shared between contexts.
|
//! - one instance should be shared between contexts.
|
||||||
//! - instance associated to Graphic3d_AspectFillCapping data.
|
//! - instance associated to Graphic3d_ClipPlane data by id.
|
||||||
//! - should created and released within context (owns OpenGl elements and resources).
|
//! - should created and released within context (owns OpenGl elements and resources).
|
||||||
class OpenGl_CappingPlaneResource : public OpenGl_Resource
|
class OpenGl_CappingPlaneResource : public OpenGl_Resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Create and assign style.
|
//! Constructor.
|
||||||
Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_AspectFillCapping)& theAspect);
|
//! Create capping plane presentation associated to clipping plane data.
|
||||||
|
//! @param thePlane [in] the plane data.
|
||||||
|
Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane);
|
||||||
|
|
||||||
//! Destroy object.
|
//! Destroy object.
|
||||||
Standard_EXPORT virtual ~OpenGl_CappingPlaneResource();
|
Standard_EXPORT virtual ~OpenGl_CappingPlaneResource();
|
||||||
|
|
||||||
//! Assign section style.
|
//! Update resource data in the passed context.
|
||||||
Standard_EXPORT void SetAspect (const Handle(Graphic3d_AspectFillCapping)& theAspect);
|
//! @param theContext [in] the context
|
||||||
|
//! @param theObjAspect [in] object aspect
|
||||||
//! Returns section style parameters.
|
Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext,
|
||||||
const Handle(Graphic3d_AspectFillCapping)& Aspect() const { return myAspect; }
|
const Handle(Graphic3d_Aspects)& theObjAspect);
|
||||||
|
|
||||||
//! Release associated OpenGl resources.
|
//! Release associated OpenGl resources.
|
||||||
//! @param theContext [in] the resource context.
|
//! @param theContext [in] the resource context.
|
||||||
@@ -55,23 +57,17 @@ public:
|
|||||||
//! Returns estimated GPU memory usage - not implemented.
|
//! Returns estimated GPU memory usage - not implemented.
|
||||||
virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE { return 0; }
|
virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE { return 0; }
|
||||||
|
|
||||||
|
//! Return parent clipping plane structure.
|
||||||
|
const Handle(Graphic3d_ClipPlane)& Plane() const { return myPlaneRoot; }
|
||||||
|
|
||||||
|
//! @return aspect face for rendering capping surface.
|
||||||
|
inline const OpenGl_Aspects* AspectFace() const { return myAspect; }
|
||||||
|
|
||||||
|
//! @return evaluated orientation matrix to transform infinite plane.
|
||||||
|
inline const OpenGl_Matrix* Orientation() const { return &myOrientation; }
|
||||||
|
|
||||||
//! @return primitive array of vertices to render infinite plane.
|
//! @return primitive array of vertices to render infinite plane.
|
||||||
static OpenGl_PrimitiveArray* BuildInfinitPlaneVertices();
|
inline const OpenGl_PrimitiveArray& Primitives() const { return myPrimitives; }
|
||||||
|
|
||||||
//! Returns true if capping should draw hatch layer.
|
|
||||||
Standard_Boolean ToDrawHatch() const
|
|
||||||
{
|
|
||||||
return myAspect->ToDrawHatch()
|
|
||||||
&& (myAspect->IsStippleHatch()
|
|
||||||
|| myAspect->IsTextureHatch());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns the shading aspect for drawing face of a clipping section itself.
|
|
||||||
//! @param theObjectAspect [in] the aspect of an object if it requires combining.
|
|
||||||
Standard_EXPORT const OpenGl_Aspects* CappingFaceAspect (const OpenGl_Aspects* theObjectAspect) const;
|
|
||||||
|
|
||||||
//! Returns the shading aspect for drawing hatch layer of a section.
|
|
||||||
Standard_EXPORT const OpenGl_Aspects* HatchingFaceAspect() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -83,11 +79,14 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Handle(Graphic3d_AspectFillCapping) myAspect; //!< Section style settings from application's level.
|
OpenGl_PrimitiveArray myPrimitives; //!< vertices and texture coordinates for rendering
|
||||||
mutable OpenGl_Aspects myCappingAspect; //!< GL aspect for shading base layer of a capping section.
|
OpenGl_Matrix myOrientation; //!< plane transformation matrix.
|
||||||
mutable OpenGl_Aspects myHatchingAspect; //!< GL aspect for shading hatching layer (additional to base) of a capping section.
|
OpenGl_Aspects* myAspect; //!< capping face aspect.
|
||||||
mutable Standard_Size myHatchingState;
|
Handle(Graphic3d_ClipPlane) myPlaneRoot; //!< parent clipping plane structure.
|
||||||
|
Handle(Graphic3d_Aspects) myFillAreaAspect;//!< own capping aspect
|
||||||
gp_XYZ myLocalOrigin; //!< layer origin
|
gp_XYZ myLocalOrigin; //!< layer origin
|
||||||
|
unsigned int myEquationMod; //!< modification counter for plane equation.
|
||||||
|
unsigned int myAspectMod; //!< modification counter for aspect.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
#include <Standard_Assert.hxx>
|
#include <Standard_Assert.hxx>
|
||||||
#include <TCollection_ExtendedString.hxx>
|
#include <TCollection_ExtendedString.hxx>
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Font,OpenGl_Resource)
|
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Font,OpenGl_Resource)
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -34,8 +33,6 @@ OpenGl_Font::OpenGl_Font (const Handle(Font_FTFont)& theFont,
|
|||||||
myFont (theFont),
|
myFont (theFont),
|
||||||
myAscender (0.0f),
|
myAscender (0.0f),
|
||||||
myDescender (0.0f),
|
myDescender (0.0f),
|
||||||
myLineSpacing (0.0f),
|
|
||||||
myTileSizeX (0),
|
|
||||||
myTileSizeY (0),
|
myTileSizeY (0),
|
||||||
myLastTileId (-1),
|
myLastTileId (-1),
|
||||||
myTextureFormat (GL_ALPHA)
|
myTextureFormat (GL_ALPHA)
|
||||||
@@ -107,9 +104,7 @@ bool OpenGl_Font::Init (const Handle(OpenGl_Context)& theCtx)
|
|||||||
|
|
||||||
myAscender = myFont->Ascender();
|
myAscender = myFont->Ascender();
|
||||||
myDescender = myFont->Descender();
|
myDescender = myFont->Descender();
|
||||||
myLineSpacing = myFont->LineSpacing();
|
myTileSizeY = myFont->GlyphMaxSizeY (true);
|
||||||
myTileSizeX = myFont->GlyphMaxSizeX();
|
|
||||||
myTileSizeY = myFont->GlyphMaxSizeY();
|
|
||||||
|
|
||||||
myLastTileId = -1;
|
myLastTileId = -1;
|
||||||
if (!createTexture (theCtx))
|
if (!createTexture (theCtx))
|
||||||
@@ -126,12 +121,16 @@ bool OpenGl_Font::Init (const Handle(OpenGl_Context)& theCtx)
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
|
bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
|
||||||
{
|
{
|
||||||
|
// Single font might define very wide range of symbols, with very few of them actually used in text.
|
||||||
|
// Limit single texture with circa 4096 glyphs.
|
||||||
|
static const Standard_Integer THE_MAX_GLYPHS_PER_TEXTURE = 4096;
|
||||||
|
|
||||||
|
myTileSizeY = myFont->GlyphMaxSizeY (true);
|
||||||
|
const Standard_Integer aGlyphsNb = Min (THE_MAX_GLYPHS_PER_TEXTURE, myFont->GlyphsNumber (true) - myLastTileId + 1);
|
||||||
|
const Standard_Integer aMaxTileSizeX = myFont->GlyphMaxSizeX (true);
|
||||||
const Standard_Integer aMaxSize = theCtx->MaxTextureSize();
|
const Standard_Integer aMaxSize = theCtx->MaxTextureSize();
|
||||||
|
const Standard_Integer aTextureSizeX = OpenGl_Context::GetPowerOfTwo (aGlyphsNb * aMaxTileSizeX, aMaxSize);
|
||||||
Standard_Integer aGlyphsNb = myFont->GlyphsNumber() - myLastTileId + 1;
|
const Standard_Integer aTilesPerRow = aTextureSizeX / aMaxTileSizeX;
|
||||||
|
|
||||||
const Standard_Integer aTextureSizeX = OpenGl_Context::GetPowerOfTwo (aGlyphsNb * myTileSizeX, aMaxSize);
|
|
||||||
const Standard_Integer aTilesPerRow = aTextureSizeX / myTileSizeX;
|
|
||||||
const Standard_Integer aTextureSizeY = OpenGl_Context::GetPowerOfTwo (GLint((aGlyphsNb / aTilesPerRow) + 1) * myTileSizeY, aMaxSize);
|
const Standard_Integer aTextureSizeY = OpenGl_Context::GetPowerOfTwo (GLint((aGlyphsNb / aTilesPerRow) + 1) * myTileSizeY, aMaxSize);
|
||||||
|
|
||||||
memset (&myLastTilePx, 0, sizeof(myLastTilePx));
|
memset (&myLastTilePx, 0, sizeof(myLastTilePx));
|
||||||
@@ -186,14 +185,18 @@ bool OpenGl_Font::renderGlyph (const Handle(OpenGl_Context)& theCtx,
|
|||||||
const Standard_Integer aTileId = myLastTileId + 1;
|
const Standard_Integer aTileId = myLastTileId + 1;
|
||||||
myLastTilePx.Left = myLastTilePx.Right + 3;
|
myLastTilePx.Left = myLastTilePx.Right + 3;
|
||||||
myLastTilePx.Right = myLastTilePx.Left + (Standard_Integer )anImg.SizeX();
|
myLastTilePx.Right = myLastTilePx.Left + (Standard_Integer )anImg.SizeX();
|
||||||
if (myLastTilePx.Right >= aTexture->SizeX())
|
if (myLastTilePx.Right > aTexture->SizeX()
|
||||||
|
|| (Standard_Integer )anImg.SizeY() > myTileSizeY)
|
||||||
{
|
{
|
||||||
|
myTileSizeY = myFont->GlyphMaxSizeY (true);
|
||||||
|
|
||||||
myLastTilePx.Left = 0;
|
myLastTilePx.Left = 0;
|
||||||
myLastTilePx.Right = (Standard_Integer )anImg.SizeX();
|
myLastTilePx.Right = (Standard_Integer )anImg.SizeX();
|
||||||
myLastTilePx.Top += myTileSizeY;
|
myLastTilePx.Top += myTileSizeY;
|
||||||
myLastTilePx.Bottom += myTileSizeY;
|
myLastTilePx.Bottom += myTileSizeY;
|
||||||
|
|
||||||
if (myLastTilePx.Bottom >= aTexture->SizeY())
|
if (myLastTilePx.Bottom > aTexture->SizeY()
|
||||||
|
|| myLastTilePx.Right > aTexture->SizeX())
|
||||||
{
|
{
|
||||||
if (!createTexture (theCtx))
|
if (!createTexture (theCtx))
|
||||||
{
|
{
|
||||||
|
@@ -106,12 +106,6 @@ public:
|
|||||||
return myDescender;
|
return myDescender;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return default line spacing (the baseline-to-baseline distance)
|
|
||||||
inline float LineSpacing() const
|
|
||||||
{
|
|
||||||
return myLineSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Render glyph to texture if not already.
|
//! Render glyph to texture if not already.
|
||||||
//! @param theCtx active context
|
//! @param theCtx active context
|
||||||
//! @param theUChar unicode symbol to render
|
//! @param theUChar unicode symbol to render
|
||||||
@@ -135,8 +129,6 @@ protected:
|
|||||||
Handle(Font_FTFont) myFont; //!< FreeType font instance
|
Handle(Font_FTFont) myFont; //!< FreeType font instance
|
||||||
Standard_ShortReal myAscender; //!< ascender provided my FT font
|
Standard_ShortReal myAscender; //!< ascender provided my FT font
|
||||||
Standard_ShortReal myDescender; //!< descender provided my FT font
|
Standard_ShortReal myDescender; //!< descender provided my FT font
|
||||||
Standard_ShortReal myLineSpacing; //!< line spacing provided my FT font
|
|
||||||
Standard_Integer myTileSizeX; //!< tile width
|
|
||||||
Standard_Integer myTileSizeY; //!< tile height
|
Standard_Integer myTileSizeY; //!< tile height
|
||||||
Standard_Integer myLastTileId; //!< id of last tile
|
Standard_Integer myLastTileId; //!< id of last tile
|
||||||
RectI myLastTilePx;
|
RectI myLastTilePx;
|
||||||
|
@@ -25,7 +25,6 @@
|
|||||||
#include <OpenGl_Workspace.hxx>
|
#include <OpenGl_Workspace.hxx>
|
||||||
|
|
||||||
#include <Graphic3d_ArrayOfPrimitives.hxx>
|
#include <Graphic3d_ArrayOfPrimitives.hxx>
|
||||||
#include <Graphic3d_AspectFillCapping.hxx>
|
|
||||||
#include <Graphic3d_GroupDefinitionError.hxx>
|
#include <Graphic3d_GroupDefinitionError.hxx>
|
||||||
|
|
||||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
|
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
|
||||||
@@ -91,20 +90,6 @@ void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_Aspects)& th
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!theAspect.IsNull() && theAspect->IsKind (STANDARD_TYPE(Graphic3d_AspectFillCapping)))
|
|
||||||
{
|
|
||||||
Handle(Graphic3d_AspectFillCapping) aFillCappingAspect = Handle(Graphic3d_AspectFillCapping)::DownCast (theAspect);
|
|
||||||
if (myAspectFillCapping == NULL)
|
|
||||||
{
|
|
||||||
myAspectFillCapping = new OpenGl_CappingPlaneResource (aFillCappingAspect);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
myAspectFillCapping->SetAspect (aFillCappingAspect);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (myAspects == NULL)
|
if (myAspects == NULL)
|
||||||
{
|
{
|
||||||
myAspects = new OpenGl_Aspects (theAspect);
|
myAspects = new OpenGl_Aspects (theAspect);
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <NCollection_List.hxx>
|
#include <NCollection_List.hxx>
|
||||||
#include <OpenGl_Aspects.hxx>
|
#include <OpenGl_Aspects.hxx>
|
||||||
#include <OpenGl_CappingPlaneResource.hxx>
|
|
||||||
#include <OpenGl_Element.hxx>
|
#include <OpenGl_Element.hxx>
|
||||||
|
|
||||||
class OpenGl_Group;
|
class OpenGl_Group;
|
||||||
@@ -118,17 +117,6 @@ public:
|
|||||||
//! Is the group ray-tracable (contains ray-tracable elements)?
|
//! Is the group ray-tracable (contains ray-tracable elements)?
|
||||||
Standard_Boolean IsRaytracable() const { return myIsRaytracable; }
|
Standard_Boolean IsRaytracable() const { return myIsRaytracable; }
|
||||||
|
|
||||||
//! Returns section style aspect.
|
|
||||||
virtual Handle(Graphic3d_AspectFillCapping) FillCappingAspect() const Standard_OVERRIDE
|
|
||||||
{
|
|
||||||
return myAspectFillCapping != NULL
|
|
||||||
? myAspectFillCapping->Aspect()
|
|
||||||
: Handle(Graphic3d_AspectFillCapping)();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns OpenGL capping filling aspect.
|
|
||||||
const OpenGl_CappingPlaneResource* AspectFillCapping() const { return myAspectFillCapping; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Standard_EXPORT virtual ~OpenGl_Group();
|
Standard_EXPORT virtual ~OpenGl_Group();
|
||||||
@@ -136,7 +124,6 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
OpenGl_Aspects* myAspects;
|
OpenGl_Aspects* myAspects;
|
||||||
OpenGl_CappingPlaneResource* myAspectFillCapping;
|
|
||||||
OpenGl_ElementNode* myFirst;
|
OpenGl_ElementNode* myFirst;
|
||||||
OpenGl_ElementNode* myLast;
|
OpenGl_ElementNode* myLast;
|
||||||
Standard_Boolean myIsRaytracable;
|
Standard_Boolean myIsRaytracable;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user