mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
828a75f228 | ||
|
59515ca600 | ||
|
fa1710b567 | ||
|
9460f8c0b9 | ||
|
a3a3ff3d33 | ||
|
2108d9a25b | ||
|
e8dec5e171 | ||
|
0dab581700 | ||
|
1c728f2d6d | ||
|
6b9b7e3c92 | ||
|
7c08e3ac6e | ||
|
718d07fe5e | ||
|
bc28da5c3a | ||
|
2fb08f0132 | ||
|
b8d92a7f8f | ||
|
f6abd02cdc | ||
|
943b4e5b95 | ||
|
c55c8fe929 | ||
|
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")
|
||||
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
|
||||
if (CAN_USE_EIGEN)
|
||||
set (USE_EIGEN OFF CACHE BOOL "${USE_EIGEN_DESCR}")
|
||||
|
@@ -440,4 +440,6 @@ t TKVCAF
|
||||
n XCAFView
|
||||
n XCAFNoteObjects
|
||||
t TKRWMesh
|
||||
n RWGltf
|
||||
n RWMesh
|
||||
n RWObj
|
||||
|
@@ -73,7 +73,7 @@ if (WIN32)
|
||||
set (CSF_OpenGlLibs "opengl32.lib")
|
||||
endif()
|
||||
|
||||
else()
|
||||
else()
|
||||
|
||||
if (APPLE)
|
||||
set (CSF_objc "objc")
|
||||
@@ -117,5 +117,6 @@ if (WIN32)
|
||||
endif()
|
||||
set (CSF_XwLibs "X11 Xext Xmu Xi")
|
||||
set (CSF_dl "dl")
|
||||
set (CSF_fontconfig "fontconfig")
|
||||
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_FREETYPE "FreeType binaries")
|
||||
INSTALL_MESSAGE (INSTALL_TBB "TBB binaries")
|
||||
INSTALL_MESSAGE (INSTALL_RAPIDJSON "RapidJSON header files")
|
||||
INSTALL_MESSAGE (INSTALL_TCL "TCL binaries")
|
||||
INSTALL_MESSAGE (INSTALL_TK "TK 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
|
||||
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
|
||||
"Indicates whether EGL should be used in OCCT visualization
|
||||
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"}
|
||||
}
|
||||
if { "$::HAVE_RAPIDJSON" == "true" } {
|
||||
wokdep:SearchRapidJson anIncErrs anLib32Errs anLib64Errs anBin32Errs anBin64Errs
|
||||
}
|
||||
|
||||
if { "$::CHECK_QT4" == "true" } {
|
||||
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
|
||||
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
|
||||
ttk::label .myFrame.myChecks.myQt4Lbl -text "Search Qt4"
|
||||
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.myZLibLbl -row $aCheckRowIter -column 7 -sticky w
|
||||
|
||||
grid .myFrame.myChecks.myQt4Check -row $aCheckRowIter -column 10 -sticky e
|
||||
grid .myFrame.myChecks.myQt4Lbl -row $aCheckRowIter -column 11 -sticky w
|
||||
grid .myFrame.myChecks.myQt4Check -row $aCheckRowIter -column 12 -sticky e
|
||||
grid .myFrame.myChecks.myQt4Lbl -row $aCheckRowIter -column 13 -sticky w
|
||||
|
||||
incr aCheckRowIter
|
||||
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.myLzmaLbl -row $aCheckRowIter -column 7 -sticky w
|
||||
grid .myFrame.myChecks.myJDKCheck -row $aCheckRowIter -column 10 -sticky e
|
||||
grid .myFrame.myChecks.myJDKLbl -row $aCheckRowIter -column 11 -sticky w
|
||||
grid .myFrame.myChecks.myJDKCheck -row $aCheckRowIter -column 12 -sticky e
|
||||
grid .myFrame.myChecks.myJDKLbl -row $aCheckRowIter -column 13 -sticky w
|
||||
|
||||
incr aCheckRowIter
|
||||
if { "$::tcl_platform(os)" == "Darwin" } {
|
||||
@@ -588,6 +594,10 @@ if { "$::tcl_platform(os)" == "Darwin" } {
|
||||
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
|
||||
grid .myFrame.myIncLbl -row $aRowIter -column 0 -columnspan 10 -sticky w
|
||||
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
|
||||
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 {
|
||||
set ${anEnvIter} "false"
|
||||
if { [info exists ::env(${anEnvIter})] } {
|
||||
@@ -858,6 +858,25 @@ proc wokdep:SearchGLES {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin6
|
||||
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
|
||||
proc wokdep:VtkVersion { thePath } {
|
||||
set aResult "6.1"
|
||||
|
@@ -1393,6 +1393,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
|
||||
set aLibsMap(CSF_TclTkLibs) ""
|
||||
set aLibsMap(CSF_QT) "QtCore QtGui"
|
||||
} else {
|
||||
set aLibsMap(CSF_fontconfig) "fontconfig"
|
||||
if { "$theOS" == "qnx" } {
|
||||
# CSF_ThreadLibs - pthread API is part of libc on QNX
|
||||
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
||||
|
@@ -63,6 +63,7 @@ win32 {
|
||||
CSF_TclTkLibs = -lX11 -ltk8.6
|
||||
CSF_XwLibs = -lX11 -lXext -lXmu -lXi
|
||||
CSF_MotifLibs = -lX11
|
||||
CSF_fontconfig = -lfontconfig
|
||||
HAVE_GLES2 { CSF_OpenGlLibs = -lEGL -lGLESv2 }
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@ set "HAVE_GLES2=false"
|
||||
set "HAVE_D3D=false"
|
||||
set "HAVE_ZLIB=false"
|
||||
set "HAVE_LIBLZMA=false"
|
||||
set "HAVE_RAPIDJSON=false"
|
||||
set "CSF_OPT_INC="
|
||||
set "CSF_OPT_LIB32="
|
||||
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_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_RAPIDJSON%"] == ["true"] set "PRODUCTS_DEFINES=%PRODUCTS_DEFINES% -DHAVE_RAPIDJSON" & set "CSF_DEFINES=HAVE_RAPIDJSON;%CSF_DEFINES%"
|
||||
|
||||
rem Eliminate VS warning
|
||||
if ["%CSF_DEFINES%"] == [""] set "CSF_DEFINES=;"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.6 KiB |
@@ -878,7 +878,18 @@ The test grid name is constructed depending on the type of the tested chamfers.
|
||||
| dist_angle_complex | | Distance from edge and given angle |
|
||||
| dist_angle_sequence | | Distance from edge and given angle |
|
||||
|
||||
@subsubsection testmanual_5_1_7 demo
|
||||
@subsubsection testmanual_5_1_7 de
|
||||
|
||||
This group tests reading and writing of CAD data files (iges, step) to and from OCCT.
|
||||
|
||||
Test cases check transfer status, shape and attributes against expected reference values.
|
||||
|
||||
| Grid | Commands | Functionality |
|
||||
| :---- | :----- | :------- |
|
||||
| iges_1, iges_2, iges_3 | igesbrep, brepiges, ReadIges, WriteIges | IGES tests |
|
||||
| step_1, step_2, step_3, step_4, step_5 | stepread, stepwrite, ReadStep, WriteStep | STEP tests |
|
||||
|
||||
@subsubsection testmanual_5_1_8 demo
|
||||
|
||||
This group allows demonstrating how testing cases are created, and testing DRAW commands and the test system as a whole.
|
||||
|
||||
@@ -889,7 +900,7 @@ This group allows demonstrating how testing cases are created, and testing DRAW
|
||||
| samples | | OCCT samples |
|
||||
|
||||
|
||||
@subsubsection testmanual_5_1_8 draft
|
||||
@subsubsection testmanual_5_1_9 draft
|
||||
|
||||
This group allows testing draft operations.
|
||||
|
||||
@@ -900,7 +911,7 @@ DRAW module: MODELING.
|
||||
| Angle | depouille | Drafts with angle (inclined walls) |
|
||||
|
||||
|
||||
@subsubsection testmanual_5_1_9 feat
|
||||
@subsubsection testmanual_5_1_10 feat
|
||||
|
||||
This group allows testing creation of features on a shape.
|
||||
|
||||
@@ -914,7 +925,7 @@ DRAW module: MODELING (package *BRepTest*).
|
||||
| featrevol | | |
|
||||
| featrf | | |
|
||||
|
||||
@subsubsection testmanual_5_1_10 heal
|
||||
@subsubsection testmanual_5_1_11 heal
|
||||
|
||||
This group allows testing the functionality provided by *ShapeHealing* toolkit.
|
||||
|
||||
@@ -943,7 +954,7 @@ DRAW module: XSDRAW
|
||||
| surface_to_revolution_standard | DT_ShapeConvertRev | Convert elementary surfaces to revolutions, simple cases |
|
||||
| update_tolerance_locked | updatetolerance | Update the tolerance of shape so that it satisfy the rule: toler(face)<=toler(edge)<=toler(vertex) |
|
||||
|
||||
@subsubsection testmanual_5_1_11 mesh
|
||||
@subsubsection testmanual_5_1_12 mesh
|
||||
|
||||
This group allows testing shape tessellation (*BRepMesh*) and shading.
|
||||
|
||||
@@ -960,7 +971,7 @@ DRAW modules: MODELING (package *MeshTest*), VISUALIZATION (package *ViewerTest*
|
||||
| advanced_incmesh_parallel | incmesh | Meshing of complex shapes, parallel mode |
|
||||
| standard_incmesh_parallel | incmesh | Meshing of simple shapes, parallel mode |
|
||||
|
||||
@subsubsection testmanual_5_1_12 mkface
|
||||
@subsubsection testmanual_5_1_13 mkface
|
||||
|
||||
This group allows testing creation of simple surfaces.
|
||||
|
||||
@@ -975,7 +986,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| after_revsurf_and_offset | mkface | |
|
||||
| mkplane | mkplane | |
|
||||
|
||||
@subsubsection testmanual_5_1_13 nproject
|
||||
@subsubsection testmanual_5_1_14 nproject
|
||||
|
||||
This group allows testing normal projection of edges and wires onto a face.
|
||||
|
||||
@@ -985,7 +996,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| :---- | :----- | :------- |
|
||||
| Base | nproject | |
|
||||
|
||||
@subsubsection testmanual_5_1_14 offset
|
||||
@subsubsection testmanual_5_1_15 offset
|
||||
|
||||
This group allows testing offset functionality for curves and surfaces.
|
||||
|
||||
@@ -1001,7 +1012,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| shape | offsetshape | |
|
||||
| wire_closed_outside_0_005, wire_closed_outside_0_025, wire_closed_outside_0_075, wire_closed_inside_0_005, wire_closed_inside_0_025, wire_closed_inside_0_075, wire_unclosed_outside_0_005, wire_unclosed_outside_0_025, wire_unclosed_outside_0_075 | mkoffset | 2d offset of closed and unclosed planar wires with different offset step and directions of offset ( inside / outside ) |
|
||||
|
||||
@subsubsection testmanual_5_1_15 pipe
|
||||
@subsubsection testmanual_5_1_16 pipe
|
||||
|
||||
This group allows testing construction of pipes (sweeping of a contour along profile).
|
||||
|
||||
@@ -1011,7 +1022,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| :---- | :----- | :------- |
|
||||
| Standard | pipe | |
|
||||
|
||||
@subsubsection testmanual_5_1_16 prism
|
||||
@subsubsection testmanual_5_1_17 prism
|
||||
|
||||
This group allows testing construction of prisms.
|
||||
|
||||
@@ -1021,7 +1032,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| :---- | :----- | :------- |
|
||||
| seminf | prism | |
|
||||
|
||||
@subsubsection testmanual_5_1_17 sewing
|
||||
@subsubsection testmanual_5_1_18 sewing
|
||||
|
||||
This group allows testing sewing of faces by connecting edges.
|
||||
|
||||
@@ -1033,7 +1044,7 @@ DRAW module: MODELING (package *BRepTest*)
|
||||
| tol_1 | sewing | Sewing faces with tolerance 1 |
|
||||
| tol_100 | sewing | Sewing faces with tolerance 100 |
|
||||
|
||||
@subsubsection testmanual_5_1_18 thrusection
|
||||
@subsubsection testmanual_5_1_19 thrusection
|
||||
|
||||
This group allows testing construction of shell or a solid passing through a set of sections in a given sequence (loft).
|
||||
|
||||
@@ -1042,7 +1053,7 @@ This group allows testing construction of shell or a solid passing through a set
|
||||
| solids | thrusection | Lofting with resulting solid |
|
||||
| not_solids | thrusection | Lofting with resulting shell or face |
|
||||
|
||||
@subsubsection testmanual_5_1_19 xcaf
|
||||
@subsubsection testmanual_5_1_20 xcaf
|
||||
|
||||
This group allows testing extended data exchange packages.
|
||||
|
||||
|
@@ -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/ |
|
||||
| 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 |
|
||||
| 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/ |
|
||||
| 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 |
|
||||
|
@@ -5595,7 +5595,7 @@ Draw provides command to create curves and surfaces by approximation.
|
||||
* **appro** fits a curve through 3d points;
|
||||
* **surfapp** and **grilapp** fit a surface through 3d points by approximation;
|
||||
* **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
|
||||
|
||||
|
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>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
|
||||
|
||||
|
@@ -783,6 +783,7 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
BRepAdaptor_Surface surf1( aFace );
|
||||
Handle( Adaptor3d_HSurface ) surf2;
|
||||
Standard_Boolean isOffset = Standard_False;
|
||||
Offset = 0.0;
|
||||
|
||||
if (surf1.GetType() == GeomAbs_OffsetSurface)
|
||||
{
|
||||
@@ -801,7 +802,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aPlane = surf2->Plane();
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
|
||||
@@ -817,7 +817,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
|
||||
aPlane = thePlane;
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
}
|
||||
@@ -826,7 +825,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
if (Result == Standard_False)
|
||||
{
|
||||
@@ -839,7 +837,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
TheType == STANDARD_TYPE(Geom_ToroidalSurface))
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -899,20 +896,18 @@ gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
|
||||
//function : InitFaceLength
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS::InitFaceLength (const TopoDS_Face& aFace,
|
||||
gp_Pln & aPlane,
|
||||
Handle(Geom_Surface) & aSurface,
|
||||
AIS_KindOfSurface & aSurfaceType,
|
||||
Standard_Real & anOffset)
|
||||
void AIS::InitFaceLength (const TopoDS_Face& theFace,
|
||||
gp_Pln& thePlane,
|
||||
Handle(Geom_Surface)& theSurface,
|
||||
AIS_KindOfSurface& theSurfaceType,
|
||||
Standard_Real& theOffset)
|
||||
{
|
||||
AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
|
||||
|
||||
if (Abs( anOffset ) > Precision::Confusion())
|
||||
{
|
||||
aSurface = new Geom_OffsetSurface( aSurface, anOffset );
|
||||
anOffset = 0.0e0;
|
||||
}
|
||||
|
||||
if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
|
||||
&& Abs (theOffset) > Precision::Confusion())
|
||||
{
|
||||
theSurface = new Geom_OffsetSurface (theSurface, theOffset);
|
||||
theOffset = 0.0e0;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -48,7 +48,7 @@ void AIS_AnimationCamera::update (const AIS_AnimationProgress& theProgress)
|
||||
Handle(Graphic3d_Camera) aCamera = myView->Camera();
|
||||
|
||||
Graphic3d_CameraLerp aCamLerp (myCamStart, myCamEnd);
|
||||
aCamLerp.Interpolate (theProgress.LocalNormalized, aCamera);
|
||||
aCamLerp.Interpolate (HasOwnDuration() ? theProgress.LocalNormalized : 1.0, aCamera);
|
||||
|
||||
const Standard_Boolean aPrevImmUpdate = myView->SetImmediateUpdate (Standard_False);
|
||||
myView->SetCamera (aCamera);
|
||||
|
@@ -33,6 +33,9 @@ public:
|
||||
//! Return the target view.
|
||||
const Handle(V3d_View)& View() const { return myView; }
|
||||
|
||||
//! Set target view.
|
||||
void SetView (const Handle(V3d_View)& theView) { myView = theView; }
|
||||
|
||||
//! Return camera start position.
|
||||
const Handle(Graphic3d_Camera)& CameraStart() const { return myCamStart; }
|
||||
|
||||
|
@@ -633,9 +633,6 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation
|
||||
{
|
||||
aShadedGroup = thePrs->NewGroup();
|
||||
aShadedGroup->SetClosed (isClosed);
|
||||
if (isClosed
|
||||
&& !myCappingStyle.IsNull())
|
||||
aShadedGroup->SetGroupPrimitivesAspect (myCappingStyle);
|
||||
}
|
||||
aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect());
|
||||
aShadedGroup->AddPrimitiveArray (aTriangles);
|
||||
|
@@ -187,6 +187,29 @@ AIS_InteractiveContext::~AIS_InteractiveContext()
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LastActiveView
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(V3d_View) AIS_InteractiveContext::LastActiveView() const
|
||||
{
|
||||
if (myLastActiveView == NULL
|
||||
|| myMainVwr.IsNull())
|
||||
{
|
||||
return Handle(V3d_View)();
|
||||
}
|
||||
|
||||
// as a precaution - check that myLastActiveView pointer is a valid active View
|
||||
for (V3d_ListOfViewIterator aViewIter = myMainVwr->ActiveViewIterator(); aViewIter.More(); aViewIter.Next())
|
||||
{
|
||||
if (aViewIter.Value() == myLastActiveView)
|
||||
{
|
||||
return aViewIter.Value();
|
||||
}
|
||||
}
|
||||
return Handle(V3d_View)();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateCurrentViewer
|
||||
//purpose :
|
||||
@@ -2447,12 +2470,10 @@ void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView)
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FitSelected
|
||||
//purpose : Fits the view corresponding to the bounds of selected objects
|
||||
//function : BoundingBoxOfSelection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView,
|
||||
const Standard_Real theMargin,
|
||||
const Standard_Boolean theToUpdate)
|
||||
Bnd_Box AIS_InteractiveContext::BoundingBoxOfSelection() const
|
||||
{
|
||||
Bnd_Box aBndSelected;
|
||||
AIS_MapOfObjectOwners anObjectOwnerMap;
|
||||
@@ -2491,12 +2512,22 @@ void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView,
|
||||
aBndSelected.Add (aTmpBox);
|
||||
}
|
||||
|
||||
anObjectOwnerMap.Clear();
|
||||
return aBndSelected;
|
||||
}
|
||||
|
||||
if (aBndSelected.IsVoid())
|
||||
return;
|
||||
|
||||
theView->FitAll (aBndSelected, theMargin, theToUpdate);
|
||||
//=======================================================================
|
||||
//function : FitSelected
|
||||
//purpose : Fits the view corresponding to the bounds of selected objects
|
||||
//=======================================================================
|
||||
void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView,
|
||||
const Standard_Real theMargin,
|
||||
const Standard_Boolean theToUpdate)
|
||||
{
|
||||
Bnd_Box aBndSelected = BoundingBoxOfSelection();
|
||||
if (!aBndSelected.IsVoid())
|
||||
{
|
||||
theView->FitAll (aBndSelected, theMargin, theToUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -370,6 +370,9 @@ public: //! @name mouse picking logic (detection and dynamic highlighting of ent
|
||||
const Standard_Integer theMode,
|
||||
const Standard_Integer theNewSensitivity);
|
||||
|
||||
//! Returns last active View (argument of MoveTo()/Select() methods).
|
||||
Standard_EXPORT Handle(V3d_View) LastActiveView() const;
|
||||
|
||||
//! Relays mouse position in pixels theXPix and theYPix to the interactive context selectors.
|
||||
//! This is done by the view theView passing this position to the main viewer and updating it.
|
||||
//! If theToRedrawOnUpdate is set to false, callee should call RedrawImmediate() to highlight detected object.
|
||||
@@ -505,6 +508,9 @@ public: //! @name Selection management
|
||||
const Handle(V3d_View)& theView,
|
||||
const Standard_Boolean theToUpdateViewer);
|
||||
|
||||
//! Returns bounding box of selected objects.
|
||||
Standard_EXPORT Bnd_Box BoundingBoxOfSelection() const;
|
||||
|
||||
//! Fits the view correspondingly to the bounds of selected objects.
|
||||
//! Infinite objects are ignored if infinite state of AIS_InteractiveObject is set to true.
|
||||
Standard_EXPORT void FitSelected (const Handle(V3d_View)& theView,
|
||||
@@ -1379,6 +1385,7 @@ protected: //! @name internal fields
|
||||
Handle(PrsMgr_PresentationManager3d) myMainPM;
|
||||
Handle(V3d_Viewer) myMainVwr;
|
||||
Handle(StdSelect_ViewerSelector3d) myMainSel;
|
||||
V3d_View* myLastActiveView;
|
||||
Handle(SelectMgr_EntityOwner) myLastPicked;
|
||||
Standard_Boolean myToHilightSelected;
|
||||
Handle(AIS_Selection) mySelection;
|
||||
|
@@ -325,6 +325,7 @@ AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer th
|
||||
myCurDetected = 0;
|
||||
myCurHighlighted = 0;
|
||||
myDetectedSeq.Clear();
|
||||
myLastActiveView = theView.get();
|
||||
|
||||
// preliminaires
|
||||
AIS_StatusOfDetection aStatus = AIS_SOD_Nothing;
|
||||
@@ -495,6 +496,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer theXPMi
|
||||
// all objects detected by the selector are taken, previous current objects are emptied,
|
||||
// new objects are put...
|
||||
ClearSelected (Standard_False);
|
||||
myLastActiveView = theView.get();
|
||||
myMainSel->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
|
||||
for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
|
||||
{
|
||||
@@ -534,6 +536,7 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& the
|
||||
// all objects detected by the selector are taken, previous current objects are emptied,
|
||||
// new objects are put...
|
||||
ClearSelected (Standard_False);
|
||||
myLastActiveView = theView.get();
|
||||
myMainSel->Pick (thePolyline, theView);
|
||||
for (Standard_Integer aPickIter = 1; aPickIter <= myMainSel->NbPicked(); ++aPickIter)
|
||||
{
|
||||
@@ -565,6 +568,17 @@ AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdate
|
||||
{
|
||||
if (!myLastPicked.IsNull())
|
||||
{
|
||||
Graphic3d_Vec2i aMousePos (-1, -1);
|
||||
if (myMainSel->GetManager().GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
|
||||
{
|
||||
aMousePos.SetValues ((Standard_Integer )myMainSel->GetManager().GetMousePosition().X(),
|
||||
(Standard_Integer )myMainSel->GetManager().GetMousePosition().Y());
|
||||
}
|
||||
if (myLastPicked->HandleMouseClick (aMousePos, Aspect_VKeyMouse_LeftButton, Aspect_VKeyFlags_NONE, false))
|
||||
{
|
||||
return AIS_SOP_NothingSelected;
|
||||
}
|
||||
|
||||
if (myAutoHilight)
|
||||
{
|
||||
clearDynamicHighlight();
|
||||
@@ -630,6 +644,7 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer the
|
||||
throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
|
||||
}
|
||||
|
||||
myLastActiveView = theView.get();
|
||||
if (myAutoHilight)
|
||||
{
|
||||
UnhilightSelected (Standard_False);
|
||||
@@ -670,6 +685,7 @@ AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d
|
||||
throw Standard_ProgramError ("AIS_InteractiveContext::ShiftSelect() - invalid argument");
|
||||
}
|
||||
|
||||
myLastActiveView = theView.get();
|
||||
if (myAutoHilight)
|
||||
{
|
||||
UnhilightSelected (Standard_False);
|
||||
|
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||
#include <Graphic3d_AspectFillCapping.hxx>
|
||||
#include <Graphic3d_AspectLine3d.hxx>
|
||||
#include <Graphic3d_AspectMarker3d.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
|
||||
//purpose :
|
||||
|
@@ -104,12 +104,6 @@ public:
|
||||
void ClearOwner() { myOwner.Nullify(); }
|
||||
|
||||
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.
|
||||
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()
|
||||
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;
|
||||
}
|
||||
|
||||
aPresentation->CStructure()->ViewAffinity = thePM->StructureManager()->ObjectAffinity (Handle(Standard_Transient) (this));
|
||||
|
||||
if (anOwner->Mode() == AIS_MM_TranslationPlane)
|
||||
{
|
||||
Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
|
||||
aStyle->SetColor(myAxes[anOwner->Index()].Color());
|
||||
aStyle->SetTransparency(0.5);
|
||||
aPresentation->Highlight(aStyle);
|
||||
aStyle->SetColor (myAxes[anOwner->Index()].Color());
|
||||
aStyle->SetTransparency (0.5);
|
||||
aPresentation->Highlight (aStyle);
|
||||
}
|
||||
else
|
||||
aPresentation->Highlight(theStyle);
|
||||
{
|
||||
aPresentation->Highlight (theStyle);
|
||||
}
|
||||
|
||||
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
|
||||
aGroupIter.More(); aGroupIter.Next())
|
||||
{
|
||||
|
@@ -180,7 +180,10 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "AIS_ViewController.hxx"
|
||||
|
||||
#include <AIS_AnimationCamera.hxx>
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <AIS_Manipulator.hxx>
|
||||
#include <AIS_Point.hxx>
|
||||
@@ -47,12 +48,15 @@ AIS_ViewController::AIS_ViewController()
|
||||
myToAllowZFocus (true),
|
||||
myToAllowHighlight (true),
|
||||
myToAllowDragging (true),
|
||||
myToStickToRayOnZoom (true),
|
||||
myToStickToRayOnRotation (true),
|
||||
//
|
||||
myWalkSpeedAbsolute (1.5f),
|
||||
myWalkSpeedRelative (0.1f),
|
||||
myThrustSpeed (0.0f),
|
||||
myHasThrust (false),
|
||||
//
|
||||
myViewAnimation (new AIS_AnimationCamera ("AIS_ViewController_ViewAnimation", Handle(V3d_View)())),
|
||||
myPrevMoveTo (-1, -1),
|
||||
myHasHlrOnBeforeRotation (false),
|
||||
//
|
||||
@@ -1224,6 +1228,20 @@ AIS_WalkDelta AIS_ViewController::FetchNavigationKeys (Standard_Real theCrouchRa
|
||||
return aWalk;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AbortViewAnimation
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void AIS_ViewController::AbortViewAnimation()
|
||||
{
|
||||
if (!myViewAnimation.IsNull()
|
||||
&& !myViewAnimation->IsStopped())
|
||||
{
|
||||
myViewAnimation->Stop();
|
||||
myViewAnimation->SetView (Handle(V3d_View)());
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : handlePanning
|
||||
// purpose :
|
||||
@@ -1236,6 +1254,8 @@ void AIS_ViewController::handlePanning (const Handle(V3d_View)& theView)
|
||||
return;
|
||||
}
|
||||
|
||||
AbortViewAnimation();
|
||||
|
||||
const Handle(Graphic3d_Camera)& aCam = theView->Camera();
|
||||
if (aCam->IsOrthographic()
|
||||
|| !hasPanningAnchorPoint())
|
||||
@@ -1276,6 +1296,8 @@ void AIS_ViewController::handleZRotate (const Handle(V3d_View)& theView)
|
||||
return;
|
||||
}
|
||||
|
||||
AbortViewAnimation();
|
||||
|
||||
Graphic3d_Vec2i aViewPort;
|
||||
theView->Window()->Size (aViewPort.x(), aViewPort.y());
|
||||
Graphic3d_Vec2d aRotPnt (0.99 * aViewPort.x(),
|
||||
@@ -1299,6 +1321,8 @@ void AIS_ViewController::handleZoom (const Handle(V3d_View)& theView,
|
||||
return;
|
||||
}
|
||||
|
||||
AbortViewAnimation();
|
||||
|
||||
const Handle(Graphic3d_Camera)& aCam = theView->Camera();
|
||||
if (thePnt != NULL)
|
||||
{
|
||||
@@ -1371,9 +1395,9 @@ void AIS_ViewController::handleZoom (const Handle(V3d_View)& theView,
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
theView->Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
const Graphic3d_Vec2d aPanFromCenterPx (double(theParams.Point.x()) - 0.5 * double(aWinSize.x()),
|
||||
double(theParams.Point.y()) - 0.5 * double(aWinSize.y()));
|
||||
double(aWinSize.y() - theParams.Point.y() - 1) - 0.5 * double(aWinSize.y()));
|
||||
aDxy.x() += -aViewDims1.X() * aPanFromCenterPx.x() / double(aWinSize.x());
|
||||
aDxy.y() += aViewDims1.X() * aPanFromCenterPx.y() / double(aWinSize.x());
|
||||
aDxy.y() += -aViewDims1.Y() * aPanFromCenterPx.y() / double(aWinSize.y());
|
||||
}
|
||||
|
||||
//theView->Translate (aCam, aDxy.x(), aDxy.y());
|
||||
@@ -1450,6 +1474,7 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView,
|
||||
return;
|
||||
}
|
||||
|
||||
AbortViewAnimation();
|
||||
if (theToLockZUp)
|
||||
{
|
||||
// amend camera to exclude roll angle (put camera Up vector to plane containing global Z and view direction)
|
||||
@@ -1561,6 +1586,8 @@ void AIS_ViewController::handleViewRotation (const Handle(V3d_View)& theView,
|
||||
return;
|
||||
}
|
||||
|
||||
AbortViewAnimation();
|
||||
|
||||
Graphic3d_Vec2i aWinXY;
|
||||
theView->Window()->Size (aWinXY.x(), aWinXY.y());
|
||||
double aYawAngleDelta = ((myGL.ViewRotation.PointStart.x() - myGL.ViewRotation.PointTo.x()) / double (aWinXY.x())) * (M_PI * 0.5);
|
||||
@@ -1636,7 +1663,7 @@ gp_Pnt AIS_ViewController::GravityPoint (const Handle(AIS_InteractiveContext)& t
|
||||
}
|
||||
|
||||
gp_Pnt aPnt;
|
||||
if (PickPoint (aPnt, theCtx, theView, aCursor, false))
|
||||
if (PickPoint (aPnt, theCtx, theView, aCursor, myToStickToRayOnRotation))
|
||||
{
|
||||
return aPnt;
|
||||
}
|
||||
@@ -1857,12 +1884,9 @@ void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContex
|
||||
|
||||
if (!theView->Camera()->IsOrthographic())
|
||||
{
|
||||
// what is more natural to user - point on ray or point exactly on geometry in corner cases?
|
||||
const bool toStickToRay = false; // true;
|
||||
|
||||
gp_Pnt aPnt;
|
||||
if (aZoomParams.HasPoint()
|
||||
&& PickPoint (aPnt, theCtx, theView, aZoomParams.Point, toStickToRay))
|
||||
&& PickPoint (aPnt, theCtx, theView, aZoomParams.Point, myToStickToRayOnZoom))
|
||||
{
|
||||
handleZoom (theView, aZoomParams, &aPnt);
|
||||
continue;
|
||||
@@ -1870,7 +1894,7 @@ void AIS_ViewController::handleCameraActions (const Handle(AIS_InteractiveContex
|
||||
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
theView->Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
if (PickPoint (aPnt, theCtx, theView, aWinSize / 2, toStickToRay))
|
||||
if (PickPoint (aPnt, theCtx, theView, aWinSize / 2, myToStickToRayOnZoom))
|
||||
{
|
||||
aZoomParams.ResetPoint(); // do not pretend to zoom at 'nothing'
|
||||
handleZoom (theView, aZoomParams, &aPnt);
|
||||
@@ -2035,11 +2059,6 @@ void AIS_ViewController::handleSelectionPick (const Handle(AIS_InteractiveContex
|
||||
{
|
||||
for (NCollection_Sequence<Graphic3d_Vec2i>::Iterator aPntIter (myGL.Selection.Points); aPntIter.More(); aPntIter.Next())
|
||||
{
|
||||
if (!myGL.Selection.IsXOR)
|
||||
{
|
||||
theCtx->ClearSelected (false);
|
||||
}
|
||||
|
||||
const bool hadPrevMoveTo = HasPreviousMoveTo();
|
||||
contextLazyMoveTo (theCtx, theView, aPntIter.Value());
|
||||
if (!hadPrevMoveTo)
|
||||
@@ -2274,6 +2293,15 @@ void AIS_ViewController::handleMoveTo (const Handle(AIS_InteractiveContext)& the
|
||||
void AIS_ViewController::handleViewRedraw (const Handle(AIS_InteractiveContext)& ,
|
||||
const Handle(V3d_View)& theView)
|
||||
{
|
||||
// manage animation state
|
||||
if (!myViewAnimation.IsNull()
|
||||
&& !myViewAnimation->IsStopped())
|
||||
{
|
||||
myViewAnimation->UpdateTimer();
|
||||
ResetPreviousMoveTo();
|
||||
setAskNextFrame();
|
||||
}
|
||||
|
||||
for (V3d_ListOfViewIterator aViewIter (theView->Viewer()->ActiveViewIterator()); aViewIter.More(); aViewIter.Next())
|
||||
{
|
||||
const Handle(V3d_View)& aView = aViewIter.Value();
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
|
||||
class AIS_AnimationCamera;
|
||||
class AIS_InteractiveObject;
|
||||
class AIS_InteractiveContext;
|
||||
class AIS_Point;
|
||||
@@ -56,6 +57,15 @@ public:
|
||||
//! Return input buffer.
|
||||
AIS_ViewInputBuffer& ChangeInputBuffer (AIS_ViewInputBufferType theType) { return theType == AIS_ViewInputBufferType_UI ? myUI : myGL; }
|
||||
|
||||
//! Return view animation; empty (but not NULL) animation by default.
|
||||
const Handle(AIS_AnimationCamera)& ViewAnimation() const { return myViewAnimation; }
|
||||
|
||||
//! Set view animation to be handled within handleViewRedraw().
|
||||
void SetViewAnimation (const Handle(AIS_AnimationCamera)& theAnimation) { myViewAnimation = theAnimation; }
|
||||
|
||||
//! Interrupt active view animation.
|
||||
Standard_EXPORT void AbortViewAnimation();
|
||||
|
||||
public: //! @name global parameters
|
||||
|
||||
//! Return camera rotation mode, AIS_RotationMode_BndBoxActive by default.
|
||||
@@ -142,6 +152,18 @@ public: //! @name global parameters
|
||||
//! Set if dynamic highlight on mouse move is allowed.
|
||||
void SetAllowDragging (bool theToEnable) { myToAllowDragging = theToEnable; }
|
||||
|
||||
//! Return TRUE if picked point should be projected to picking ray on zooming at point; TRUE by default.
|
||||
bool ToStickToRayOnZoom() const { return myToStickToRayOnZoom; }
|
||||
|
||||
//! Set if picked point should be projected to picking ray on zooming at point.
|
||||
void SetStickToRayOnZoom (bool theToEnable) { myToStickToRayOnZoom = theToEnable; }
|
||||
|
||||
//! Return TRUE if picked point should be projected to picking ray on rotating around point; TRUE by default.
|
||||
bool ToStickToRayOnRotation() const { return myToStickToRayOnRotation; }
|
||||
|
||||
//! Set if picked point should be projected to picking ray on rotating around point.
|
||||
void SetStickToRayOnRotation (bool theToEnable) { myToStickToRayOnRotation = theToEnable; }
|
||||
|
||||
//! Return TRUE if pitch direction should be inverted while processing Aspect_VKey_NavLookUp/Aspect_VKey_NavLookDown; FALSE by default.
|
||||
bool ToInvertPitch() const { return myToInvertPitch; }
|
||||
|
||||
@@ -590,12 +612,15 @@ protected:
|
||||
Standard_Boolean myToAllowZFocus; //!< enable ZFocus change; TRUE by default
|
||||
Standard_Boolean myToAllowHighlight; //!< enable dynamic highlight on mouse move; TRUE by default
|
||||
Standard_Boolean myToAllowDragging; //!< enable dragging object; TRUE by default
|
||||
Standard_Boolean myToStickToRayOnZoom; //!< project picked point to ray while zooming at point, TRUE by default
|
||||
Standard_Boolean myToStickToRayOnRotation; //!< project picked point to ray while rotating around point; TRUE by default
|
||||
|
||||
Standard_ShortReal myWalkSpeedAbsolute; //!< normal walking speed, in m/s; 1.5 by default
|
||||
Standard_ShortReal myWalkSpeedRelative; //!< walking speed relative to scene bounding box; 0.1 by default
|
||||
Standard_ShortReal myThrustSpeed; //!< active thrust value
|
||||
Standard_Boolean myHasThrust; //!< flag indicating active thrust
|
||||
|
||||
Handle(AIS_AnimationCamera) myViewAnimation; //!< view animation
|
||||
Handle(AIS_RubberBand) myRubberBand; //!< Rubber-band presentation
|
||||
Handle(AIS_InteractiveObject) myDragObject; //!< currently dragged object
|
||||
Graphic3d_Vec2i myPrevMoveTo; //!< previous position of MoveTo event in 3D viewer
|
||||
|
891
src/AIS/AIS_ViewCube.cxx
Normal file
891
src/AIS/AIS_ViewCube.cxx
Normal file
@@ -0,0 +1,891 @@
|
||||
// Created on: 2017-07-25
|
||||
// Created by: Anastasia BOBYLEVA
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
#include <AIS_ViewCube.hxx>
|
||||
|
||||
#include <AIS_AnimationCamera.hxx>
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <Graphic3d_ViewAffinity.hxx>
|
||||
#include <NCollection_Lerp.hxx>
|
||||
#include <Prs3d.hxx>
|
||||
#include <Prs3d_Arrow.hxx>
|
||||
#include <Prs3d_DatumAspect.hxx>
|
||||
#include <Prs3d_Root.hxx>
|
||||
#include <Prs3d_Text.hxx>
|
||||
#include <Prs3d_ToolDisk.hxx>
|
||||
#include <Prs3d_ToolSphere.hxx>
|
||||
#include <Select3D_SensitivePrimitiveArray.hxx>
|
||||
#include <SelectMgr_SequenceOfOwner.hxx>
|
||||
#include <V3d.hxx>
|
||||
#include <V3d_View.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCube, AIS_InteractiveObject)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(AIS_ViewCubeOwner, SelectMgr_EntityOwner)
|
||||
|
||||
namespace
|
||||
{
|
||||
static const Standard_Integer THE_NB_ROUND_SPLITS = 8;
|
||||
static const Standard_Integer THE_NB_DISK_SLICES = 20;
|
||||
static const Standard_Integer THE_NB_ARROW_FACETTES = 20;
|
||||
|
||||
//! Return the number of non-zero components.
|
||||
static Standard_Integer nbDirectionComponents (const gp_Dir& theDir)
|
||||
{
|
||||
Standard_Integer aNbComps = 0;
|
||||
for (Standard_Integer aCompIter = 1; aCompIter <= 3; ++aCompIter)
|
||||
{
|
||||
if (Abs (theDir.Coord (aCompIter)) > gp::Resolution())
|
||||
{
|
||||
++aNbComps;
|
||||
}
|
||||
}
|
||||
return aNbComps;
|
||||
}
|
||||
}
|
||||
|
||||
//! Simple sensitive element for picking by point only.
|
||||
class AIS_ViewCubeSensitive : public Select3D_SensitivePrimitiveArray
|
||||
{
|
||||
DEFINE_STANDARD_RTTI_INLINE(AIS_ViewCubeSensitive, Select3D_SensitivePrimitiveArray)
|
||||
public:
|
||||
//! Constructor.
|
||||
AIS_ViewCubeSensitive (const Handle(SelectMgr_EntityOwner)& theOwner,
|
||||
const Handle(Graphic3d_ArrayOfTriangles)& theTris)
|
||||
: Select3D_SensitivePrimitiveArray (theOwner)
|
||||
{
|
||||
InitTriangulation (theTris->Attributes(), theTris->Indices(), TopLoc_Location());
|
||||
}
|
||||
|
||||
//! Checks whether element overlaps current selecting volume.
|
||||
virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE
|
||||
{
|
||||
return isValidRay (theMgr)
|
||||
&& Select3D_SensitivePrimitiveArray::Matches (theMgr, thePickResult);
|
||||
}
|
||||
|
||||
//! Checks if picking ray can be used for detection.
|
||||
bool isValidRay (const SelectBasics_SelectingVolumeManager& theMgr) const
|
||||
{
|
||||
if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Point)
|
||||
{
|
||||
// disallow rectangular selection
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AIS_ViewCubeOwner* anOwner = dynamic_cast<AIS_ViewCubeOwner* >(myOwnerId.get()))
|
||||
{
|
||||
const Standard_Real anAngleToler = 10.0 * M_PI / 180.0;
|
||||
const gp_Vec aRay (theMgr.GetNearPickedPnt(), theMgr.GetFarPickedPnt());
|
||||
const gp_Dir aDir = V3d::GetProjAxis (anOwner->MainOrientation());
|
||||
return !aRay.IsNormal (aDir, anAngleToler);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : IsBoxSide
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
bool AIS_ViewCube::IsBoxSide (V3d_TypeOfOrientation theOrient)
|
||||
{
|
||||
return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsBoxEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
bool AIS_ViewCube::IsBoxEdge (V3d_TypeOfOrientation theOrient)
|
||||
{
|
||||
return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 2;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsBoxCorner
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
bool AIS_ViewCube::IsBoxCorner (V3d_TypeOfOrientation theOrient)
|
||||
{
|
||||
return nbDirectionComponents (V3d::GetProjAxis (theOrient)) == 3;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AIS_ViewCube
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
AIS_ViewCube::AIS_ViewCube()
|
||||
: myBoxEdgeAspect (new Prs3d_ShadingAspect()),
|
||||
myBoxCornerAspect (new Prs3d_ShadingAspect()),
|
||||
mySize (1.0),
|
||||
myBoxEdgeMinSize (2.0),
|
||||
myBoxEdgeGap (0.0),
|
||||
myBoxFacetExtension (1.0),
|
||||
myAxesPadding (1.0),
|
||||
myCornerMinSize (2.0),
|
||||
myRoundRadius (0.0),
|
||||
myToDisplayAxes (true),
|
||||
myToDisplayEdges (true),
|
||||
myToDisplayVertices (true),
|
||||
myIsYup (false),
|
||||
myViewAnimation (new AIS_AnimationCamera ("AIS_ViewCube", Handle(V3d_View)())),
|
||||
myStartState(new Graphic3d_Camera()),
|
||||
myEndState (new Graphic3d_Camera()),
|
||||
myDuration (0.5),
|
||||
myToAutoStartAnim (true),
|
||||
myIsFixedAnimation (true),
|
||||
myToFitSelected (true),
|
||||
myToResetCameraUp (false)
|
||||
{
|
||||
myInfiniteState = true;
|
||||
myIsMutable = true;
|
||||
myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
|
||||
myTransformPersistence = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (100, 100));
|
||||
|
||||
myDrawer->SetTextAspect (new Prs3d_TextAspect());
|
||||
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
|
||||
myDynHilightDrawer = new Prs3d_Drawer();
|
||||
myDynHilightDrawer->SetLink (myDrawer);
|
||||
myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
|
||||
setDefaultAttributes();
|
||||
setDefaultHighlightAttributes();
|
||||
|
||||
// setup default labels
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Front, "FRONT");
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Back, "BACK");
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Top, "TOP");
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Bottom, "BOTTOM");
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Left, "LEFT");
|
||||
myBoxSideLabels.Bind (V3d_TypeOfOrientation_Zup_Right, "RIGHT");
|
||||
|
||||
myAxesLabels.Bind (Prs3d_DP_XAxis, "X");
|
||||
myAxesLabels.Bind (Prs3d_DP_YAxis, "Y");
|
||||
myAxesLabels.Bind (Prs3d_DP_ZAxis, "Z");
|
||||
|
||||
// define default size
|
||||
SetSize (70.0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : setDefaultAttributes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::setDefaultAttributes()
|
||||
{
|
||||
myDrawer->TextAspect()->SetHorizontalJustification(Graphic3d_HTA_CENTER);
|
||||
myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_CENTER);
|
||||
myDrawer->TextAspect()->SetColor (Quantity_NOC_BLACK);
|
||||
myDrawer->TextAspect()->SetFont (Font_NOF_SANS_SERIF);
|
||||
myDrawer->TextAspect()->SetHeight (16.0);
|
||||
// this should be forced back-face culling regardless Closed flag
|
||||
myDrawer->TextAspect()->Aspect()->SetSuppressBackFaces (true);
|
||||
|
||||
Graphic3d_MaterialAspect aMat (Graphic3d_NOM_UserDefined);
|
||||
aMat.SetColor (Quantity_NOC_WHITE);
|
||||
aMat.SetAmbientColor (Quantity_NOC_GRAY60);
|
||||
|
||||
const Handle(Graphic3d_AspectFillArea3d)& aShading = myDrawer->ShadingAspect()->Aspect();
|
||||
aShading->SetInteriorStyle (Aspect_IS_SOLID);
|
||||
// this should be forced back-face culling regardless Closed flag
|
||||
aShading->SetSuppressBackFaces (true);
|
||||
aShading->SetInteriorColor (aMat.Color());
|
||||
aShading->SetFrontMaterial (aMat);
|
||||
myDrawer->SetFaceBoundaryDraw (false);
|
||||
|
||||
*myBoxEdgeAspect ->Aspect() = *aShading;
|
||||
myBoxEdgeAspect->SetColor (Quantity_NOC_GRAY30);
|
||||
*myBoxCornerAspect->Aspect() = *aShading;
|
||||
myBoxCornerAspect->SetColor (Quantity_NOC_GRAY30);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : setDefaultHighlightAttributes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::setDefaultHighlightAttributes()
|
||||
{
|
||||
Graphic3d_MaterialAspect aHighlightMaterial;
|
||||
aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
|
||||
aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
|
||||
aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
|
||||
aHighlightMaterial.SetReflectionModeOff (Graphic3d_TOR_EMISSION);
|
||||
aHighlightMaterial.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
|
||||
myDynHilightDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
|
||||
myDynHilightDrawer->ShadingAspect()->SetMaterial (aHighlightMaterial);
|
||||
myDynHilightDrawer->ShadingAspect()->SetColor (Quantity_NOC_CYAN1);
|
||||
myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
|
||||
myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetYup
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::SetYup (Standard_Boolean theIsYup,
|
||||
Standard_Boolean theToUpdateLabels)
|
||||
{
|
||||
if (myIsYup == theIsYup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myIsYup = theIsYup;
|
||||
|
||||
static const V3d_TypeOfOrientation THE_ZUP_ORI_LIST[6] =
|
||||
{
|
||||
V3d_TypeOfOrientation_Zup_Front, V3d_TypeOfOrientation_Zup_Back,
|
||||
V3d_TypeOfOrientation_Zup_Top, V3d_TypeOfOrientation_Zup_Bottom,
|
||||
V3d_TypeOfOrientation_Zup_Left, V3d_TypeOfOrientation_Zup_Right
|
||||
};
|
||||
static const V3d_TypeOfOrientation THE_YUP_ORI_LIST[6] =
|
||||
{
|
||||
V3d_TypeOfOrientation_Yup_Front, V3d_TypeOfOrientation_Yup_Back,
|
||||
V3d_TypeOfOrientation_Yup_Top, V3d_TypeOfOrientation_Yup_Bottom,
|
||||
V3d_TypeOfOrientation_Yup_Left, V3d_TypeOfOrientation_Yup_Right
|
||||
};
|
||||
if (theToUpdateLabels)
|
||||
{
|
||||
NCollection_Array1<TCollection_AsciiString> aLabels (0, 5);
|
||||
for (Standard_Integer aLabelIter = 0; aLabelIter < 6; ++aLabelIter)
|
||||
{
|
||||
myBoxSideLabels.Find (!myIsYup ? THE_YUP_ORI_LIST[aLabelIter] : THE_ZUP_ORI_LIST[aLabelIter],
|
||||
aLabels.ChangeValue (aLabelIter));
|
||||
}
|
||||
for (Standard_Integer aLabelIter = 0; aLabelIter < 6; ++aLabelIter)
|
||||
{
|
||||
myBoxSideLabels.Bind (myIsYup ? THE_YUP_ORI_LIST[aLabelIter] : THE_ZUP_ORI_LIST[aLabelIter],
|
||||
aLabels.Value (aLabelIter));
|
||||
}
|
||||
}
|
||||
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ResetStyles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::ResetStyles()
|
||||
{
|
||||
UnsetAttributes();
|
||||
UnsetHilightAttributes();
|
||||
|
||||
myBoxEdgeMinSize = 2.0;
|
||||
myCornerMinSize = 2.0;
|
||||
myBoxEdgeGap = 0.0;
|
||||
myRoundRadius = 0.0;
|
||||
|
||||
myToDisplayAxes = true;
|
||||
myToDisplayEdges = true;
|
||||
myToDisplayVertices = true;
|
||||
|
||||
myBoxFacetExtension = 1.0;
|
||||
myAxesPadding = 1.0;
|
||||
SetSize (70.0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetSize
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::SetSize (Standard_Real theValue,
|
||||
Standard_Boolean theToAdaptAnother)
|
||||
{
|
||||
const bool isNewSize = Abs (mySize - theValue) > Precision::Confusion();
|
||||
mySize = theValue;
|
||||
if (theToAdaptAnother)
|
||||
{
|
||||
if (myBoxFacetExtension > 0.0)
|
||||
{
|
||||
SetBoxFacetExtension (mySize * 0.15);
|
||||
}
|
||||
if (myAxesPadding > 0.0)
|
||||
{
|
||||
SetAxesPadding (mySize * 0.1);
|
||||
}
|
||||
SetFontHeight (mySize * 0.16);
|
||||
}
|
||||
if (isNewSize)
|
||||
{
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetRoundRadius
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::SetRoundRadius (const Standard_Real theValue)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if (theValue < 0.0 || theValue > 0.5,
|
||||
"AIS_ViewCube::SetRoundRadius(): theValue should be in [0; 0.5]");
|
||||
if (Abs (myRoundRadius - theValue) > Precision::Confusion())
|
||||
{
|
||||
myRoundRadius = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createRoundRectangleTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createRoundRectangleTriangles (const gp_XY& theSize,
|
||||
Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf)
|
||||
{
|
||||
const Standard_Real aRadius = Min (theRadius, Min (theSize.X(), theSize.Y()) * 0.5);
|
||||
const gp_XY aHSize (theSize.X() * 0.5 - aRadius, theSize.Y() * 0.5 - aRadius);
|
||||
const gp_Dir aNorm = gp::DZ().Transformed (theTrsf);
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTris;
|
||||
if (aRadius > 0.0)
|
||||
{
|
||||
const Standard_Integer aNbNodes = (THE_NB_ROUND_SPLITS + 1) * 4 + 1;
|
||||
aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbNodes * 3, Graphic3d_ArrayFlags_VertexNormal);
|
||||
|
||||
aTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (theTrsf));
|
||||
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
|
||||
{
|
||||
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (M_PI * 0.5, 0.0, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
|
||||
aTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
|
||||
{
|
||||
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (0.0, -M_PI * 0.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
|
||||
aTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
|
||||
{
|
||||
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI * 0.5, -M_PI, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
|
||||
aTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
|
||||
{
|
||||
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI, -M_PI * 1.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
|
||||
aTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
|
||||
// split triangle fan
|
||||
for (Standard_Integer aNodeIter = 2; aNodeIter <= aTris->VertexNumber(); ++aNodeIter)
|
||||
{
|
||||
aTris->AddEdge (1);
|
||||
aTris->AddEdge (aNodeIter - 1);
|
||||
aTris->AddEdge (aNodeIter);
|
||||
}
|
||||
aTris->AddEdge (1);
|
||||
aTris->AddEdge (aTris->VertexNumber());
|
||||
aTris->AddEdge (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
aTris = new Graphic3d_ArrayOfTriangles (4, 6, Graphic3d_ArrayFlags_VertexNormal);
|
||||
aTris->AddVertex (gp_Pnt (-aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
|
||||
aTris->AddVertex (gp_Pnt (-aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
|
||||
aTris->AddVertex (gp_Pnt ( aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
|
||||
aTris->AddVertex (gp_Pnt ( aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
|
||||
aTris->AddEdges (3, 1, 2);
|
||||
aTris->AddEdges (1, 3, 4);
|
||||
}
|
||||
|
||||
for (Standard_Integer aVertIter = 1; aVertIter <= aTris->VertexNumber(); ++aVertIter)
|
||||
{
|
||||
aTris->SetVertexNormal (aVertIter, -aNorm);
|
||||
}
|
||||
return aTris;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createBoxPartTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxPartTriangles (V3d_TypeOfOrientation theDir) const
|
||||
{
|
||||
if (IsBoxSide (theDir))
|
||||
{
|
||||
return createBoxSideTriangles (theDir);
|
||||
}
|
||||
else if (IsBoxEdge (theDir)
|
||||
&& myToDisplayEdges)
|
||||
{
|
||||
return createBoxEdgeTriangles (theDir);
|
||||
}
|
||||
else if (IsBoxCorner (theDir)
|
||||
&& myToDisplayVertices)
|
||||
{
|
||||
return createBoxCornerTriangles (theDir);
|
||||
}
|
||||
return Handle(Graphic3d_ArrayOfTriangles)();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createBoxSideTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxSideTriangles (V3d_TypeOfOrientation theDirection) const
|
||||
{
|
||||
const gp_Dir aDir = V3d::GetProjAxis (theDirection);
|
||||
const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension);
|
||||
const gp_Ax2 aPosition (aPos, aDir.Reversed());
|
||||
|
||||
gp_Ax3 aSystem (aPosition);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aSystem, gp_Ax3());
|
||||
|
||||
return createRoundRectangleTriangles (gp_XY (mySize, mySize), myRoundRadius * mySize, aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createBoxEdgeTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxEdgeTriangles (V3d_TypeOfOrientation theDirection) const
|
||||
{
|
||||
const Standard_Real aThickness = Max (myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() - myBoxEdgeGap, myBoxEdgeMinSize);
|
||||
|
||||
const gp_Dir aDir = V3d::GetProjAxis (theDirection);
|
||||
const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 * gp_XY (1.0, 1.0).Modulus() + myBoxFacetExtension * Cos (M_PI_4));
|
||||
const gp_Ax2 aPosition (aPos, aDir.Reversed());
|
||||
|
||||
gp_Ax3 aSystem (aPosition);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aSystem, gp_Ax3());
|
||||
|
||||
return createRoundRectangleTriangles (gp_XY (aThickness, mySize), myRoundRadius * mySize, aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createBoxCornerTriangles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxCornerTriangles (V3d_TypeOfOrientation theDir) const
|
||||
{
|
||||
const Standard_Real aHSize = mySize * 0.5;
|
||||
const gp_Dir aDir = V3d::GetProjAxis (theDir);
|
||||
const gp_XYZ aHSizeDir = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude());
|
||||
if (myRoundRadius > 0.0)
|
||||
{
|
||||
const Standard_Real anEdgeHWidth = myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() * 0.5;
|
||||
const Standard_Real aHeight = anEdgeHWidth * Sqrt (2.0 / 3.0); // tetrahedron height
|
||||
const gp_Pnt aPos = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude() + aHeight);
|
||||
const gp_Ax2 aPosition (aPos, aDir.Reversed());
|
||||
gp_Ax3 aSystem (aPosition);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aSystem, gp_Ax3());
|
||||
const Standard_Real aRadius = Max (myBoxFacetExtension * 0.5 / Cos (M_PI_4), myCornerMinSize);
|
||||
return Prs3d_ToolDisk::Create (0.0, aRadius, THE_NB_DISK_SLICES, 1, aTrsf);
|
||||
}
|
||||
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (3, 3, Graphic3d_ArrayFlags_VertexNormal);
|
||||
|
||||
aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (aDir.X(), 0.0, 0.0).XYZ());
|
||||
aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, aDir.Y(), 0.0).XYZ());
|
||||
aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, 0.0, aDir.Z()).XYZ());
|
||||
|
||||
const gp_XYZ aNode1 = aTris->Vertice (1).XYZ();
|
||||
const gp_XYZ aNode2 = aTris->Vertice (2).XYZ();
|
||||
const gp_XYZ aNode3 = aTris->Vertice (3).XYZ();
|
||||
const gp_XYZ aNormTri = ((aNode2 - aNode1).Crossed (aNode3 - aNode1));
|
||||
if (aNormTri.Dot (aDir.XYZ()) < 0.0)
|
||||
{
|
||||
aTris->AddEdges (1, 3, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
aTris->AddEdges (1, 2, 3);
|
||||
}
|
||||
|
||||
for (Standard_Integer aVertIter = 1; aVertIter <= aTris->VertexNumber(); ++aVertIter)
|
||||
{
|
||||
aTris->SetVertexNormal (aVertIter, aDir);
|
||||
}
|
||||
return aTris;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Compute
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
const Handle(Prs3d_Presentation)& thePrs,
|
||||
const Standard_Integer theMode)
|
||||
{
|
||||
thePrs->SetInfiniteState (true);
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const gp_Pnt aLocation = (mySize * 0.5 + myBoxFacetExtension + myAxesPadding) * gp_XYZ (-1.0, -1.0, -1.0);
|
||||
|
||||
// Display axes
|
||||
if (myToDisplayAxes)
|
||||
{
|
||||
const Standard_Real anAxisSize = mySize + 2.0 * myBoxFacetExtension + myAxesPadding;
|
||||
const Handle(Prs3d_DatumAspect)& aDatumAspect = myDrawer->DatumAspect();
|
||||
for (Standard_Integer anAxisIter = Prs3d_DP_XAxis; anAxisIter <= Prs3d_DP_ZAxis; ++anAxisIter)
|
||||
{
|
||||
const Prs3d_DatumParts aPart = (Prs3d_DatumParts )anAxisIter;
|
||||
if (!aDatumAspect->DrawDatumPart (aPart))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gp_Ax1 anAx1;
|
||||
switch (aPart)
|
||||
{
|
||||
case Prs3d_DP_XAxis: anAx1 = gp_Ax1 (aLocation, gp::DX()); break;
|
||||
case Prs3d_DP_YAxis: anAx1 = gp_Ax1 (aLocation, gp::DY()); break;
|
||||
case Prs3d_DP_ZAxis: anAx1 = gp_Ax1 (aLocation, gp::DZ()); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
Handle(Graphic3d_Group) anAxisGroup = thePrs->NewGroup();
|
||||
anAxisGroup->SetGroupPrimitivesAspect (aDatumAspect->ShadingAspect (aPart)->Aspect());
|
||||
|
||||
const Standard_Real anArrowLength = 0.2 * anAxisSize;
|
||||
Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = Prs3d_Arrow::DrawShaded (anAx1, 1.0, anAxisSize, 3.0, anArrowLength, THE_NB_ARROW_FACETTES);
|
||||
anAxisGroup->AddPrimitiveArray (aTriangleArray);
|
||||
|
||||
TCollection_AsciiString anAxisLabel;
|
||||
if (aDatumAspect->ToDrawLabels()
|
||||
&& myAxesLabels.Find (aPart, anAxisLabel)
|
||||
&& !anAxisLabel.IsEmpty())
|
||||
{
|
||||
Handle(Graphic3d_Group) anAxisLabelGroup = thePrs->NewGroup();
|
||||
gp_Pnt aTextOrigin = anAx1.Location().Translated (gp_Vec (anAx1.Direction().X() * (anAxisSize + anArrowLength),
|
||||
anAx1.Direction().Y() * (anAxisSize + anArrowLength),
|
||||
anAx1.Direction().Z() * (anAxisSize + anArrowLength)));
|
||||
Prs3d_Text::Draw (anAxisLabelGroup, aDatumAspect->TextAspect(), TCollection_ExtendedString (anAxisLabel), aTextOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
// Display center
|
||||
{
|
||||
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
||||
Handle(Prs3d_ShadingAspect) anAspectCen = new Prs3d_ShadingAspect();
|
||||
anAspectCen->SetColor (Quantity_NOC_WHITE);
|
||||
aGroup->SetGroupPrimitivesAspect (anAspectCen->Aspect());
|
||||
Prs3d_ToolSphere aTool (4.0, THE_NB_DISK_SLICES, THE_NB_DISK_SLICES);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTranslation (gp_Vec (gp::Origin(), aLocation));
|
||||
Handle(Graphic3d_ArrayOfTriangles) aCenterArray;
|
||||
aTool.FillArray (aCenterArray, aTrsf);
|
||||
aGroup->AddPrimitiveArray (aCenterArray);
|
||||
}
|
||||
}
|
||||
|
||||
// Display box
|
||||
{
|
||||
Handle(Graphic3d_Group) aGroupSides = thePrs->NewGroup(), aGroupEdges = thePrs->NewGroup(), aGroupCorners = thePrs->NewGroup();
|
||||
aGroupSides->SetClosed (true); // should be replaced by forced back-face culling aspect
|
||||
aGroupSides->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
|
||||
|
||||
aGroupEdges->SetClosed (true);
|
||||
aGroupEdges->SetGroupPrimitivesAspect (myBoxEdgeAspect->Aspect());
|
||||
|
||||
aGroupCorners->SetClosed (true);
|
||||
aGroupCorners->SetGroupPrimitivesAspect (myBoxCornerAspect->Aspect());
|
||||
|
||||
Handle(Graphic3d_Group) aTextGroup = thePrs->NewGroup();
|
||||
//aTextGroup->SetClosed (true);
|
||||
aTextGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
|
||||
for (Standard_Integer aPartIter = 0; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
|
||||
{
|
||||
const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
|
||||
if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (anOrient))
|
||||
{
|
||||
if (IsBoxSide (anOrient))
|
||||
{
|
||||
aGroupSides->AddPrimitiveArray (aTris);
|
||||
|
||||
TCollection_AsciiString aLabel;
|
||||
if (!myBoxSideLabels.Find (anOrient, aLabel)
|
||||
|| aLabel.IsEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const gp_Dir aDir = V3d::GetProjAxis (anOrient);
|
||||
gp_Dir anUp = myIsYup ? gp::DY() : gp::DZ();
|
||||
if (myIsYup)
|
||||
{
|
||||
if (anOrient == V3d_Ypos
|
||||
|| anOrient == V3d_Yneg)
|
||||
{
|
||||
anUp = -gp::DZ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (anOrient == V3d_Zpos)
|
||||
{
|
||||
anUp = gp::DY();
|
||||
}
|
||||
else if (anOrient == V3d_Zneg)
|
||||
{
|
||||
anUp = -gp::DY();
|
||||
}
|
||||
}
|
||||
|
||||
const Standard_Real anOffset = 2.0; // extra offset to avoid overlapping with triangulation
|
||||
const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension + anOffset);
|
||||
const gp_Ax2 aPosition (aPos, aDir, anUp.Crossed (aDir));
|
||||
Prs3d_Text::Draw (aTextGroup, myDrawer->TextAspect(), aLabel, aPosition);
|
||||
}
|
||||
else if (IsBoxEdge (anOrient))
|
||||
{
|
||||
aGroupEdges->AddPrimitiveArray (aTris);
|
||||
}
|
||||
else if (IsBoxCorner (anOrient))
|
||||
{
|
||||
aGroupCorners->AddPrimitiveArray (aTris);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeSelection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
||||
const Standard_Integer theMode)
|
||||
{
|
||||
if (theMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Standard_Integer aPartIter = 0; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
|
||||
{
|
||||
const V3d_TypeOfOrientation anOri = (V3d_TypeOfOrientation )aPartIter;
|
||||
if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (anOri))
|
||||
{
|
||||
Standard_Integer aSensitivity = 2;
|
||||
if (IsBoxCorner (anOri))
|
||||
{
|
||||
aSensitivity = 8;
|
||||
}
|
||||
else if (IsBoxEdge (anOri))
|
||||
{
|
||||
aSensitivity = 4;
|
||||
}
|
||||
Handle(AIS_ViewCubeOwner) anOwner = new AIS_ViewCubeOwner (this, anOri);
|
||||
Handle(AIS_ViewCubeSensitive) aTriSens = new AIS_ViewCubeSensitive (anOwner, aTris);
|
||||
aTriSens->SetSensitivityFactor (aSensitivity);
|
||||
theSelection->Add (aTriSens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HasAnimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean AIS_ViewCube::HasAnimation() const
|
||||
{
|
||||
return !myViewAnimation->IsStopped();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StartAnimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::StartAnimation (const Handle(AIS_ViewCubeOwner)& theOwner)
|
||||
{
|
||||
Handle(V3d_View) aView = GetContext()->LastActiveView();
|
||||
if (theOwner.IsNull()
|
||||
|| aView.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myStartState->Copy (aView->Camera());
|
||||
myEndState ->Copy (aView->Camera());
|
||||
|
||||
{
|
||||
Handle(Graphic3d_Camera) aBackupCamera = new Graphic3d_Camera (aView->Camera());
|
||||
|
||||
const bool wasImmediateUpdate = aView->SetImmediateUpdate (false);
|
||||
aView->SetCamera (myEndState);
|
||||
aView->SetProj (theOwner->MainOrientation(), myIsYup);
|
||||
|
||||
const gp_Dir aNewDir = aView->Camera()->Direction();
|
||||
if (!myToResetCameraUp
|
||||
&& !aNewDir.IsEqual (aBackupCamera->Direction(), Precision::Angular()))
|
||||
{
|
||||
// find the Up direction closest to current instead of default one
|
||||
const gp_Ax1 aNewDirAx1 (gp::Origin(), aNewDir);
|
||||
const gp_Dir anOldUp = aBackupCamera->Up();
|
||||
const gp_Dir anUpList[4] =
|
||||
{
|
||||
aView->Camera()->Up(),
|
||||
aView->Camera()->Up().Rotated (aNewDirAx1, M_PI_2),
|
||||
aView->Camera()->Up().Rotated (aNewDirAx1, M_PI),
|
||||
aView->Camera()->Up().Rotated (aNewDirAx1, M_PI * 1.5),
|
||||
};
|
||||
|
||||
Standard_Real aBestAngle = Precision::Infinite();
|
||||
gp_Dir anUpBest;
|
||||
for (Standard_Integer anUpIter = 0; anUpIter < 4; ++anUpIter)
|
||||
{
|
||||
Standard_Real anAngle = anUpList[anUpIter].Angle (anOldUp);
|
||||
if (aBestAngle > anAngle)
|
||||
{
|
||||
aBestAngle = anAngle;
|
||||
anUpBest = anUpList[anUpIter];
|
||||
}
|
||||
}
|
||||
aView->Camera()->SetUp (anUpBest);
|
||||
}
|
||||
|
||||
const Bnd_Box aBndSelected = myToFitSelected ? GetContext()->BoundingBoxOfSelection() : Bnd_Box();
|
||||
if (!aBndSelected.IsVoid())
|
||||
{
|
||||
aView->FitAll (aBndSelected, 0.01, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
aView->FitAll (0.01, false);
|
||||
}
|
||||
aView->SetCamera (aBackupCamera);
|
||||
aView->SetImmediateUpdate (wasImmediateUpdate);
|
||||
}
|
||||
|
||||
myViewAnimation->SetView (aView);
|
||||
myViewAnimation->SetCameraStart (myStartState);
|
||||
myViewAnimation->SetCameraEnd (myEndState);
|
||||
myViewAnimation->SetOwnDuration (myDuration);
|
||||
myViewAnimation->StartTimer (0.0, 1.0, true, false);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : updateAnimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean AIS_ViewCube::updateAnimation()
|
||||
{
|
||||
const Standard_Real aPts = myViewAnimation->UpdateTimer();
|
||||
if (aPts >= myDuration)
|
||||
{
|
||||
myViewAnimation->Stop();
|
||||
onAnimationFinished();
|
||||
myViewAnimation->SetView (Handle(V3d_View)());
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateAnimation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean AIS_ViewCube::UpdateAnimation (const Standard_Boolean theToUpdate)
|
||||
{
|
||||
Handle(V3d_View) aView = myViewAnimation->View();
|
||||
if (!HasAnimation()
|
||||
|| !updateAnimation())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (theToUpdate
|
||||
&& !aView.IsNull())
|
||||
{
|
||||
aView->IsInvalidated() ? aView->Redraw() : aView->RedrawImmediate();
|
||||
}
|
||||
|
||||
onAfterAnimation();
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HandleClick
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::HandleClick (const Handle(AIS_ViewCubeOwner)& theOwner)
|
||||
{
|
||||
if (!myToAutoStartAnim)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartAnimation (theOwner);
|
||||
if (!myIsFixedAnimation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (; HasAnimation(); )
|
||||
{
|
||||
UpdateAnimation (true);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HilightOwnerWithColor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||
const Handle(Prs3d_Drawer)& theStyle,
|
||||
const Handle(SelectMgr_EntityOwner)& theOwner)
|
||||
{
|
||||
if (theOwner.IsNull()
|
||||
|| !thePrsMgr->IsImmediateModeOn())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Graphic3d_ZLayerId aLayer = theStyle->ZLayer() != Graphic3d_ZLayerId_UNKNOWN ? theStyle->ZLayer() : myDrawer->ZLayer();
|
||||
const AIS_ViewCubeOwner* aCubeOwner = dynamic_cast<AIS_ViewCubeOwner* >(theOwner.get());
|
||||
|
||||
Handle(Prs3d_Presentation) aHiPrs = GetHilightPresentation (thePrsMgr);
|
||||
aHiPrs->Clear();
|
||||
aHiPrs->CStructure()->ViewAffinity = thePrsMgr->StructureManager()->ObjectAffinity (Handle(Standard_Transient)(this));
|
||||
aHiPrs->SetTransformPersistence (TransformPersistence());
|
||||
aHiPrs->SetZLayer (aLayer);
|
||||
|
||||
{
|
||||
Handle(Graphic3d_Group) aGroup = aHiPrs->NewGroup();
|
||||
aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
|
||||
if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (aCubeOwner->MainOrientation()))
|
||||
{
|
||||
aGroup->AddPrimitiveArray (aTris);
|
||||
}
|
||||
}
|
||||
|
||||
if (thePrsMgr->IsImmediateModeOn())
|
||||
{
|
||||
thePrsMgr->AddToImmediateList (aHiPrs);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HilightSelected
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_ViewCube::HilightSelected (const Handle(PrsMgr_PresentationManager3d)& ,
|
||||
const SelectMgr_SequenceOfOwner& theSeq)
|
||||
{
|
||||
// this method should never be called since AIS_InteractiveObject::HandleClick() has been overridden
|
||||
if (theSeq.Size() == 1)
|
||||
{
|
||||
//HandleClick (Handle(AIS_ViewCubeOwner)::DownCast (theSeq.First()));
|
||||
}
|
||||
}
|
645
src/AIS/AIS_ViewCube.hxx
Normal file
645
src/AIS/AIS_ViewCube.hxx
Normal file
@@ -0,0 +1,645 @@
|
||||
// Created on: 2017-07-25
|
||||
// Created by: Anastasia BOBYLEVA
|
||||
// Copyright (c) 2017-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 _AIS_ViewCube_HeaderFile
|
||||
#define _AIS_ViewCube_HeaderFile
|
||||
|
||||
#include <AIS_InteractiveObject.hxx>
|
||||
#include <Graphic3d_Camera.hxx>
|
||||
#include <Graphic3d_Vec2.hxx>
|
||||
#include <Prs3d_DatumParts.hxx>
|
||||
#include <Prs3d_ShadingAspect.hxx>
|
||||
#include <Prs3d_TextAspect.hxx>
|
||||
#include <SelectMgr_EntityOwner.hxx>
|
||||
#include <V3d_TypeOfOrientation.hxx>
|
||||
|
||||
class AIS_AnimationCamera;
|
||||
class AIS_ViewCubeOwner;
|
||||
class Graphic3d_ArrayOfTriangles;
|
||||
|
||||
//! Interactive object for displaying the view manipulation cube.
|
||||
//!
|
||||
//! View cube consists of several parts that are responsible for different camera manipulations:
|
||||
//! @li Cube sides represent main views: top, bottom, left, right, front and back.
|
||||
//! @li Edges represent rotation of one of main views on 45 degrees.
|
||||
//! @li Vertices represent rotation of one of man views in two directions.
|
||||
//!
|
||||
//! The object is expected to behave like a trihedron in the view corner,
|
||||
//! therefore its position should be defined using transformation persistence flags:
|
||||
//! @code SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_LOWER, Graphic3d_Vec2i (100, 100)); @endcode
|
||||
//!
|
||||
//! View Cube parts are sensitive to detection, or dynamic highlighting (but not selection),
|
||||
//! and every its owner AIS_ViewCubeOwner corresponds to camera transformation.
|
||||
//! @code
|
||||
//! for (aViewCube->StartAnimation (aDetectedOwner); aViewCube->HasAnimation(); )
|
||||
//! {
|
||||
//! aViewCube->UpdateAnimation();
|
||||
//! ... // updating of application window
|
||||
//! }
|
||||
//! @endcode
|
||||
//! or
|
||||
//! @code aViewCube->HandleClick (aDetectedOwner); @endcode
|
||||
//! that includes transformation loop.
|
||||
//! This loop allows external actions like application updating. For this purpose AIS_ViewCube has virtual interface onAfterAnimation(),
|
||||
//! that is to be redefined on application level.
|
||||
class AIS_ViewCube : public AIS_InteractiveObject
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(AIS_ViewCube, AIS_InteractiveObject)
|
||||
public:
|
||||
|
||||
//! Return TRUE if specified orientation belongs to box side.
|
||||
Standard_EXPORT static bool IsBoxSide (V3d_TypeOfOrientation theOrient);
|
||||
|
||||
//! Return TRUE if specified orientation belongs to box edge.
|
||||
Standard_EXPORT static bool IsBoxEdge (V3d_TypeOfOrientation theOrient);
|
||||
|
||||
//! Return TRUE if specified orientation belongs to box corner (vertex).
|
||||
Standard_EXPORT static bool IsBoxCorner (V3d_TypeOfOrientation theOrient);
|
||||
|
||||
public:
|
||||
|
||||
//! Empty constructor.
|
||||
Standard_EXPORT AIS_ViewCube();
|
||||
|
||||
//! Return view animation.
|
||||
const Handle(AIS_AnimationCamera)& ViewAnimation() const { return myViewAnimation; }
|
||||
|
||||
//! Set view animation.
|
||||
void SetViewAnimation (const Handle(AIS_AnimationCamera)& theAnimation) { myViewAnimation = theAnimation; }
|
||||
|
||||
//! Return TRUE if automatic camera transformation on selection (highlighting) is enabled; TRUE by default.
|
||||
Standard_Boolean ToAutoStartAnimation() const { return myToAutoStartAnim; }
|
||||
|
||||
//! Enable/disable automatic camera transformation on selection (highlighting).
|
||||
//! The automatic logic can be disabled if application wants performing action manually
|
||||
//! basing on picking results (AIS_ViewCubeOwner).
|
||||
void SetAutoStartAnimation (bool theToEnable) { myToAutoStartAnim = theToEnable; }
|
||||
|
||||
//! Return TRUE if camera animation should be done in uninterruptible loop; TRUE by default.
|
||||
Standard_Boolean IsFixedAnimationLoop() const { return myIsFixedAnimation; }
|
||||
|
||||
//! Set if camera animation should be done in uninterruptible loop.
|
||||
void SetFixedAnimationLoop (bool theToEnable) { myIsFixedAnimation = theToEnable; }
|
||||
|
||||
//! Reset all size and style parameters to default.
|
||||
//! @warning It doesn't reset position of View Cube
|
||||
Standard_EXPORT void ResetStyles();
|
||||
|
||||
protected:
|
||||
|
||||
//! Set default visual attributes
|
||||
Standard_EXPORT void setDefaultAttributes();
|
||||
|
||||
//! Set default dynamic highlight properties
|
||||
Standard_EXPORT void setDefaultHighlightAttributes();
|
||||
|
||||
public: //! @name Geometry management API
|
||||
|
||||
//! @return size (width and height) of View cube sides; 100 by default.
|
||||
Standard_Real Size() const { return mySize; }
|
||||
|
||||
//! Sets size (width and height) of View cube sides.
|
||||
//! @param theToAdaptAnother if TRUE, then other parameters will be adapted to specified size
|
||||
Standard_EXPORT void SetSize (Standard_Real theValue,
|
||||
Standard_Boolean theToAdaptAnother = true);
|
||||
|
||||
//! Return box facet extension to edge/corner facet split; 10 by default.
|
||||
Standard_Real BoxFacetExtension() const { return myBoxFacetExtension; }
|
||||
|
||||
//! Set new value of box facet extension.
|
||||
void SetBoxFacetExtension (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myBoxFacetExtension - theValue) > Precision::Confusion())
|
||||
{
|
||||
myBoxFacetExtension = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return padding between axes and 3D part (box); 10 by default.
|
||||
Standard_Real AxesPadding() const { return myAxesPadding; }
|
||||
|
||||
//! Set new value of padding between axes and 3D part (box).
|
||||
void SetAxesPadding (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myAxesPadding - theValue) > Precision::Confusion())
|
||||
{
|
||||
myAxesPadding = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return gap between box edges and box sides; 0 by default.
|
||||
Standard_Real BoxEdgeGap() const { return myBoxEdgeGap; }
|
||||
|
||||
//! Set new value of box edges gap.
|
||||
void SetBoxEdgeGap (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myBoxEdgeGap - theValue) > Precision::Confusion())
|
||||
{
|
||||
myBoxEdgeGap = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return minimal size of box edge; 2 by default.
|
||||
Standard_Real BoxEdgeMinSize() const { return myBoxEdgeMinSize; }
|
||||
|
||||
//! Set new value of box edge minimal size.
|
||||
void SetBoxEdgeMinSize (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myBoxEdgeMinSize - theValue) > Precision::Confusion())
|
||||
{
|
||||
myBoxEdgeMinSize = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return minimal size of box corner; 2 by default.
|
||||
Standard_Real BoxCornerMinSize() const { return myCornerMinSize; }
|
||||
|
||||
//! Set new value of box corner minimal size.
|
||||
void SetBoxCornerMinSize (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myCornerMinSize - theValue) > Precision::Confusion())
|
||||
{
|
||||
myCornerMinSize = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return relative radius of side corners (round rectangle); 0.0 by default.
|
||||
//! The value in within [0, 0.5] range meaning absolute radius = RoundRadius() / Size().
|
||||
Standard_Real RoundRadius() const { return myRoundRadius; }
|
||||
|
||||
//! Set relative radius of View Cube sides corners (round rectangle).
|
||||
//! The value should be within [0, 0.5] range.
|
||||
Standard_EXPORT void SetRoundRadius (const Standard_Real theValue);
|
||||
|
||||
//! @return TRUE if trihedron is drawn; TRUE by default.
|
||||
Standard_Boolean ToDrawAxes() const { return myToDisplayAxes; }
|
||||
|
||||
//! Enable/disable drawing of trihedron.
|
||||
void SetDrawAxes (Standard_Boolean theValue)
|
||||
{
|
||||
if (myToDisplayAxes != theValue)
|
||||
{
|
||||
myToDisplayAxes = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! @return TRUE if edges of View Cube is drawn; TRUE by default.
|
||||
Standard_Boolean ToDrawEdges() const { return myToDisplayEdges; }
|
||||
|
||||
//! Enable/disable drawing of edges of View Cube.
|
||||
void SetDrawEdges (Standard_Boolean theValue)
|
||||
{
|
||||
if (myToDisplayEdges != theValue)
|
||||
{
|
||||
myToDisplayEdges = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return TRUE if vertices (vertex) of View Cube is drawn; TRUE by default.
|
||||
Standard_Boolean ToDrawVertices() const { return myToDisplayVertices; }
|
||||
|
||||
//! Enable/disable drawing of vertices (corners) of View Cube.
|
||||
void SetDrawVertices (Standard_Boolean theValue)
|
||||
{
|
||||
if (myToDisplayVertices != theValue)
|
||||
{
|
||||
myToDisplayVertices = theValue;
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return TRUE if application expects Y-up viewer orientation instead of Z-up; FALSE by default.
|
||||
Standard_Boolean IsYup() const { return myIsYup; }
|
||||
|
||||
//! Set if application expects Y-up viewer orientation instead of Z-up.
|
||||
Standard_EXPORT void SetYup (Standard_Boolean theIsYup,
|
||||
Standard_Boolean theToUpdateLabels = Standard_True);
|
||||
|
||||
public: //! @name Style management API
|
||||
|
||||
//! Return shading style of box sides.
|
||||
const Handle(Prs3d_ShadingAspect)& BoxSideStyle() const { return myDrawer->ShadingAspect(); }
|
||||
|
||||
//! Return shading style of box edges.
|
||||
const Handle(Prs3d_ShadingAspect)& BoxEdgeStyle() const { return myBoxEdgeAspect; }
|
||||
|
||||
//! Return shading style of box corners.
|
||||
const Handle(Prs3d_ShadingAspect)& BoxCornerStyle() const { return myBoxCornerAspect; }
|
||||
|
||||
//! Return value of front color for the 3D part of object.
|
||||
const Quantity_Color& BoxColor() const { return myDrawer->ShadingAspect()->Color(); }
|
||||
|
||||
//! Set new value of front color for the 3D part of object.
|
||||
//! @param theColor [in] input color value.
|
||||
void SetBoxColor (const Quantity_Color& theColor)
|
||||
{
|
||||
if (!myDrawer->ShadingAspect()->Color().IsEqual (theColor)
|
||||
|| !myBoxEdgeAspect ->Color().IsEqual (theColor)
|
||||
|| !myBoxCornerAspect->Color().IsEqual (theColor))
|
||||
{
|
||||
myDrawer->ShadingAspect()->SetColor (theColor);
|
||||
myBoxEdgeAspect->SetColor (theColor);
|
||||
myBoxCornerAspect->SetColor (theColor);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return transparency for 3D part of object.
|
||||
Standard_Real BoxTransparency() const { return myDrawer->ShadingAspect()->Transparency(); }
|
||||
|
||||
//! Set new value of transparency for 3D part of object.
|
||||
//! @param theValue [in] input transparency value
|
||||
void SetBoxTransparency (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myDrawer->ShadingAspect()->Transparency() - theValue) > Precision::Confusion()
|
||||
|| Abs (myBoxEdgeAspect ->Transparency() - theValue) > Precision::Confusion()
|
||||
|| Abs (myBoxCornerAspect->Transparency() - theValue) > Precision::Confusion())
|
||||
{
|
||||
myDrawer->ShadingAspect()->SetTransparency (theValue);
|
||||
myBoxEdgeAspect->SetTransparency (theValue);
|
||||
myBoxCornerAspect->SetTransparency (theValue);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return color of sides back material.
|
||||
const Quantity_Color& InnerColor() const { return myDrawer->ShadingAspect()->Color (Aspect_TOFM_BACK_SIDE); }
|
||||
|
||||
//! Set color of sides back material. Alias for:
|
||||
//! @code Attributes()->ShadingAspect()->Aspect()->ChangeBackMaterial().SetColor() @endcode
|
||||
void SetInnerColor (const Quantity_Color& theColor)
|
||||
{
|
||||
myDrawer->ShadingAspect()->SetColor (theColor, Aspect_TOFM_BACK_SIDE);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
//! Return box side label or empty string if undefined.
|
||||
//! Default labels: FRONT, BACK, LEFT, RIGHT, TOP, BOTTOM.
|
||||
TCollection_AsciiString BoxSideLabel (V3d_TypeOfOrientation theSide) const
|
||||
{
|
||||
const TCollection_AsciiString* aLabel = myBoxSideLabels.Seek (theSide);
|
||||
return aLabel != NULL ? *aLabel : TCollection_AsciiString();
|
||||
}
|
||||
|
||||
//! Set box side label.
|
||||
void SetBoxSideLabel (const V3d_TypeOfOrientation theSide,
|
||||
const TCollection_AsciiString& theLabel)
|
||||
{
|
||||
if (!IsBoxSide (theSide))
|
||||
{
|
||||
throw Standard_ProgramError ("AIS_ViewCube::SetBoxSideLabel(), invalid enumeration value");
|
||||
}
|
||||
myBoxSideLabels.Bind (theSide, theLabel);
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
//! Return text color of labels of box sides; BLACK by default.
|
||||
const Quantity_Color& TextColor() const { return myDrawer->TextAspect()->Aspect()->Color(); }
|
||||
|
||||
//! Set color of text labels on box sides. Alias for:
|
||||
//! @code Attributes()->TextAspect()->SetColor() @endcode
|
||||
void SetTextColor (const Quantity_Color& theColor)
|
||||
{
|
||||
myDrawer->TextAspect()->SetColor (theColor);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
//! Return font name that is used for displaying of sides and axes text. Alias for:
|
||||
//! @code Attributes()->TextAspect()->Aspect()->SetFont() @endcode
|
||||
const TCollection_AsciiString& Font() const { return myDrawer->TextAspect()->Aspect()->Font(); }
|
||||
|
||||
//! Set font name that is used for displaying of sides and axes text. Alias for:
|
||||
//! @code Attributes()->TextAspect()->SetFont() @endcode
|
||||
void SetFont (const TCollection_AsciiString& theFont)
|
||||
{
|
||||
myDrawer->TextAspect()->Aspect()->SetFont (theFont);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
//! Return height of font
|
||||
Standard_Real FontHeight() const { return myDrawer->TextAspect()->Height(); }
|
||||
|
||||
//! Change font height. Alias for:
|
||||
//! @code Attributes()->TextAspect()->SetHeight() @endcode
|
||||
void SetFontHeight (Standard_Real theValue)
|
||||
{
|
||||
if (Abs (myDrawer->TextAspect()->Height() - theValue) > Precision::Confusion())
|
||||
{
|
||||
myDrawer->TextAspect()->SetHeight (theValue);
|
||||
SetToUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//! Return axes labels or empty string if undefined.
|
||||
//! Default labels: X, Y, Z.
|
||||
TCollection_AsciiString AxisLabel (Prs3d_DatumParts theAxis) const
|
||||
{
|
||||
const TCollection_AsciiString* aLabel = myAxesLabels.Seek (theAxis);
|
||||
return aLabel != NULL ? *aLabel : TCollection_AsciiString();
|
||||
}
|
||||
|
||||
//! Set axes labels.
|
||||
void SetAxesLabels (const TCollection_AsciiString& theX,
|
||||
const TCollection_AsciiString& theY,
|
||||
const TCollection_AsciiString& theZ)
|
||||
{
|
||||
myAxesLabels.Bind (Prs3d_DP_XAxis, theX);
|
||||
myAxesLabels.Bind (Prs3d_DP_YAxis, theY);
|
||||
myAxesLabels.Bind (Prs3d_DP_ZAxis, theZ);
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Set new value of color for the whole object.
|
||||
//! @param theColor [in] input color value.
|
||||
virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE
|
||||
{
|
||||
SetBoxColor (theColor);
|
||||
}
|
||||
|
||||
//! Reset color for the whole object.
|
||||
virtual void UnsetColor() Standard_OVERRIDE
|
||||
{
|
||||
myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
|
||||
myBoxEdgeAspect ->SetColor (Quantity_NOC_GRAY30);
|
||||
myBoxCornerAspect->SetColor (Quantity_NOC_GRAY30);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
//! Set new value of transparency for the whole object.
|
||||
//! @param theValue [in] input transparency value.
|
||||
virtual void SetTransparency (const Standard_Real theValue) Standard_OVERRIDE
|
||||
{
|
||||
SetBoxTransparency (theValue);
|
||||
}
|
||||
|
||||
//! Reset transparency for the whole object.
|
||||
virtual void UnsetTransparency() Standard_OVERRIDE
|
||||
{
|
||||
SetBoxTransparency (0.0f);
|
||||
}
|
||||
|
||||
//! Sets the material for the interactive object.
|
||||
virtual void SetMaterial (const Graphic3d_MaterialAspect& theMat) Standard_OVERRIDE
|
||||
{
|
||||
myDrawer->ShadingAspect()->SetMaterial (theMat);
|
||||
myBoxEdgeAspect ->SetMaterial (theMat);
|
||||
myBoxCornerAspect->SetMaterial (theMat);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
//! Sets the material for the interactive object.
|
||||
virtual void UnsetMaterial() Standard_OVERRIDE
|
||||
{
|
||||
Graphic3d_MaterialAspect aMat (Graphic3d_NOM_UserDefined);
|
||||
aMat.SetColor (Quantity_NOC_WHITE);
|
||||
aMat.SetAmbientColor (Quantity_NOC_GRAY60);
|
||||
myDrawer->ShadingAspect()->SetMaterial (aMat);
|
||||
myBoxEdgeAspect ->SetMaterial (aMat);
|
||||
myBoxEdgeAspect ->SetColor (Quantity_NOC_GRAY30);
|
||||
myBoxCornerAspect->SetMaterial (aMat);
|
||||
myBoxCornerAspect->SetColor (Quantity_NOC_GRAY30);
|
||||
SynchronizeAspects();
|
||||
}
|
||||
|
||||
public: //! @name animation methods
|
||||
|
||||
//! Return duration of animation in seconds; 0.5 sec by default
|
||||
Standard_Real Duration() const { return myDuration; }
|
||||
|
||||
//! Set duration of animation.
|
||||
//! @param theValue [in] input value of duration in seconds
|
||||
void SetDuration (Standard_Real theValue) { myDuration = theValue; }
|
||||
|
||||
//! Return TRUE if new camera Up direction should be always set to default value for a new camera Direction; FALSE by default.
|
||||
//! When this flag is FALSE, the new camera Up will be set as current Up orthogonalized to the new camera Direction,
|
||||
//! and will set to default Up on second click.
|
||||
Standard_Boolean ToResetCameraUp() const { return myToResetCameraUp; }
|
||||
|
||||
//! Set if new camera Up direction should be always set to default value for a new camera Direction.
|
||||
void SetResetCamera (Standard_Boolean theToReset) { myToResetCameraUp = theToReset; }
|
||||
|
||||
//! Return TRUE if animation should fit selected objects and FALSE to fit entire scene; TRUE by default.
|
||||
Standard_Boolean ToFitSelected() const { return myToFitSelected; }
|
||||
|
||||
//! Set if animation should fit selected objects or to fit entire scene.
|
||||
void SetFitSelected (Standard_Boolean theToFitSelected) { myToFitSelected = theToFitSelected; }
|
||||
|
||||
//! @return TRUE if View Cube has unfinished animation of view camera.
|
||||
Standard_EXPORT Standard_Boolean HasAnimation() const;
|
||||
|
||||
//! Start camera transformation corresponding to the input detected owner.
|
||||
//! @param theOwner [in] detected owner.
|
||||
Standard_EXPORT virtual void StartAnimation (const Handle(AIS_ViewCubeOwner)& theOwner);
|
||||
|
||||
//! Perform one step of current camera transformation.
|
||||
//! theToUpdate [in] enable/disable update of view.
|
||||
//! @return TRUE if animation is not stopped.
|
||||
Standard_EXPORT virtual Standard_Boolean UpdateAnimation (const Standard_Boolean theToUpdate);
|
||||
|
||||
//! Perform camera transformation corresponding to the input detected owner.
|
||||
Standard_EXPORT virtual void HandleClick (const Handle(AIS_ViewCubeOwner)& theOwner);
|
||||
|
||||
protected:
|
||||
|
||||
//! Perform internal single step of animation.
|
||||
//! @return FALSE if animation has been finished
|
||||
Standard_EXPORT Standard_Boolean updateAnimation();
|
||||
|
||||
protected: //! @name protected virtual API
|
||||
|
||||
//! Method that is called after one step of transformation.
|
||||
virtual void onAfterAnimation() {}
|
||||
|
||||
//! Method that is called after transformation finish.
|
||||
virtual void onAnimationFinished() {}
|
||||
|
||||
public: //! @name Presentation computation
|
||||
|
||||
//! Return TRUE for supported display mode.
|
||||
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
|
||||
|
||||
//! Global selection has no meaning for this class.
|
||||
virtual Handle(SelectMgr_EntityOwner) GlobalSelOwner() const Standard_OVERRIDE { return Handle(SelectMgr_EntityOwner)(); }
|
||||
|
||||
//! Compute 3D part of View Cube.
|
||||
//! @param thePrsMgr [in] presentation manager.
|
||||
//! @param thePrs [in] input presentation that is to be filled with flat presentation primitives.
|
||||
//! @param theMode [in] display mode.
|
||||
//! @warning this object accept only 0 display mode.
|
||||
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||
const Handle(Prs3d_Presentation)& thePrs,
|
||||
const Standard_Integer theMode = 0) Standard_OVERRIDE;
|
||||
|
||||
//! Redefine computing of sensitive entities for View Cube.
|
||||
//! @param theSelection [in] input selection object that is to be filled with sensitive entities.
|
||||
//! @param theMode [in] selection mode.
|
||||
//! @warning object accepts only 0 selection mode.
|
||||
Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE;
|
||||
|
||||
//! Disables auto highlighting to use HilightSelected() and HilightOwnerWithColor() overridden methods.
|
||||
virtual Standard_Boolean IsAutoHilight() const Standard_OVERRIDE { return Standard_False; }
|
||||
|
||||
//! Method which clear all selected owners belonging to this selectable object.
|
||||
//! @warning this object does not support selection.
|
||||
virtual void ClearSelected() Standard_OVERRIDE {}
|
||||
|
||||
//! Method which highlights input owner belonging to this selectable object.
|
||||
//! @param thePM [in] presentation manager
|
||||
//! @param theStyle [in] style for dynamic highlighting.
|
||||
//! @param theOwner [in] input entity owner.
|
||||
Standard_EXPORT virtual void HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)& thePM,
|
||||
const Handle(Prs3d_Drawer)& theStyle,
|
||||
const Handle(SelectMgr_EntityOwner)& theOwner) Standard_OVERRIDE;
|
||||
|
||||
//! Method which draws selected owners.
|
||||
Standard_EXPORT virtual void HilightSelected (const Handle(PrsMgr_PresentationManager3d)& thePM,
|
||||
const SelectMgr_SequenceOfOwner& theSeq) Standard_OVERRIDE;
|
||||
|
||||
//! Set default parameters for visual attributes
|
||||
//! @sa Attributes()
|
||||
virtual void UnsetAttributes() Standard_OVERRIDE
|
||||
{
|
||||
setDefaultAttributes();
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
//! Set default parameters for dynamic highlighting attributes, reset highlight attributes
|
||||
virtual void UnsetHilightAttributes() Standard_OVERRIDE
|
||||
{
|
||||
myHilightDrawer.Nullify();
|
||||
setDefaultHighlightAttributes();
|
||||
SetToUpdate();
|
||||
}
|
||||
|
||||
protected: //! @name Auxiliary classes to fill presentation with proper primitives
|
||||
|
||||
//! Create triangulation for a box part - for presentation and selection purposes.
|
||||
Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxPartTriangles (V3d_TypeOfOrientation theDir) const;
|
||||
|
||||
//! Create triangulation for a box side.
|
||||
Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxSideTriangles (V3d_TypeOfOrientation theDir) const;
|
||||
|
||||
//! Create triangulation for a box edge.
|
||||
Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxEdgeTriangles (V3d_TypeOfOrientation theDir) const;
|
||||
|
||||
//! Create triangulation for a box corner (vertex).
|
||||
Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxCornerTriangles (V3d_TypeOfOrientation theDir) const;
|
||||
|
||||
protected:
|
||||
|
||||
//! Create triangulation for a rectangle with round corners.
|
||||
//! @param theSize rectangle dimensions
|
||||
//! @param theRadius radius at corners
|
||||
//! @param theTrsf transformation
|
||||
Standard_EXPORT static Handle(Graphic3d_ArrayOfTriangles) createRoundRectangleTriangles (const gp_XY& theSize,
|
||||
Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf);
|
||||
|
||||
protected:
|
||||
|
||||
//! Trivial hasher to avoid ambiguity with enumeration type.
|
||||
struct IntegerHasher
|
||||
{
|
||||
static Standard_Integer HashCode (Standard_Integer theValue, Standard_Integer theUpper) { return ::HashCode (theValue, theUpper); }
|
||||
static Standard_Boolean IsEqual (Standard_Integer theA, Standard_Integer theB) { return theA == theB; }
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
NCollection_DataMap<V3d_TypeOfOrientation, TCollection_AsciiString, IntegerHasher>
|
||||
myBoxSideLabels; //!< map with box side labels
|
||||
NCollection_DataMap<Prs3d_DatumParts, TCollection_AsciiString, IntegerHasher>
|
||||
myAxesLabels; //!< map with axes labels
|
||||
Handle(Prs3d_ShadingAspect) myBoxEdgeAspect; //!< style for box edges
|
||||
Handle(Prs3d_ShadingAspect) myBoxCornerAspect; //!< style for box corner
|
||||
|
||||
Standard_Real mySize; //!< size of box side, length of one axis
|
||||
Standard_Real myBoxEdgeMinSize; //!< minimal size of box edge
|
||||
Standard_Real myBoxEdgeGap; //!< gap between box side and box edge
|
||||
Standard_Real myBoxFacetExtension; //!< box facet extension
|
||||
Standard_Real myAxesPadding; //!< Padding between box and axes
|
||||
Standard_Real myCornerMinSize; //!< minimal size of box corner
|
||||
Standard_Real myRoundRadius; //!< relative round radius within [0; 0.5] range
|
||||
Standard_Boolean myToDisplayAxes; //!< trihedron visibility
|
||||
Standard_Boolean myToDisplayEdges; //!< box edges visibility
|
||||
Standard_Boolean myToDisplayVertices; //!< box corners (vertices) visibility
|
||||
Standard_Boolean myIsYup; //!< flag indicating that application expects Y-up viewer orientation instead of Z-up
|
||||
|
||||
protected: //! @name Animation options
|
||||
|
||||
Handle(AIS_AnimationCamera) myViewAnimation; //!< Camera animation object
|
||||
Handle(Graphic3d_Camera) myStartState; //!< Start state of view camera
|
||||
Handle(Graphic3d_Camera) myEndState; //!< End state of view camera
|
||||
Standard_Real myDuration; //!< Duration of animation. By default it is half a second
|
||||
Standard_Boolean myToAutoStartAnim; //!< start animation automatically on click
|
||||
Standard_Boolean myIsFixedAnimation; //!< fixed-loop animation
|
||||
Standard_Boolean myToFitSelected; //!< fit selected or fit entire scene
|
||||
Standard_Boolean myToResetCameraUp; //!< always reset camera up direction to default
|
||||
|
||||
};
|
||||
|
||||
//! Redefined entity owner that is highlighted when owner is detected,
|
||||
//! even if Interactive Context highlighted on last detection procedure.
|
||||
class AIS_ViewCubeOwner : public SelectMgr_EntityOwner
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(AIS_ViewCubeOwner, SelectMgr_EntityOwner)
|
||||
public:
|
||||
|
||||
//! Main constructor.
|
||||
AIS_ViewCubeOwner (const Handle(AIS_ViewCube)& theObject,
|
||||
V3d_TypeOfOrientation theOrient,
|
||||
Standard_Integer thePriority = 5)
|
||||
: SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)& )theObject, thePriority),
|
||||
myMainOrient (theOrient)
|
||||
{
|
||||
myFromDecomposition = true;
|
||||
}
|
||||
|
||||
//! @return TRUE. This owner will always call method
|
||||
//! Hilight for its Selectable Object when the owner is detected.
|
||||
virtual Standard_Boolean IsForcedHilight() const Standard_OVERRIDE { return Standard_True; }
|
||||
|
||||
//! Return new orientation to set.
|
||||
V3d_TypeOfOrientation MainOrientation() const { return myMainOrient; }
|
||||
|
||||
//! Handle mouse button click event.
|
||||
virtual Standard_Boolean HandleMouseClick (const Graphic3d_Vec2i& thePoint,
|
||||
Aspect_VKeyMouse theButton,
|
||||
Aspect_VKeyFlags theModifiers,
|
||||
bool theIsDoubleClick) Standard_OVERRIDE
|
||||
{
|
||||
(void )thePoint; (void )theButton; (void )theModifiers; (void )theIsDoubleClick;
|
||||
AIS_ViewCube* aCubePrs = dynamic_cast<AIS_ViewCube* >(mySelectable);
|
||||
aCubePrs->HandleClick (this);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
V3d_TypeOfOrientation myMainOrient; //!< new orientation to set
|
||||
|
||||
};
|
||||
|
||||
#endif // _AIS_ViewCube_HeaderFile
|
@@ -182,4 +182,6 @@ AIS_TypeOfPlane.hxx
|
||||
AIS_ViewController.cxx
|
||||
AIS_ViewController.hxx
|
||||
AIS_ViewInputBuffer.hxx
|
||||
AIS_ViewCube.cxx
|
||||
AIS_ViewCube.hxx
|
||||
AIS_WalkDelta.hxx
|
||||
|
@@ -48,25 +48,6 @@ Aspect_GenId::Aspect_GenId (const Standard_Integer theLow,
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : HasFree
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Aspect_GenId::HasFree() const
|
||||
{
|
||||
return myFreeCount > 0
|
||||
|| myFreeIds.Extent() > 0;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Available
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Aspect_GenId::Available() const
|
||||
{
|
||||
return myFreeCount + myFreeIds.Extent();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Free
|
||||
// purpose :
|
||||
@@ -99,41 +80,37 @@ void Aspect_GenId::Free (const Standard_Integer theId)
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Lower
|
||||
// function : Next
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Aspect_GenId::Lower() const
|
||||
Standard_Integer Aspect_GenId::Next()
|
||||
{
|
||||
return myLowerBound;
|
||||
Standard_Integer aNewId = 0;
|
||||
if (!Next (aNewId))
|
||||
{
|
||||
throw Aspect_IdentDefinitionError("Aspect_GenId::Next(), Error: Available == 0");
|
||||
}
|
||||
return aNewId;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Next
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Aspect_GenId::Next()
|
||||
Standard_Boolean Aspect_GenId::Next (Standard_Integer& theId)
|
||||
{
|
||||
if (!myFreeIds.IsEmpty())
|
||||
{
|
||||
const Standard_Integer anId = myFreeIds.First();
|
||||
theId = myFreeIds.First();
|
||||
myFreeIds.RemoveFirst();
|
||||
return anId;
|
||||
return Standard_True;
|
||||
}
|
||||
else if (myFreeCount < 1)
|
||||
{
|
||||
throw Aspect_IdentDefinitionError("GenId Next Error: Available == 0");
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
--myFreeCount;
|
||||
const Standard_Integer anId = myLowerBound + myLength - myFreeCount - 1;
|
||||
return anId;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Upper
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Aspect_GenId::Upper() const
|
||||
{
|
||||
return myUpperBound;
|
||||
theId = myLowerBound + myLength - myFreeCount - 1;
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -49,47 +49,38 @@ public:
|
||||
Standard_EXPORT void Free (const Standard_Integer theId);
|
||||
|
||||
//! Returns true if there are available identifiers in range.
|
||||
Standard_EXPORT Standard_Boolean HasFree() const;
|
||||
Standard_Boolean HasFree() const
|
||||
{
|
||||
return myFreeCount > 0
|
||||
|| myFreeIds.Extent() > 0;
|
||||
}
|
||||
|
||||
//! Returns the number of available identifiers.
|
||||
Standard_EXPORT Standard_Integer Available() const;
|
||||
Standard_Integer Available() const { return myFreeCount + myFreeIds.Extent(); }
|
||||
|
||||
//! Returns the lower identifier in range.
|
||||
Standard_EXPORT Standard_Integer Lower() const;
|
||||
Standard_Integer Lower() const { return myLowerBound; }
|
||||
|
||||
//! Returns the next available identifier.
|
||||
//! Warning: Raises IdentDefinitionError if all identifiers are busy.
|
||||
Standard_EXPORT Standard_Integer Next();
|
||||
|
||||
//! Generates the next available identifier.
|
||||
//! @param theId [out] generated identifier
|
||||
//! @return FALSE if all identifiers are busy.
|
||||
Standard_EXPORT Standard_Boolean Next (Standard_Integer& theId);
|
||||
|
||||
//! Returns the upper identifier in range.
|
||||
Standard_EXPORT Standard_Integer Upper() const;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
Standard_Integer Upper() const { return myUpperBound; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
Standard_Integer myFreeCount;
|
||||
Standard_Integer myLength;
|
||||
Standard_Integer myLowerBound;
|
||||
Standard_Integer myUpperBound;
|
||||
TColStd_ListOfInteger myFreeIds;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _Aspect_GenId_HeaderFile
|
||||
|
@@ -93,9 +93,8 @@ public:
|
||||
//! be ignored at all.
|
||||
//! If theIsShapeToleranceUsed == TRUE then resulting box will be
|
||||
//! extended on the tolerance of the shape.
|
||||
//! theIsOptimal flag defines the algorithm for construction of initial
|
||||
//! Bnd_Box for the second method (if theIsOptimal == TRUE then
|
||||
//! this box will be created by AddOptimal(...) method).
|
||||
//! theIsOptimal flag defines whether to look for the more tight
|
||||
//! OBB for the cost of performance or not.
|
||||
Standard_EXPORT static
|
||||
void AddOBB(const TopoDS_Shape& theS,
|
||||
Bnd_OBB& theOBB,
|
||||
|
@@ -293,6 +293,7 @@ static Standard_Integer IsWCS(const gp_Dir& theDir)
|
||||
//=======================================================================
|
||||
static Standard_Boolean CheckPoints(const TopoDS_Shape& theS,
|
||||
const Standard_Boolean theIsTriangulationUsed,
|
||||
const Standard_Boolean theIsOptimal,
|
||||
const Standard_Boolean theIsShapeToleranceUsed,
|
||||
Bnd_OBB& theOBB)
|
||||
{
|
||||
@@ -329,7 +330,7 @@ static Standard_Boolean CheckPoints(const TopoDS_Shape& theS,
|
||||
}
|
||||
#endif
|
||||
|
||||
theOBB.ReBuild(anArrPnts, aPtrArrTol);
|
||||
theOBB.ReBuild(anArrPnts, aPtrArrTol, theIsOptimal);
|
||||
|
||||
return (!theOBB.IsVoid());
|
||||
}
|
||||
@@ -498,7 +499,7 @@ void BRepBndLib::AddOBB(const TopoDS_Shape& theS,
|
||||
const Standard_Boolean theIsOptimal,
|
||||
const Standard_Boolean theIsShapeToleranceUsed)
|
||||
{
|
||||
if(CheckPoints(theS, theIsTriangulationUsed, theIsShapeToleranceUsed, theOBB))
|
||||
if (CheckPoints(theS, theIsTriangulationUsed, theIsOptimal, theIsShapeToleranceUsed, theOBB))
|
||||
return;
|
||||
|
||||
ComputePCA(theS, theOBB, theIsTriangulationUsed, theIsOptimal, theIsShapeToleranceUsed);
|
||||
|
@@ -16,10 +16,8 @@
|
||||
#include <BRepExtrema_TriangleSet.hxx>
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BVH_LinearBuilder.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(BRepExtrema_TriangleSet, BVH_PrimitiveSet3d)
|
||||
|
||||
@@ -152,9 +150,6 @@ void BRepExtrema_TriangleSet::Clear()
|
||||
BVH_Array4i anEmptyTriangles;
|
||||
myTriangles.swap (anEmptyTriangles);
|
||||
|
||||
BVH_Array2d anEmptyVertUVArray;
|
||||
myVertUVArray.swap (anEmptyVertUVArray);
|
||||
|
||||
BVH_Array3d anEmptyVertexArray;
|
||||
myVertexArray.swap (anEmptyVertexArray);
|
||||
}
|
||||
@@ -179,8 +174,6 @@ Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& the
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
BRepAdaptor_Surface aFaceAdaptor (theFaces (aFaceIdx), Standard_False);
|
||||
|
||||
const Standard_Integer aVertOffset =
|
||||
static_cast<Standard_Integer> (myVertexArray.size()) - 1;
|
||||
|
||||
@@ -193,11 +186,6 @@ Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& the
|
||||
myVertexArray.push_back (BVH_Vec3d (aVertex.X(),
|
||||
aVertex.Y(),
|
||||
aVertex.Z()));
|
||||
|
||||
const Standard_Real aU = aTriangulation->UVNodes().Value (aVertIdx).X();
|
||||
const Standard_Real aV = aTriangulation->UVNodes().Value (aVertIdx).Y();
|
||||
|
||||
myVertUVArray.push_back (BVH_Vec2d (aU, aV));
|
||||
}
|
||||
|
||||
for (Standard_Integer aTriIdx = 1; aTriIdx <= aTriangulation->NbTriangles(); ++aTriIdx)
|
||||
|
@@ -75,9 +75,6 @@ protected:
|
||||
//! Array of vertex indices.
|
||||
BVH_Array4i myTriangles;
|
||||
|
||||
//! Array of vertex UV params.
|
||||
BVH_Array2d myVertUVArray;
|
||||
|
||||
//! Array of vertex coordinates.
|
||||
BVH_Array3d myVertexArray;
|
||||
|
||||
|
@@ -1437,16 +1437,13 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
||||
gp_Pnt2d ap = aCurve->Value(f);
|
||||
Standard_Boolean bFirstFound = Standard_False;
|
||||
Standard_Boolean bLastFound = Standard_False;
|
||||
Standard_Boolean bforward = Standard_True;
|
||||
|
||||
if(ap.Distance(theFirstPoint) < aTolerance1) {
|
||||
bforward = Standard_True;
|
||||
if(theOrientedList.IsEmpty())
|
||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
||||
bFirstFound = Standard_True;
|
||||
}
|
||||
else if(ap.Distance(theLastPoint) < aTolerance1) {
|
||||
bforward = Standard_False;
|
||||
if(theOrientedList.IsEmpty())
|
||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
||||
bLastFound = Standard_True;
|
||||
@@ -1454,36 +1451,31 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
||||
ap = aCurve->Value(l);
|
||||
|
||||
if(ap.Distance(theLastPoint) < aTolerance2) {
|
||||
bforward = Standard_True;
|
||||
|
||||
if(theOrientedList.IsEmpty())
|
||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
|
||||
bLastFound = Standard_True;
|
||||
}
|
||||
else if(ap.Distance(theFirstPoint) < aTolerance2) {
|
||||
bforward = Standard_False;
|
||||
|
||||
if(theOrientedList.IsEmpty())
|
||||
theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
|
||||
bFirstFound = Standard_True;
|
||||
}
|
||||
|
||||
if (!theOrientedList.IsEmpty())
|
||||
aEPrev = TopoDS::Edge (theOrientedList.Last());
|
||||
|
||||
for(; anIt.More(); anIt.Next()) {
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
|
||||
TopoDS_Vertex aV11, aV12;
|
||||
TopExp::Vertices(aEPrev, aV11, aV12);
|
||||
TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
|
||||
TopoDS_Vertex aV21, aV22;
|
||||
TopExp::Vertices(aE, aV21, aV22);
|
||||
TopAbs_Orientation anOri = TopAbs_FORWARD;
|
||||
TopExp::Vertices(aE, aV21, aV22, Standard_False);
|
||||
|
||||
if(aV12.IsSame(aV21) || aV11.IsSame(aV22)) {
|
||||
anOri = (bforward) ? TopAbs_FORWARD : TopAbs_REVERSED;
|
||||
}
|
||||
else {
|
||||
anOri = (bforward) ? TopAbs_REVERSED : TopAbs_FORWARD;
|
||||
}
|
||||
TopAbs_Orientation anOri =
|
||||
(aV12.IsSame (aV21) || aV11.IsSame (aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
|
||||
theOrientedList.Append(aE.Oriented(anOri));
|
||||
aEPrev = aE;
|
||||
aEPrev = TopoDS::Edge (theOrientedList.Last());
|
||||
|
||||
aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
|
||||
aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
|
||||
utol = aBAS.UResolution(aTolerance1);
|
||||
@@ -1511,9 +1503,7 @@ Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape& theOrderedList
|
||||
}
|
||||
}
|
||||
|
||||
if(!bFirstFound || !bLastFound)
|
||||
return Standard_False;
|
||||
return Standard_True;
|
||||
return bFirstFound && bLastFound;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------
|
||||
|
@@ -55,6 +55,8 @@ static Standard_Boolean findNearestValidPoint(
|
||||
//
|
||||
// the general step is computed using general curve resolution
|
||||
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
|
||||
if (aStep < theEps)
|
||||
aStep = theEps;
|
||||
// aD1Mag is a threshold to consider local derivative magnitude too small
|
||||
// and to accelerate going out of sphere
|
||||
// (inverse of resolution is the maximal derivative);
|
||||
@@ -159,11 +161,19 @@ Standard_Boolean BRepLib::FindValidRange
|
||||
if (theParV2 - theParV1 < Precision::PConfusion())
|
||||
return Standard_False;
|
||||
|
||||
Standard_Real anEps = Max(Max(theCurve.Resolution(theTolE) * 0.1,
|
||||
Epsilon(Max(Abs(theParV1), Abs(theParV2)))),
|
||||
Precision::PConfusion());
|
||||
Standard_Boolean isInfParV1 = Precision::IsInfinite (theParV1),
|
||||
isInfParV2 = Precision::IsInfinite (theParV2);
|
||||
|
||||
if (Precision::IsInfinite(theParV1))
|
||||
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());
|
||||
|
||||
if (isInfParV1)
|
||||
theFirst = theParV1;
|
||||
else
|
||||
{
|
||||
@@ -174,7 +184,7 @@ Standard_Boolean BRepLib::FindValidRange
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (Precision::IsInfinite(theParV2))
|
||||
if (isInfParV2)
|
||||
theLast = theParV2;
|
||||
else
|
||||
{
|
||||
|
@@ -65,7 +65,7 @@ void BRepMesh_BaseMeshAlgo::Perform(
|
||||
commitSurfaceTriangulation();
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure& /*theExeption*/)
|
||||
catch (Standard_Failure const& /*theExeption*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -83,6 +83,12 @@ public:
|
||||
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.
|
||||
//! @param theIndex index a circle should be bound with.
|
||||
//! @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
|
@@ -26,6 +26,7 @@
|
||||
#include <Adaptor3d_HCurveOnSurface.hxx>
|
||||
#include <Adaptor2d_HCurve2d.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
@@ -79,21 +80,28 @@ void BRepMesh_CurveTessellator::init()
|
||||
aPreciseLinDef *= 0.5;
|
||||
}
|
||||
|
||||
aPreciseLinDef = Max(aPreciseLinDef, Precision::Confusion());
|
||||
aPreciseAngDef = Max(aPreciseAngDef, Precision::Angular());
|
||||
aPreciseLinDef = Max (aPreciseLinDef, Precision::Confusion());
|
||||
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;
|
||||
mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize);
|
||||
mySquareMinSize = Max (mySquareEdgeDef, aMinSize * aMinSize);
|
||||
|
||||
myEdgeSqTol = BRep_Tool::Tolerance(myEdge);
|
||||
myEdgeSqTol = BRep_Tool::Tolerance (myEdge);
|
||||
myEdgeSqTol *= myEdgeSqTol;
|
||||
|
||||
const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
|
||||
|
||||
myDiscretTool.Initialize(myCurve,
|
||||
myCurve.FirstParameter(), myCurve.LastParameter(),
|
||||
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
|
||||
Precision::PConfusion(), myParameters.MinSize);
|
||||
myDiscretTool.Initialize (myCurve,
|
||||
myCurve.FirstParameter(), myCurve.LastParameter(),
|
||||
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
|
||||
Precision::PConfusion(), aMinSize);
|
||||
|
||||
if (myCurve.IsCurveOnSurface())
|
||||
{
|
||||
|
70
src/BRepMesh/BRepMesh_CustomBaseMeshAlgo.hxx
Normal file
70
src/BRepMesh/BRepMesh_CustomBaseMeshAlgo.hxx
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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 ();
|
||||
buildBaseTriangulation ();
|
||||
|
||||
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes ());
|
||||
BRepMesh_Delaun aMesher (aStructure, aCellsCount.first, aCellsCount.second, Standard_False);
|
||||
aMesher.ProcessConstraints ();
|
||||
|
||||
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
|
@@ -78,6 +78,25 @@ 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))
|
||||
{
|
||||
if (isFillCircles)
|
||||
{
|
||||
InitCirclesTool (theCellsCountU, theCellsCountV);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : BRepMesh_Delaun
|
||||
//purpose : Creates the triangulation with an empty Mesh data structure
|
||||
@@ -103,7 +122,8 @@ BRepMesh_Delaun::BRepMesh_Delaun(
|
||||
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||
IMeshData::Array1OfVertexOfDelaun& theVertices)
|
||||
: myMeshData( theOldMesh ),
|
||||
myCircles ( theVertices.Length(), theOldMesh->Allocator() )
|
||||
myCircles ( theVertices.Length(), new NCollection_IncAllocator(
|
||||
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
if ( theVertices.Length() > 2 )
|
||||
{
|
||||
@@ -119,7 +139,8 @@ BRepMesh_Delaun::BRepMesh_Delaun(
|
||||
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
|
||||
IMeshData::VectorOfInteger& theVertexIndices)
|
||||
: myMeshData( theOldMesh ),
|
||||
myCircles ( theVertexIndices.Length(), theOldMesh->Allocator() )
|
||||
myCircles ( theVertexIndices.Length(), new NCollection_IncAllocator(
|
||||
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
perform(theVertexIndices);
|
||||
}
|
||||
@@ -133,7 +154,8 @@ BRepMesh_Delaun::BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)&
|
||||
const Standard_Integer theCellsCountU,
|
||||
const Standard_Integer theCellsCountV)
|
||||
: myMeshData (theOldMesh),
|
||||
myCircles (theVertexIndices.Length (), theOldMesh->Allocator ())
|
||||
myCircles (theVertexIndices.Length (), new NCollection_IncAllocator(
|
||||
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
|
||||
{
|
||||
perform (theVertexIndices, theCellsCountU, theCellsCountV);
|
||||
}
|
||||
@@ -157,6 +179,63 @@ void BRepMesh_Delaun::Init(IMeshData::Array1OfVertexOfDelaun& theVertices)
|
||||
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
|
||||
//purpose : Create super mesh and run triangulation procedure
|
||||
@@ -180,18 +259,8 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
|
||||
|
||||
aBox.Enlarge (Precision);
|
||||
|
||||
Standard_Integer aScaler = 2;
|
||||
if ( myMeshData->NbNodes() > 100 )
|
||||
{
|
||||
aScaler = 5;
|
||||
}
|
||||
else if( myMeshData->NbNodes() > 1000 )
|
||||
{
|
||||
aScaler = 7;
|
||||
}
|
||||
|
||||
superMesh (aBox, Max (theCellsCountU, aScaler),
|
||||
Max (theCellsCountV, aScaler));
|
||||
initCirclesTool (aBox, theCellsCountU, theCellsCountV);
|
||||
superMesh (aBox);
|
||||
|
||||
ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
|
||||
std::make_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
|
||||
@@ -204,9 +273,7 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
|
||||
//function : superMesh
|
||||
//purpose : Build the super mesh
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
||||
const Standard_Integer theCellsCountU,
|
||||
const Standard_Integer theCellsCountV)
|
||||
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
|
||||
{
|
||||
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
|
||||
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
|
||||
@@ -217,9 +284,6 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
||||
Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
|
||||
Standard_Real aDelta = aDeltaX + aDeltaY;
|
||||
|
||||
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
|
||||
myCircles.SetCellSize( aDeltaX / theCellsCountU, aDeltaY / theCellsCountV);
|
||||
|
||||
mySupVert[0] = myMeshData->AddNode(
|
||||
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) );
|
||||
|
||||
@@ -254,7 +318,10 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
|
||||
void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
|
||||
IMeshData::MapOfIntegerInteger& theLoopEdges )
|
||||
{
|
||||
myCircles.Delete( theIndex );
|
||||
if (!myCircles.IsEmpty())
|
||||
{
|
||||
myCircles.Delete (theIndex);
|
||||
}
|
||||
|
||||
const BRepMesh_Triangle& aElement = GetTriangle(theIndex);
|
||||
const Standard_Integer(&e)[3] = aElement.myEdges;
|
||||
@@ -279,8 +346,11 @@ void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
|
||||
{
|
||||
// Insertion of edges of super triangles in the list of free edges:
|
||||
IMeshData::MapOfIntegerInteger aLoopEdges(10, myMeshData->Allocator());
|
||||
// Insertion of edges of super triangles in the list of free edges:
|
||||
Handle(NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator(
|
||||
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
|
||||
|
||||
IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
|
||||
const Standard_Integer(&e)[3] = mySupTrian.myEdges;
|
||||
|
||||
aLoopEdges.Bind( e[0], Standard_True );
|
||||
@@ -531,10 +601,7 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
}
|
||||
}
|
||||
|
||||
insertInternalEdges();
|
||||
|
||||
// Adjustment of meshes to boundary edges
|
||||
frontierAdjust();
|
||||
ProcessConstraints();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -41,6 +41,12 @@ public:
|
||||
|
||||
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.
|
||||
Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
|
||||
|
||||
@@ -61,6 +67,10 @@ public:
|
||||
//! Initializes the triangulation with an array of vertices.
|
||||
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.
|
||||
Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
|
||||
|
||||
@@ -77,6 +87,15 @@ public:
|
||||
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.
|
||||
inline Handle(IMeshData::MapOfInteger) Frontier() const
|
||||
{
|
||||
@@ -139,6 +158,11 @@ private:
|
||||
|
||||
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
|
||||
//! the given vector of bounding boxes for triangulation edges.
|
||||
void fillBndBox (IMeshData::SequenceOfBndB2d& theBoxes,
|
||||
@@ -156,9 +180,7 @@ private:
|
||||
const Standard_Integer theCellsCountV = -1);
|
||||
|
||||
//! Build the super mesh.
|
||||
void superMesh (const Bnd_Box2d& theBox,
|
||||
const Standard_Integer theCellsCountU,
|
||||
const Standard_Integer theCellsCountV);
|
||||
void superMesh (const Bnd_Box2d& theBox);
|
||||
|
||||
//! Computes the triangulation and adds the vertices,
|
||||
//! edges and triangles to the Mesh data structure.
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
||||
#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
|
||||
|
||||
#include <BRepMesh_BaseMeshAlgo.hxx>
|
||||
#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
|
||||
@@ -25,7 +25,7 @@ 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_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
|
||||
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -35,24 +35,12 @@ public:
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
|
||||
|
||||
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.
|
||||
Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
|
||||
|
||||
//! Perfroms processing of generated mesh.
|
||||
//! By default does nothing.
|
||||
virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -22,12 +22,12 @@
|
||||
|
||||
//! Extends node insertion Delaunay meshing algo in order to control
|
||||
//! deflection of generated trianges. Splits triangles failing the check.
|
||||
template<class RangeSplitter>
|
||||
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter>
|
||||
template<class RangeSplitter, class BaseAlgo>
|
||||
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
|
||||
{
|
||||
private:
|
||||
// Typedef for OCCT RTTI
|
||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> DelaunayInsertionBaseClass;
|
||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> DelaunayInsertionBaseClass;
|
||||
|
||||
public:
|
||||
|
||||
|
@@ -21,17 +21,18 @@
|
||||
|
||||
//! Extends base Delaunay meshing algo in order to enable possibility
|
||||
//! of addition of free vertices and internal nodes into the mesh.
|
||||
template<class RangeSplitter>
|
||||
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo>
|
||||
template<class RangeSplitter, class BaseAlgo>
|
||||
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
|
||||
{
|
||||
private:
|
||||
// Typedef for OCCT RTTI
|
||||
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> InsertionBaseClass;
|
||||
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> InsertionBaseClass;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor.
|
||||
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:
|
||||
|
||||
//! 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.
|
||||
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
|
||||
{
|
||||
@@ -55,10 +89,13 @@ protected:
|
||||
{
|
||||
InsertionBaseClass::postProcessMesh(theMesher);
|
||||
|
||||
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
|
||||
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
|
||||
if (!myIsPreProcessSurfaceNodes)
|
||||
{
|
||||
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
|
||||
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
|
||||
|
||||
insertNodes(aSurfaceNodes, theMesher);
|
||||
insertNodes(aSurfaceNodes, theMesher);
|
||||
}
|
||||
}
|
||||
|
||||
//! Inserts nodes into mesh.
|
||||
@@ -86,6 +123,37 @@ protected:
|
||||
theMesher.AddVertices(aVertexIndexes);
|
||||
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
|
||||
|
@@ -83,7 +83,7 @@ Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellation
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_EdgeDiscret::Perform (
|
||||
Standard_Boolean BRepMesh_EdgeDiscret::performInternal (
|
||||
const Handle (IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
@@ -108,69 +108,78 @@ Standard_Boolean BRepMesh_EdgeDiscret::Perform (
|
||||
void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
|
||||
{
|
||||
const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (theEdgeIndex);
|
||||
BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
|
||||
|
||||
Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
|
||||
if (!aDEdge->IsFree ())
|
||||
try
|
||||
{
|
||||
// Iterate over pcurves and check deflection on corresponding face.
|
||||
Standard_Real aMinDeflection = RealLast ();
|
||||
Standard_Integer aMinPCurveIndex = -1;
|
||||
for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
BRepMesh_Deflection::ComputeDeflection (aDEdge, myModel->GetMaxSize (), myParameters);
|
||||
|
||||
Handle (IMeshTools_CurveTessellator) aEdgeTessellator;
|
||||
if (!aDEdge->IsFree ())
|
||||
{
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
|
||||
const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
|
||||
if (aTmpDeflection < aMinDeflection)
|
||||
// Iterate over pcurves and check deflection on corresponding face.
|
||||
Standard_Real aMinDeflection = RealLast ();
|
||||
Standard_Integer aMinPCurveIndex = -1;
|
||||
for (Standard_Integer aPCurveIt = 0; aPCurveIt < aDEdge->PCurvesNb (); ++aPCurveIt)
|
||||
{
|
||||
// Identify pcurve with the smallest deflection in order to
|
||||
// retrieve polygon that represents the most smooth discretization.
|
||||
aMinDeflection = aTmpDeflection;
|
||||
aMinPCurveIndex = aPCurveIt;
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve (aPCurveIt);
|
||||
const Standard_Real aTmpDeflection = checkExistingPolygonAndUpdateStatus(aDEdge, aPCurve);
|
||||
if (aTmpDeflection < aMinDeflection)
|
||||
{
|
||||
// Identify pcurve with the smallest deflection in order to
|
||||
// retrieve polygon that represents the most smooth discretization.
|
||||
aMinDeflection = aTmpDeflection;
|
||||
aMinPCurveIndex = aPCurveIt;
|
||||
}
|
||||
|
||||
BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
|
||||
}
|
||||
|
||||
BRepMesh_ShapeTool::CheckAndUpdateFlags (aDEdge, aPCurve);
|
||||
}
|
||||
|
||||
if (aMinPCurveIndex != -1)
|
||||
{
|
||||
aDEdge->SetDeflection (aMinDeflection);
|
||||
const IMeshData::IFaceHandle aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace();
|
||||
aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
|
||||
}
|
||||
else
|
||||
{
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
|
||||
const IMeshData::IFaceHandle aDFace = aPCurve->GetFace();
|
||||
aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
|
||||
aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
|
||||
if (!aPoly3D.IsNull ())
|
||||
{
|
||||
if (aPoly3D->HasParameters () &&
|
||||
aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
|
||||
|
||||
if (aMinPCurveIndex != -1)
|
||||
{
|
||||
// Edge already has suitable 3d polygon.
|
||||
aDEdge->SetStatus(IMeshData_Reused);
|
||||
return;
|
||||
aDEdge->SetDeflection (aMinDeflection);
|
||||
const IMeshData::IFaceHandle aDFace = aDEdge->GetPCurve(aMinPCurveIndex)->GetFace();
|
||||
aEdgeTessellator = CreateEdgeTessellationExtractor(aDEdge, aDFace);
|
||||
}
|
||||
else
|
||||
{
|
||||
aDEdge->SetStatus(IMeshData_Outdated);
|
||||
const IMeshData::IPCurveHandle& aPCurve = aDEdge->GetPCurve(0);
|
||||
const IMeshData::IFaceHandle aDFace = aPCurve->GetFace();
|
||||
aEdgeTessellator = BRepMesh_EdgeDiscret::CreateEdgeTessellator(
|
||||
aDEdge, aPCurve->GetOrientation(), aDFace, myParameters);
|
||||
}
|
||||
}
|
||||
|
||||
aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
|
||||
else
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
|
||||
if (!aPoly3D.IsNull ())
|
||||
{
|
||||
if (aPoly3D->HasParameters () &&
|
||||
aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
|
||||
{
|
||||
// Edge already has suitable 3d polygon.
|
||||
aDEdge->SetStatus(IMeshData_Reused);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
aDEdge->SetStatus(IMeshData_Outdated);
|
||||
}
|
||||
}
|
||||
|
||||
aEdgeTessellator = CreateEdgeTessellator(aDEdge, myParameters);
|
||||
}
|
||||
|
||||
Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
|
||||
if (!aDEdge->IsFree())
|
||||
{
|
||||
Tessellate2d(aDEdge, Standard_True);
|
||||
}
|
||||
}
|
||||
|
||||
Tessellate3d (aDEdge, aEdgeTessellator, Standard_True);
|
||||
if (!aDEdge->IsFree())
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
Tessellate2d(aDEdge, Standard_True);
|
||||
aDEdge->SetStatus (IMeshData_Failure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,11 +52,6 @@ public:
|
||||
const IMeshData::IEdgeHandle& theDEdge,
|
||||
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.
|
||||
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
||||
process (theEdgeIndex);
|
||||
@@ -75,6 +70,13 @@ public:
|
||||
|
||||
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:
|
||||
|
||||
//! Checks existing discretization of the edge and updates data model.
|
||||
|
@@ -94,8 +94,6 @@ namespace
|
||||
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
|
||||
};
|
||||
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
//! Selector.
|
||||
//! Used to identify segments with overlapped bounding boxes.
|
||||
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector
|
||||
|
@@ -43,7 +43,7 @@ BRepMesh_FaceDiscret::~BRepMesh_FaceDiscret()
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FaceDiscret::Perform(
|
||||
Standard_Boolean BRepMesh_FaceDiscret::performInternal(
|
||||
const Handle(IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
@@ -73,14 +73,23 @@ void BRepMesh_FaceDiscret::process(const Standard_Integer theFaceIndex) const
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(IMeshTools_MeshAlgo) aMeshingAlgo =
|
||||
myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
|
||||
|
||||
if (aMeshingAlgo.IsNull())
|
||||
try
|
||||
{
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
return;
|
||||
}
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
aMeshingAlgo->Perform(aDFace, myParameters);
|
||||
Handle(IMeshTools_MeshAlgo) aMeshingAlgo =
|
||||
myAlgoFactory->GetAlgo(aDFace->GetSurface()->GetType(), myParameters);
|
||||
|
||||
if (aMeshingAlgo.IsNull())
|
||||
{
|
||||
aDFace->SetStatus(IMeshData_Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
//! 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.
|
||||
class BRepMesh_FaceDiscret : public IMeshTools_ModelAlgo
|
||||
{
|
||||
@@ -36,11 +36,6 @@ public:
|
||||
//! Destructor.
|
||||
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.
|
||||
inline void operator() (const Standard_Integer theFaceIndex) const {
|
||||
process(theFaceIndex);
|
||||
@@ -48,6 +43,13 @@ public:
|
||||
|
||||
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:
|
||||
|
||||
//! Checks existing discretization of the face and updates data model.
|
||||
|
@@ -86,19 +86,28 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
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();
|
||||
|
||||
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
|
||||
aContext->SetShape(Shape());
|
||||
aContext->ChangeParameters() = myParameters;
|
||||
aContext->ChangeParameters().CleanModel = Standard_False;
|
||||
theContext->SetShape(Shape());
|
||||
theContext->ChangeParameters() = myParameters;
|
||||
theContext->ChangeParameters().CleanModel = Standard_False;
|
||||
|
||||
IMeshTools_MeshBuilder aIncMesh(aContext);
|
||||
IMeshTools_MeshBuilder aIncMesh(theContext);
|
||||
aIncMesh.Perform();
|
||||
|
||||
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)
|
||||
{
|
||||
const IMeshData::IFaceHandle& aDFace = aModel->GetFace(aFaceIt);
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <BRepMesh_DiscretRoot.hxx>
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
#include <IMeshTools_Context.hxx>
|
||||
|
||||
//! Builds the mesh of a shape with respect of their
|
||||
//! correctly triangulated parts
|
||||
@@ -51,8 +52,11 @@ public: //! @name mesher API
|
||||
Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
|
||||
const IMeshTools_Parameters& theParameters);
|
||||
|
||||
//! Performs meshing ot the shape.
|
||||
//! Performs meshing ot the shape.
|
||||
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.
|
||||
|
||||
|
@@ -35,13 +35,13 @@ namespace
|
||||
template<class RangeSplitter>
|
||||
struct NodeInsertionMeshAlgo
|
||||
{
|
||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> Type;
|
||||
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
|
||||
};
|
||||
|
||||
template<class RangeSplitter>
|
||||
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;
|
||||
|
||||
case GeomAbs_Cylinder:
|
||||
return new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type;
|
||||
return theParameters.InternalVerticesMode ?
|
||||
new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
|
||||
new BaseMeshAlgo::Type;
|
||||
break;
|
||||
|
||||
case GeomAbs_Cone:
|
||||
|
@@ -18,7 +18,6 @@
|
||||
#include <BRepMesh_ShapeVisitor.hxx>
|
||||
#include <BRepMesh_ShapeTool.hxx>
|
||||
#include <IMeshTools_ShapeExplorer.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
@@ -43,52 +42,42 @@ BRepMesh_ModelBuilder::~BRepMesh_ModelBuilder ()
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Handle (IMeshData_Model) BRepMesh_ModelBuilder::Perform (
|
||||
Handle (IMeshData_Model) BRepMesh_ModelBuilder::performInternal (
|
||||
const TopoDS_Shape& theShape,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
ClearStatus ();
|
||||
|
||||
Handle (BRepMeshData_Model) aModel;
|
||||
try
|
||||
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add (theShape, aBox, Standard_False);
|
||||
|
||||
if (!aBox.IsVoid ())
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
// Build data model for further processing.
|
||||
aModel = new BRepMeshData_Model (theShape);
|
||||
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add (theShape, aBox, Standard_False);
|
||||
|
||||
if (!aBox.IsVoid ())
|
||||
if (theParameters.Relative)
|
||||
{
|
||||
// Build data model for further processing.
|
||||
aModel = new BRepMeshData_Model (theShape);
|
||||
|
||||
if (theParameters.Relative)
|
||||
{
|
||||
Standard_Real aMaxSize;
|
||||
BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
|
||||
aModel->SetMaxSize(aMaxSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
aModel->SetMaxSize(Max(theParameters.Deflection,
|
||||
theParameters.DeflectionInterior));
|
||||
}
|
||||
|
||||
Handle (IMeshTools_ShapeVisitor) aVisitor =
|
||||
new BRepMesh_ShapeVisitor (aModel);
|
||||
|
||||
IMeshTools_ShapeExplorer aExplorer (theShape);
|
||||
aExplorer.Accept (aVisitor);
|
||||
SetStatus (Message_Done1);
|
||||
Standard_Real aMaxSize;
|
||||
BRepMesh_ShapeTool::BoxMaxDimension (aBox, aMaxSize);
|
||||
aModel->SetMaxSize(aMaxSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStatus(Message_Fail1);
|
||||
aModel->SetMaxSize(Max(theParameters.Deflection,
|
||||
theParameters.DeflectionInterior));
|
||||
}
|
||||
|
||||
Handle (IMeshTools_ShapeVisitor) aVisitor =
|
||||
new BRepMesh_ShapeVisitor (aModel);
|
||||
|
||||
IMeshTools_ShapeExplorer aExplorer (theShape);
|
||||
aExplorer.Accept (aVisitor);
|
||||
SetStatus (Message_Done1);
|
||||
}
|
||||
catch (Standard_Failure&)
|
||||
else
|
||||
{
|
||||
SetStatus (Message_Fail2);
|
||||
SetStatus (Message_Fail1);
|
||||
}
|
||||
|
||||
return aModel;
|
||||
|
@@ -36,13 +36,15 @@ public:
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~BRepMesh_ModelBuilder ();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
|
||||
|
||||
protected:
|
||||
|
||||
//! Creates discrete model for the given shape.
|
||||
//! 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 IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelBuilder, IMeshTools_ModelBuilder)
|
||||
};
|
||||
|
||||
#endif
|
@@ -115,7 +115,7 @@ BRepMesh_ModelHealer::~BRepMesh_ModelHealer()
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_ModelHealer::Perform(
|
||||
Standard_Boolean BRepMesh_ModelHealer::performInternal(
|
||||
const Handle(IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
@@ -226,22 +226,31 @@ Standard_Boolean BRepMesh_ModelHealer::popEdgesToUpdate(
|
||||
//=======================================================================
|
||||
void BRepMesh_ModelHealer::process(const IMeshData::IFaceHandle& theDFace) const
|
||||
{
|
||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
|
||||
aIntersections.Nullify();
|
||||
|
||||
fixFaceBoundaries(theDFace);
|
||||
|
||||
if (!theDFace->IsSet(IMeshData_Failure))
|
||||
try
|
||||
{
|
||||
BRepMesh_FaceChecker aChecker(theDFace, myParameters);
|
||||
if (!aChecker.Perform())
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myFaceIntersectingEdges->ChangeFind(theDFace.get());
|
||||
aIntersections.Nullify();
|
||||
|
||||
fixFaceBoundaries(theDFace);
|
||||
|
||||
if (!theDFace->IsSet(IMeshData_Failure))
|
||||
{
|
||||
BRepMesh_FaceChecker aChecker(theDFace, myParameters);
|
||||
if (!aChecker.Perform())
|
||||
{
|
||||
#ifdef DEBUG_HEALER
|
||||
std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
|
||||
std::cout << "Failed : #" << aChecker.GetIntersectingEdges()->Size() << std::endl;
|
||||
#endif
|
||||
aIntersections = aChecker.GetIntersectingEdges();
|
||||
aIntersections = aChecker.GetIntersectingEdges();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure const&)
|
||||
{
|
||||
theDFace->SetStatus (IMeshData_Failure);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -44,11 +44,6 @@ public:
|
||||
//! Destructor.
|
||||
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.
|
||||
inline void operator() (const Standard_Integer theEdgeIndex) const {
|
||||
process(theEdgeIndex);
|
||||
@@ -61,6 +56,13 @@ public:
|
||||
|
||||
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:
|
||||
|
||||
//! Checks existing discretization of the face and updates data model.
|
||||
|
@@ -177,7 +177,7 @@ BRepMesh_ModelPostProcessor::~BRepMesh_ModelPostProcessor()
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_ModelPostProcessor::Perform(
|
||||
Standard_Boolean BRepMesh_ModelPostProcessor::performInternal(
|
||||
const Handle(IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& /*theParameters*/)
|
||||
{
|
||||
|
@@ -32,12 +32,14 @@ public:
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~BRepMesh_ModelPostProcessor();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
||||
|
||||
protected:
|
||||
|
||||
//! 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 IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPostProcessor, IMeshTools_ModelAlgo)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -242,7 +242,7 @@ BRepMesh_ModelPreProcessor::~BRepMesh_ModelPreProcessor()
|
||||
// Function: Perform
|
||||
// Purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_ModelPreProcessor::Perform(
|
||||
Standard_Boolean BRepMesh_ModelPreProcessor::performInternal(
|
||||
const Handle(IMeshData_Model)& theModel,
|
||||
const IMeshTools_Parameters& theParameters)
|
||||
{
|
||||
|
@@ -33,12 +33,14 @@ public:
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~BRepMesh_ModelPreProcessor();
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
|
||||
|
||||
protected:
|
||||
|
||||
//! 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 IMeshTools_Parameters& theParameters) Standard_OVERRIDE;
|
||||
|
||||
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ModelPreProcessor, IMeshTools_ModelAlgo)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -1,5 +1,6 @@
|
||||
BRepMesh_BaseMeshAlgo.cxx
|
||||
BRepMesh_BaseMeshAlgo.hxx
|
||||
BRepMesh_ConstrainedBaseMeshAlgo.hxx
|
||||
BRepMesh_BoundaryParamsRangeSplitter.hxx
|
||||
BRepMesh_Circle.hxx
|
||||
BRepMesh_CircleInspector.hxx
|
||||
@@ -82,4 +83,6 @@ BRepMesh_UVParamRangeSplitter.hxx
|
||||
BRepMesh_Vertex.hxx
|
||||
BRepMesh_VertexInspector.hxx
|
||||
BRepMesh_VertexTool.cxx
|
||||
BRepMesh_VertexTool.hxx
|
||||
BRepMesh_VertexTool.hxx
|
||||
BRepMesh_CustomBaseMeshAlgo.hxx
|
||||
BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <BRepMesh_OrientedEdge.hxx>
|
||||
#include <BRepMesh_Vertex.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
//=======================================================================
|
||||
// Function: Constructor
|
||||
@@ -74,6 +75,9 @@ void BRepMeshData_PCurve::AddPoint (
|
||||
//=======================================================================
|
||||
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];
|
||||
}
|
||||
|
||||
@@ -83,6 +87,9 @@ gp_Pnt2d& BRepMeshData_PCurve::GetPoint (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];
|
||||
}
|
||||
|
||||
@@ -92,6 +99,9 @@ Standard_Integer& BRepMeshData_PCurve::GetIndex(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];
|
||||
}
|
||||
|
||||
|
@@ -1486,7 +1486,9 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: -noTriangulation Force use of exact geometry for calculation"
|
||||
"\n\t\t: even if triangulation is present."
|
||||
"\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:"
|
||||
"\n\t\t: Output options:"
|
||||
|
@@ -845,7 +845,6 @@ Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferCompound (const TopoD
|
||||
// take all isolated Wires
|
||||
for (Ex.Init(start, TopAbs_WIRE, TopAbs_FACE); Ex.More(); Ex.Next()) {
|
||||
TopoDS_Wire S = TopoDS::Wire(Ex.Current());
|
||||
AddWarning(S," a Wire alone is not an IGESBRep entity : no Transfer");
|
||||
|
||||
BRepToIGES_BRWire BW(*this);
|
||||
BW.SetModel(GetModel());
|
||||
@@ -857,7 +856,6 @@ Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferCompound (const TopoD
|
||||
// take all isolated Edges
|
||||
for (Ex.Init(start, TopAbs_EDGE, TopAbs_WIRE); Ex.More(); Ex.Next()) {
|
||||
TopoDS_Edge S = TopoDS::Edge(Ex.Current());
|
||||
AddWarning(S," a Edge alone is not an IGESBRep entity : no Transfer");
|
||||
|
||||
BRepToIGES_BRWire BW(*this);
|
||||
BW.SetModel(GetModel());
|
||||
@@ -869,7 +867,6 @@ Handle(IGESData_IGESEntity) BRepToIGESBRep_Entity::TransferCompound (const TopoD
|
||||
// take all isolated Vertices
|
||||
for (Ex.Init(start, TopAbs_VERTEX, TopAbs_EDGE); Ex.More(); Ex.Next()) {
|
||||
TopoDS_Vertex S = TopoDS::Vertex(Ex.Current());
|
||||
AddWarning(S," a Vertex alone is not an IGESBRep entity : no Transfer");
|
||||
|
||||
BRepToIGES_BRWire BW(*this);
|
||||
BW.SetModel(GetModel());
|
||||
|
@@ -156,6 +156,13 @@ void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
|
||||
TopoDS_Shape shape = ashape;
|
||||
TopoDS_Shape newshape = anewshape;
|
||||
if ( shape.IsNull() || shape == newshape ) return;
|
||||
if (Apply (newshape) == shape)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "Warning: BRepTools_ReShape::Replace: recording the shape will lead to a loop" << endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (shape.Orientation() == TopAbs_REVERSED)
|
||||
{
|
||||
@@ -181,7 +188,9 @@ void BRepTools_ReShape::replace (const TopoDS_Shape& ashape,
|
||||
#ifdef OCCT_DEBUG
|
||||
if ( IsRecorded ( shape ) && ((myConsiderLocation && ! Value ( shape ).IsPartner ( newshape )) ||
|
||||
(!myConsiderLocation && ! Value ( shape ).IsSame ( newshape ))))
|
||||
{
|
||||
cout << "Warning: BRepTools_ReShape::Replace: shape already recorded" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
myShapeToReplacement.Bind(shape, TReplacement(newshape, theKind));
|
||||
|
@@ -14,11 +14,177 @@
|
||||
|
||||
#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 <Precision.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
|
||||
{
|
||||
public:
|
||||
@@ -31,7 +197,8 @@ public:
|
||||
//! must be available during all time of OBB creation
|
||||
//! (i.e. while the object of OBBTool exists).
|
||||
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
|
||||
//! (http://www.idt.mdh.se/~tla/publ/FastOBBs.pdf)
|
||||
@@ -41,6 +208,10 @@ public:
|
||||
void BuildBox(Bnd_OBB& theBox);
|
||||
|
||||
protected:
|
||||
|
||||
// Computes the extreme points on the set of Initial axes
|
||||
void ComputeExtremePoints ();
|
||||
|
||||
//! Works with the triangle set by the points in myTriIdx.
|
||||
//! If theIsBuiltTrg == TRUE, new set of triangles will be
|
||||
//! recomputed.
|
||||
@@ -71,6 +242,106 @@ protected:
|
||||
OBBTool& operator=(const OBBTool&);
|
||||
|
||||
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.
|
||||
static const Standard_Integer myNbInitAxes = 7;
|
||||
|
||||
@@ -96,6 +367,16 @@ private:
|
||||
|
||||
//! The surface area of the OBB
|
||||
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;
|
||||
}
|
||||
else if(theNewParam > thePrmArr[1])
|
||||
if(theNewParam > thePrmArr[1])
|
||||
{
|
||||
thePrmArr[1] = theNewParam;
|
||||
}
|
||||
@@ -122,76 +403,102 @@ static inline void SetMinMax(Standard_Real* const thePrmArr,
|
||||
//=======================================================================
|
||||
OBBTool::
|
||||
OBBTool(const TColgp_Array1OfPnt& theL,
|
||||
const TColStd_Array1OfReal *theLT) :myPntsList(theL),
|
||||
myListOfTolers(theLT),
|
||||
myQualityCriterion(RealLast())
|
||||
const TColStd_Array1OfReal *theLT,
|
||||
const Standard_Boolean theIsOptimal) : myPntsList(theL),
|
||||
myListOfTolers(theLT),
|
||||
myQualityCriterion(RealLast()),
|
||||
myOptimal (theIsOptimal)
|
||||
{
|
||||
if (myOptimal)
|
||||
{
|
||||
// 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);
|
||||
// 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};
|
||||
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 };
|
||||
|
||||
// Minimal and maximal point on every axis
|
||||
const Standard_Integer aNbPoints = 2 * myNbInitAxes;
|
||||
// Set of initial axes
|
||||
const gp_XYZ *anInitialAxesArray = anInitialAxes7;
|
||||
|
||||
for(Standard_Integer i = 0; i < 5; i++)
|
||||
{
|
||||
myTriIdx[i] = INT_MAX;
|
||||
}
|
||||
|
||||
// Min and Max parameter
|
||||
Standard_Real aParams[aNbPoints];
|
||||
for(Standard_Integer i = 0; i < aNbPoints; i += 2)
|
||||
{
|
||||
aParams[i] = RealLast();
|
||||
aParams[i + 1] = RealFirst();
|
||||
}
|
||||
|
||||
Standard_Real aParams[myNbExtremalPoints];
|
||||
// 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();
|
||||
for(Standard_Integer anAxeInd = 0, aPrmInd = 0; anAxeInd < myNbInitAxes; anAxeInd++, aPrmInd++)
|
||||
{
|
||||
const Standard_Real aParam = aCurrPoint.Dot(anInitialAxesArray[anAxeInd]);
|
||||
if(aParam < aParams[aPrmInd])
|
||||
{
|
||||
myLExtremalPoints[aPrmInd] = aCurrPoint;
|
||||
aParams[aPrmInd] = aParam;
|
||||
}
|
||||
aPrmInd++;
|
||||
|
||||
if(aParam > aParams[aPrmInd])
|
||||
{
|
||||
myLExtremalPoints[aPrmInd] = aCurrPoint;
|
||||
aParams[aPrmInd] = aParam;
|
||||
}
|
||||
}
|
||||
Standard_Integer aMinInd = ++aPrmInd, aMaxInd = ++aPrmInd;
|
||||
aParams[aMinInd] = RealLast();
|
||||
aParams[aMaxInd] = -RealLast();
|
||||
Project (anInitialAxesArray[anAxeInd],
|
||||
aParams[aMinInd], aParams[aMaxInd],
|
||||
&myLExtremalPoints[aMinInd], &myLExtremalPoints[aMaxInd]);
|
||||
}
|
||||
|
||||
// Compute myTriIdx[0] and myTriIdx[1].
|
||||
|
||||
Standard_Real aMaxSqDist = -1.0;
|
||||
for(Standard_Integer aPrmInd = 0; aPrmInd < aNbPoints; aPrmInd += 2)
|
||||
// For not optimal box it is necessary to compute the max axis
|
||||
// created by the maximally distant extreme points
|
||||
if (!myOptimal)
|
||||
{
|
||||
const gp_Pnt &aP1 = myLExtremalPoints[aPrmInd],
|
||||
&aP2 = myLExtremalPoints[aPrmInd + 1];
|
||||
const Standard_Real aSqDist = aP1.SquareDistance(aP2);
|
||||
if(aSqDist > aMaxSqDist)
|
||||
{
|
||||
aMaxSqDist = aSqDist;
|
||||
myTriIdx[0] = aPrmInd;
|
||||
myTriIdx[1] = aPrmInd + 1;
|
||||
}
|
||||
}
|
||||
for(Standard_Integer i = 0; i < 5; i++)
|
||||
myTriIdx[i] = INT_MAX;
|
||||
|
||||
FillToTriangle3();
|
||||
// Compute myTriIdx[0] and myTriIdx[1].
|
||||
Standard_Real aMaxSqDist = -1.0;
|
||||
for (Standard_Integer aPrmInd = 0; aPrmInd < myNbExtremalPoints; aPrmInd += 2)
|
||||
{
|
||||
const gp_Pnt &aP1 = myLExtremalPoints[aPrmInd],
|
||||
&aP2 = myLExtremalPoints[aPrmInd + 1];
|
||||
const Standard_Real aSqDist = aP1.SquareDistance(aP2);
|
||||
if (aSqDist > aMaxSqDist)
|
||||
{
|
||||
aMaxSqDist = aSqDist;
|
||||
myTriIdx[0] = aPrmInd;
|
||||
myTriIdx[1] = aPrmInd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the maximal axis orthogonal to the found one
|
||||
FillToTriangle3();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -233,6 +540,7 @@ void OBBTool::FillToTriangle5(const gp_XYZ& theNormal,
|
||||
const gp_XYZ& theBarryCenter)
|
||||
{
|
||||
Standard_Real aParams[2] = {0.0, 0.0};
|
||||
Standard_Integer id3 = -1, id4 = -1;
|
||||
|
||||
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 Standard_Real aParam = theNormal.Dot(aCurrPoint - theBarryCenter);
|
||||
|
||||
if(aParam < aParams[0])
|
||||
if (aParam < aParams[0])
|
||||
{
|
||||
myTriIdx[3] = aPtIdx;
|
||||
id3 = aPtIdx;
|
||||
aParams[0] = aParam;
|
||||
}
|
||||
else if(aParam > aParams[1])
|
||||
else if (aParam > aParams[1])
|
||||
{
|
||||
myTriIdx[4] = aPtIdx;
|
||||
id4 = aPtIdx;
|
||||
aParams[1] = aParam;
|
||||
}
|
||||
}
|
||||
|
||||
// The points must be in the different sides of the triangle plane.
|
||||
if(aParams[0] > -Precision::Confusion())
|
||||
{
|
||||
myTriIdx[3] = INT_MAX;
|
||||
}
|
||||
if (id3 >= 0 && aParams[0] < -Precision::Confusion())
|
||||
myTriIdx[3] = id3;
|
||||
|
||||
if(aParams[1] < Precision::Confusion())
|
||||
{
|
||||
myTriIdx[4] = INT_MAX;
|
||||
}
|
||||
if (id4 >= 0 && aParams[1] > Precision::Confusion())
|
||||
myTriIdx[4] = id4;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -279,71 +583,60 @@ void OBBTool::ProcessTriangle(const Standard_Integer theIdx1,
|
||||
{
|
||||
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
|
||||
// (see ComputeQuality(...) method).
|
||||
gp_XYZ aYAxis[aNbAxes] = {(myLExtremalPoints[theIdx2] - myLExtremalPoints[theIdx1]),
|
||||
(myLExtremalPoints[theIdx3] - myLExtremalPoints[theIdx2]),
|
||||
(myLExtremalPoints[theIdx1] - myLExtremalPoints[theIdx3])};
|
||||
int ID1[3] = { theIdx2, theIdx3, theIdx1 },
|
||||
ID2[3] = { theIdx1, theIdx2, 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
|
||||
gp_XYZ aZAxis = aYAxis[0].Crossed(aYAxis[1]);
|
||||
|
||||
Standard_Real aSqMod = aZAxis.SquareModulus();
|
||||
|
||||
if(aSqMod < Precision::SquareConfusion())
|
||||
if (aSqMod < Precision::SquareConfusion())
|
||||
return;
|
||||
|
||||
aZAxis /= Sqrt(aSqMod);
|
||||
|
||||
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();
|
||||
aYAxis[i].Normalize();
|
||||
}
|
||||
|
||||
if(theIsBuiltTrg)
|
||||
FillToTriangle5(aZAxis, aP0);
|
||||
if (theIsBuiltTrg)
|
||||
FillToTriangle5 (aZAxis, myLExtremalPoints[theIdx1]);
|
||||
|
||||
// Min and Max parameter
|
||||
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;
|
||||
for(Standard_Integer anAxeInd = 0; anAxeInd < aNbAxes; anAxeInd++)
|
||||
{
|
||||
const gp_XYZ &aAX = aXAxis[anAxeInd],
|
||||
&aAY = aYAxis[anAxeInd];
|
||||
|
||||
Standard_Real aParams[aNbPoints] = {0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0};
|
||||
|
||||
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 gp_XYZ &aAX = aXAxis[anAxeInd];
|
||||
// Compute params on XAxis
|
||||
FindMinMax (aAX, aParams[0], aParams[1]);
|
||||
// Compute params on YAxis checking for stored values
|
||||
ComputeParams (ID1[anAxeInd], ID2[anAxeInd], aParams[2], aParams[3]);
|
||||
|
||||
const Standard_Real anArea = ComputeQuality(aParams);
|
||||
if(anArea < myQualityCriterion)
|
||||
if (anArea < myQualityCriterion)
|
||||
{
|
||||
myQualityCriterion = anArea;
|
||||
aMinIdx = anAxeInd;
|
||||
}
|
||||
}
|
||||
|
||||
if(aMinIdx < 0)
|
||||
if (aMinIdx < 0)
|
||||
return;
|
||||
|
||||
myAxes[0] = aXAxis[aMinIdx];
|
||||
myAxes[1] = aYAxis[aMinIdx];
|
||||
myAxes[1] = aYAxis[aMinIdx].Normalized();
|
||||
myAxes[2] = aZAxis;
|
||||
}
|
||||
//=======================================================================
|
||||
@@ -352,20 +645,41 @@ void OBBTool::ProcessTriangle(const Standard_Integer theIdx1,
|
||||
//=======================================================================
|
||||
void OBBTool::ProcessDiTetrahedron()
|
||||
{
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[2], Standard_True);
|
||||
|
||||
if(myTriIdx[3] <= myNbExtremalPoints)
|
||||
// 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)
|
||||
{
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[3], Standard_False);
|
||||
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(myTriIdx[4] <= myNbExtremalPoints)
|
||||
else
|
||||
{
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[4], Standard_False);
|
||||
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[4], Standard_False);
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[4], Standard_False);
|
||||
// Use the standard DiTo approach
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[2], Standard_True);
|
||||
|
||||
if (myTriIdx[3] <= myNbExtremalPoints)
|
||||
{
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[3], Standard_False);
|
||||
ProcessTriangle(myTriIdx[1], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[2], myTriIdx[3], Standard_False);
|
||||
}
|
||||
|
||||
if (myTriIdx[4] <= myNbExtremalPoints)
|
||||
{
|
||||
ProcessTriangle(myTriIdx[0], myTriIdx[1], myTriIdx[4], Standard_False);
|
||||
ProcessTriangle(myTriIdx[1], 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/
|
||||
// =======================================================================
|
||||
void Bnd_OBB::ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
||||
const TColStd_Array1OfReal *theListOfTolerances)
|
||||
const TColStd_Array1OfReal *theListOfTolerances,
|
||||
const Standard_Boolean theIsOptimal)
|
||||
{
|
||||
switch(theListOfPoints.Length())
|
||||
{
|
||||
@@ -504,7 +819,7 @@ void Bnd_OBB::ReBuild(const TColgp_Array1OfPnt& theListOfPoints,
|
||||
break;
|
||||
}
|
||||
|
||||
OBBTool aTool(theListOfPoints, theListOfTolerances);
|
||||
OBBTool aTool(theListOfPoints, theListOfTolerances, theIsOptimal);
|
||||
aTool.ProcessDiTetrahedron();
|
||||
aTool.BuildBox(*this);
|
||||
}
|
||||
|
@@ -95,12 +95,17 @@ public:
|
||||
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.
|
||||
//! 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.
|
||||
//! <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,
|
||||
const TColStd_Array1OfReal *theListOfTolerances = 0);
|
||||
const TColStd_Array1OfReal *theListOfTolerances = 0,
|
||||
const Standard_Boolean theIsOptimal = Standard_False);
|
||||
|
||||
//! Sets the center of OBB
|
||||
void SetCenter(const gp_Pnt& theCenter)
|
||||
|
@@ -44,22 +44,17 @@ D3DHost_GraphicDriver::~D3DHost_GraphicDriver()
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : View
|
||||
// function : CreateView
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Graphic3d_CView) D3DHost_GraphicDriver::CreateView (const Handle(Graphic3d_StructureManager)& theMgr)
|
||||
{
|
||||
Handle(D3DHost_View) aView = new D3DHost_View (theMgr, this, myCaps, &myStateCounter);
|
||||
|
||||
myMapOfView.Add (aView);
|
||||
|
||||
for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
const Graphic3d_ZLayerId aLayerID = aLayerIt.Value();
|
||||
const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerID);
|
||||
aView->AddZLayer (aLayerID);
|
||||
aView->SetZLayerSettings (aLayerID, aSettings);
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
aView->InsertLayerAfter (aLayer->LayerId(), aLayer->LayerSettings(), Graphic3d_ZLayerId_UNKNOWN);
|
||||
}
|
||||
|
||||
return aView;
|
||||
}
|
||||
|
@@ -362,6 +362,11 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
|
||||
#else
|
||||
di << "OpenGL: desktop\n";
|
||||
#endif
|
||||
#ifdef HAVE_RAPIDJSON
|
||||
di << "RapidJSON enabled (HAVE_RAPIDJSON)\n";
|
||||
#else
|
||||
di << "RapidJSON disabled\n";
|
||||
#endif
|
||||
#ifdef HAVE_VTK
|
||||
di << "VTK enabled (HAVE_VTK)\n";
|
||||
#else
|
||||
|
@@ -310,6 +310,23 @@ proc checkreal {name value expected tol_abs tol_rel} {
|
||||
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 {
|
||||
Compare number of free edges with ref_value
|
||||
|
||||
|
@@ -1298,23 +1298,23 @@ proc _run_test {scriptsdir group gridname casefile echo} {
|
||||
# execute test scripts
|
||||
if { [file exists $scriptsdir/$group/begin] } {
|
||||
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] } {
|
||||
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
|
||||
uplevel source $casefile
|
||||
uplevel source -encoding utf-8 $casefile
|
||||
|
||||
if { [file exists $scriptsdir/$group/$gridname/end] } {
|
||||
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] } {
|
||||
puts "Executing $scriptsdir/$group/end..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/end
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/end
|
||||
}
|
||||
} res] {
|
||||
puts "Tcl Exception: $res"
|
||||
|
@@ -78,13 +78,19 @@ proc dftree { 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 #
|
||||
########
|
||||
|
||||
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 configure Label -font 9x15bold -foreground DarkGreen
|
||||
#$tree1 tag configure Attribute -font 9x15 -background bisque3
|
||||
|
@@ -17,3 +17,4 @@ Font_SystemFont.cxx
|
||||
Font_SystemFont.hxx
|
||||
Font_TextFormatter.hxx
|
||||
Font_TextFormatter.cxx
|
||||
Font_UnicodeSubset.hxx
|
||||
|
@@ -407,7 +407,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
{
|
||||
theShape.Nullify();
|
||||
if (!loadGlyph (theChar)
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -416,8 +416,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
return !theShape.IsNull();
|
||||
}
|
||||
|
||||
FT_Outline& anOutline = myFTFace->glyph->outline;
|
||||
|
||||
const FT_Outline& anOutline = myActiveFTFace->glyph->outline;
|
||||
if (!anOutline.n_contours)
|
||||
return Standard_False;
|
||||
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <ft2build.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)
|
||||
: myFTLib (theFTLib),
|
||||
myFTFace (NULL),
|
||||
myActiveFTFace(NULL),
|
||||
myFontAspect (Font_FontAspect_Regular),
|
||||
myWidthScaling(1.0),
|
||||
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
||||
myUChar (0U)
|
||||
myUChar (0U),
|
||||
myToUseUnicodeSubsetFallback (Font_FontMgr::ToUseUnicodeSubsetFallback())
|
||||
{
|
||||
if (myFTLib.IsNull())
|
||||
{
|
||||
@@ -66,6 +71,7 @@ void Font_FTFont::Release()
|
||||
FT_Done_Face (myFTFace);
|
||||
myFTFace = NULL;
|
||||
}
|
||||
myActiveFTFace = NULL;
|
||||
myBuffer.Nullify();
|
||||
}
|
||||
|
||||
@@ -135,6 +141,7 @@ bool Font_FTFont::Init (const Handle(NCollection_Buffer)& theData,
|
||||
|
||||
FT_Set_Transform (myFTFace, &aMat, 0);
|
||||
}
|
||||
myActiveFTFace = myFTFace;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -161,6 +168,7 @@ Handle(Font_FTFont) Font_FTFont::FindAndCreate (const TCollection_AsciiString& t
|
||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||
if (aFont->Init (aPath, aParams))
|
||||
{
|
||||
aFont->myFontAspect = aFontAspect;
|
||||
return aFont;
|
||||
}
|
||||
}
|
||||
@@ -177,22 +185,61 @@ bool Font_FTFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
Font_FTFontParams aParams = theParams;
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
myFontAspect = theFontAspect;
|
||||
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())
|
||||
{
|
||||
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);
|
||||
}
|
||||
Release();
|
||||
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
|
||||
// purpose :
|
||||
@@ -206,9 +253,26 @@ bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
|
||||
|
||||
myGlyphImg.Clear();
|
||||
myUChar = 0;
|
||||
if (theUChar == 0
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||
|| myFTFace->glyph == NULL)
|
||||
myActiveFTFace = myFTFace;
|
||||
if (theUChar == 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -225,26 +289,67 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
{
|
||||
myGlyphImg.Clear();
|
||||
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
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myFTFace->glyph == NULL
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
|| FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myActiveFTFace->glyph == NULL
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
|
||||
if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
|
||||
|| aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
FT_Bitmap aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
if (aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||
|
||||
if (aBitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||
{
|
||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
|
||||
myUChar = theUChar;
|
||||
return true;
|
||||
}
|
||||
@@ -253,24 +358,58 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
// function : GlyphMaxSizeX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX (bool theToIncludeFallback) const
|
||||
{
|
||||
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))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||
return (unsigned int)(aWidth + 0.5f);
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
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))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||
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
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY (bool theToIncludeFallback) const
|
||||
{
|
||||
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))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||
return (unsigned int)(aHeight + 0.5f);
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
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))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||
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);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : getKerning
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::getKerning (FT_Vector& theKern,
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
theKern.x = 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 aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext);
|
||||
const FT_UInt aCharCurr = FT_Get_Char_Index (myActiveFTFace, theUCharCurr);
|
||||
const FT_UInt aCharNext = FT_Get_Char_Index (myActiveFTFace, theUCharNext);
|
||||
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.y = 0;
|
||||
@@ -357,7 +500,7 @@ float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const
|
||||
|
||||
FT_Vector aKern;
|
||||
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;
|
||||
getKerning (aKern, myUChar, theUCharNext);
|
||||
return fromFTPoints<float> (myFTFace->glyph->advance.y + aKern.y);
|
||||
return fromFTPoints<float> (myActiveFTFace->glyph->advance.y + aKern.y);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GlyphsNumber
|
||||
// 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 :
|
||||
// =======================================================================
|
||||
void Font_FTFont::GlyphRect (Font_Rect& theRect) const
|
||||
{
|
||||
const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
const FT_Bitmap& aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myActiveFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myActiveFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myActiveFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myActiveFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Font_Rect.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
||||
#include <Graphic3d_VerticalTextAlignment.hxx>
|
||||
#include <Image_PixMap.hxx>
|
||||
@@ -33,10 +34,10 @@ class Font_FTLibrary;
|
||||
//! Font initialization parameters.
|
||||
struct Font_FTFontParams
|
||||
{
|
||||
unsigned int PointSize; //!< face size in points (1/72 inch)
|
||||
unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size()
|
||||
bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default
|
||||
bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default
|
||||
unsigned int PointSize; //!< face size in points (1/72 inch)
|
||||
unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size()
|
||||
bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default
|
||||
bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default
|
||||
|
||||
//! Empty constructor.
|
||||
Font_FTFontParams() : PointSize (0), Resolution (72u), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {}
|
||||
@@ -68,6 +69,69 @@ public:
|
||||
const Font_FTFontParams& theParams,
|
||||
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:
|
||||
|
||||
//! Create uninitialized instance.
|
||||
@@ -119,6 +183,13 @@ public:
|
||||
const Font_FTFontParams& theParams,
|
||||
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.
|
||||
//! 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; }
|
||||
@@ -136,10 +207,10 @@ public:
|
||||
Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
|
||||
|
||||
//! @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).
|
||||
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.
|
||||
Standard_EXPORT float Ascender() const;
|
||||
@@ -163,6 +234,9 @@ public:
|
||||
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.
|
||||
//! Assuming text rendered horizontally.
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
@@ -187,8 +261,9 @@ public:
|
||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext);
|
||||
|
||||
//! @return glyphs number in this font.
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber() const;
|
||||
//! Return glyphs number in this font.
|
||||
//! @param theToIncludeFallback if TRUE then the number will include fallback list
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! Retrieve glyph bitmap rectangle
|
||||
Standard_EXPORT void GlyphRect (Font_Rect& theRect) const;
|
||||
@@ -262,18 +337,25 @@ protected:
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Initialize fallback font.
|
||||
Standard_EXPORT bool findAndInitFallback (Font_UnicodeSubset theSubset);
|
||||
|
||||
protected:
|
||||
|
||||
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
||||
Handle(NCollection_Buffer) myBuffer; //!< memory buffer
|
||||
Handle(Font_FTFont) myFallbackFaces[Font_UnicodeSubset_NB]; //!< fallback fonts
|
||||
FT_Face myFTFace; //!< FT face object
|
||||
FT_Face myActiveFTFace; //!< active FT face object (the main of fallback)
|
||||
TCollection_AsciiString myFontPath; //!< font path
|
||||
Font_FTFontParams myFontParams; //!< font initialization parameters
|
||||
Font_FontAspect myFontAspect; //!< font initialization aspect
|
||||
float myWidthScaling; //!< scale glyphs along X-axis
|
||||
int32_t myLoadFlags; //!< default load flags
|
||||
|
||||
Image_PixMap myGlyphImg; //!< cached glyph plane
|
||||
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",
|
||||
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
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -193,6 +197,16 @@ Handle(Font_FontMgr) Font_FontMgr::GetInstance()
|
||||
return _mgr;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ToUseUnicodeSubsetFallback
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean& Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||
{
|
||||
static Standard_Boolean TheToUseUnicodeSubsetFallback = true;
|
||||
return TheToUseUnicodeSubsetFallback;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : addFontAlias
|
||||
// purpose :
|
||||
@@ -239,6 +253,7 @@ Font_FontMgr::Font_FontMgr()
|
||||
Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aCJK = 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,
|
||||
// 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 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 ("courier", aMono); // Font_NOF_ASCII_MONO
|
||||
addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
|
||||
@@ -308,6 +332,7 @@ Font_FontMgr::Font_FontMgr()
|
||||
addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
|
||||
addFontAlias ("cjk", aCJK); // Font_NOF_CJK
|
||||
addFontAlias ("nsimsun", aCJK);
|
||||
addFontAlias ("arabic", anArab); // Font_NOF_ARABIC
|
||||
addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
|
||||
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()
|
||||
{
|
||||
myFontMap.Clear();
|
||||
Handle(Font_FTLibrary) aFtLibrary;
|
||||
Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
|
||||
|
||||
#if defined(OCCT_UWP)
|
||||
// system font files are not accessible
|
||||
@@ -407,7 +432,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
static const DWORD aBufferSize = 256;
|
||||
char aNameBuff[aBufferSize];
|
||||
char aPathBuff[aBufferSize];
|
||||
@@ -450,61 +474,86 @@ void Font_FontMgr::InitFontDataBase()
|
||||
|
||||
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
||||
|
||||
// read fonts directories from font service config file (obsolete)
|
||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||
if (FcConfig* aFcCfg = FcInitLoadConfig())
|
||||
{
|
||||
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
|
||||
OSD_File aFile (aFileOfFontsPath);
|
||||
if (!aFile.Exists())
|
||||
if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
if (!aFile.IsOpen())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Integer aNByte = 256;
|
||||
Standard_Integer aNbyteRead;
|
||||
TCollection_AsciiString aStr; // read string with information
|
||||
while (!aFile.IsAtEnd())
|
||||
{
|
||||
Standard_Integer aLocation = -1;
|
||||
Standard_Integer aPathLocation = -1;
|
||||
|
||||
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
|
||||
aLocation = aStr.Search ("catalogue=");
|
||||
if (aLocation < 0)
|
||||
for (;;)
|
||||
{
|
||||
aLocation = aStr.Search ("catalogue =");
|
||||
}
|
||||
|
||||
aPathLocation = aStr.Search ("/");
|
||||
if (aLocation > 0 && aPathLocation > 0)
|
||||
{
|
||||
aStr = aStr.Split (aPathLocation - 1);
|
||||
TCollection_AsciiString aFontPath;
|
||||
Standard_Integer aPathNumber = 1;
|
||||
do
|
||||
FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
|
||||
if (aFcFolder == NULL)
|
||||
{
|
||||
// Getting directory paths, which can be splitted by "," or ":"
|
||||
aFontPath = aStr.Token (":,", aPathNumber);
|
||||
aFontPath.RightAdjust();
|
||||
if (!aFontPath.IsEmpty())
|
||||
{
|
||||
OSD_Path aPath(aFontPath);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
aPathNumber++;
|
||||
break;
|
||||
}
|
||||
while (!aFontPath.IsEmpty());
|
||||
|
||||
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);
|
||||
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)
|
||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||
{
|
||||
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
|
||||
OSD_File aFile (aFileOfFontsPath);
|
||||
if (!aFile.Exists())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
if (!aFile.IsOpen())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Integer aNByte = 256;
|
||||
Standard_Integer aNbyteRead;
|
||||
TCollection_AsciiString aStr; // read string with information
|
||||
while (!aFile.IsAtEnd())
|
||||
{
|
||||
Standard_Integer aLocation = -1;
|
||||
Standard_Integer aPathLocation = -1;
|
||||
|
||||
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
|
||||
aLocation = aStr.Search ("catalogue=");
|
||||
if (aLocation < 0)
|
||||
{
|
||||
aLocation = aStr.Search ("catalogue =");
|
||||
}
|
||||
|
||||
aPathLocation = aStr.Search ("/");
|
||||
if (aLocation > 0 && aPathLocation > 0)
|
||||
{
|
||||
aStr = aStr.Split (aPathLocation - 1);
|
||||
TCollection_AsciiString aFontPath;
|
||||
Standard_Integer aPathNumber = 1;
|
||||
do
|
||||
{
|
||||
// Getting directory paths, which can be splitted by "," or ":"
|
||||
aFontPath = aStr.Token (":,", aPathNumber);
|
||||
aFontPath.RightAdjust();
|
||||
if (!aFontPath.IsEmpty())
|
||||
{
|
||||
OSD_Path aPath(aFontPath);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
aPathNumber++;
|
||||
}
|
||||
while (!aFontPath.IsEmpty());
|
||||
}
|
||||
}
|
||||
aFile.Close();
|
||||
}
|
||||
aFile.Close();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -524,7 +573,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
|
||||
anIter.More(); anIter.Next())
|
||||
{
|
||||
@@ -686,6 +734,24 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& th
|
||||
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
|
||||
// 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
|
||||
aFont = myFontMap.Find (TCollection_AsciiString());
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Font_NListOfSystemFont.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
@@ -55,6 +56,9 @@ public:
|
||||
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:
|
||||
|
||||
//! Return the list of available fonts.
|
||||
@@ -106,7 +110,14 @@ public:
|
||||
{
|
||||
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.
|
||||
Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
|
||||
|
||||
|
@@ -16,8 +16,9 @@
|
||||
#define Font_NOF_MONOSPACE "monospace"
|
||||
#define Font_NOF_SERIF "serif"
|
||||
#define Font_NOF_SANS_SERIF "sans-serif"
|
||||
#define Font_NOF_CJK "cjk"
|
||||
#define Font_NOF_KOREAN "korean"
|
||||
#define Font_NOF_CJK "cjk" // Font_UnicodeSubset_CJK
|
||||
#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_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
|
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@
|
||||
#include <DrawTrSurf_Curve2d.hxx>
|
||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||
#include <Geom2dAPI_ExtremaCurveCurve.hxx>
|
||||
#include <Geom2dAPI_Interpolate.hxx>
|
||||
#include <Geom2dAPI_PointsToBSpline.hxx>
|
||||
#include <Geom2dAPI_InterCurveCurve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
@@ -178,7 +179,6 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
|
||||
|
||||
else {
|
||||
// test points ou ordonnees
|
||||
hasPoints = Standard_False;
|
||||
Standard_Integer nc = n - 3;
|
||||
if (nc == 2 * Nb) {
|
||||
// points
|
||||
@@ -190,6 +190,7 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
|
||||
}
|
||||
else if (nc - 2 == Nb) {
|
||||
// YValues
|
||||
hasPoints = Standard_False;
|
||||
nc = 5;
|
||||
X0 = Draw::Atof(a[3]);
|
||||
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;
|
||||
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
|
||||
{
|
||||
Geom2dAPI_PointsToBSpline anApprox (Points, Dmin, Dmax, GeomAbs_C2, Tol2d);
|
||||
if (!anApprox.IsDone())
|
||||
{
|
||||
di << "not done";
|
||||
return 1;
|
||||
}
|
||||
TheCurve = anApprox.Curve();
|
||||
}
|
||||
}
|
||||
else
|
||||
TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
|
||||
{
|
||||
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);
|
||||
di << a[1];
|
||||
|
@@ -15,8 +15,6 @@ Graphic3d_Aspects.cxx
|
||||
Graphic3d_Aspects.hxx
|
||||
Graphic3d_AspectFillArea3d.cxx
|
||||
Graphic3d_AspectFillArea3d.hxx
|
||||
Graphic3d_AspectFillCapping.cxx
|
||||
Graphic3d_AspectFillCapping.hxx
|
||||
Graphic3d_AspectLine3d.cxx
|
||||
Graphic3d_AspectLine3d.hxx
|
||||
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
|
@@ -12,22 +12,13 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Graphic3d_CView.hxx>
|
||||
|
||||
#include <Graphic3d_Layer.hxx>
|
||||
#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
|
||||
#include <Graphic3d_StructureManager.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)
|
||||
|
||||
namespace
|
||||
{
|
||||
static const int THE_DEFAULT_LAYERS[] = { Graphic3d_ZLayerId_Top,
|
||||
Graphic3d_ZLayerId_Topmost,
|
||||
Graphic3d_ZLayerId_BotOSD,
|
||||
Graphic3d_ZLayerId_TopOSD };
|
||||
|
||||
static const int THE_NB_DEFAULT_LAYERS = sizeof(THE_DEFAULT_LAYERS) / sizeof(*THE_DEFAULT_LAYERS);
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
@@ -357,6 +348,28 @@ void Graphic3d_CView::Update (const Graphic3d_ZLayerId theLayerId)
|
||||
InvalidateZLayerBoundingBox (theLayerId);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InvalidateZLayerBoundingBox
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_CView::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId)
|
||||
{
|
||||
if (Handle(Graphic3d_Layer) aLayer = Layer (theLayerId))
|
||||
{
|
||||
aLayer->InvalidateBoundingBox();
|
||||
return;
|
||||
}
|
||||
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
if (aLayer->NbOfTransformPersistenceObjects() > 0)
|
||||
{
|
||||
aLayer->InvalidateBoundingBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ContainsFacet
|
||||
// purpose :
|
||||
@@ -407,40 +420,25 @@ void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructur
|
||||
// =======================================================================
|
||||
Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
|
||||
{
|
||||
Bnd_Box aResult;
|
||||
|
||||
if (!IsDefined())
|
||||
{
|
||||
return aResult;
|
||||
return Bnd_Box();
|
||||
}
|
||||
|
||||
Handle(Graphic3d_Camera) aCamera = Camera();
|
||||
Standard_Integer aWinWidth = 0;
|
||||
Standard_Integer aWinHeight = 0;
|
||||
const Handle(Graphic3d_Camera)& aCamera = Camera();
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
|
||||
Window()->Size (aWinWidth, aWinHeight);
|
||||
|
||||
for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
|
||||
Bnd_Box aResult;
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
Bnd_Box aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
|
||||
aCamera,
|
||||
aWinWidth,
|
||||
aWinHeight,
|
||||
theToIncludeAuxiliary);
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
Bnd_Box aBox = aLayer->BoundingBox (Identification(),
|
||||
aCamera,
|
||||
aWinSize.x(), aWinSize.y(),
|
||||
theToIncludeAuxiliary);
|
||||
aResult.Add (aBox);
|
||||
}
|
||||
|
||||
Standard_Integer aMaxZLayer = ZLayerMax();
|
||||
for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
|
||||
{
|
||||
Bnd_Box aBox = ZLayerBoundingBox (aLayerId,
|
||||
aCamera,
|
||||
aWinWidth,
|
||||
aWinHeight,
|
||||
theToIncludeAuxiliary);
|
||||
aResult.Add(aBox);
|
||||
}
|
||||
|
||||
return aResult;
|
||||
}
|
||||
|
||||
@@ -455,21 +453,15 @@ Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
Handle(Graphic3d_Camera) aCamera = Camera();
|
||||
Standard_Integer aWinWidth = 0;
|
||||
Standard_Integer aWinHeight = 0;
|
||||
|
||||
Window()->Size (aWinWidth, aWinHeight);
|
||||
const Handle(Graphic3d_Camera)& aCamera = Camera();
|
||||
Graphic3d_Vec2i aWinSize;
|
||||
Window()->Size (aWinSize.x(), aWinSize.y());
|
||||
|
||||
Standard_Real aMaxCoef = 1.0;
|
||||
for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight));
|
||||
}
|
||||
|
||||
for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
|
||||
{
|
||||
aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight));
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
aMaxCoef = Max (aMaxCoef, aLayer->considerZoomPersistenceObjects (Identification(), aCamera, aWinSize.x(), aWinSize.y()));
|
||||
}
|
||||
|
||||
return aMaxCoef;
|
||||
|
@@ -46,6 +46,7 @@
|
||||
|
||||
class Graphic3d_CView;
|
||||
class Graphic3d_GraphicDriver;
|
||||
class Graphic3d_Layer;
|
||||
class Graphic3d_StructureManager;
|
||||
|
||||
DEFINE_STANDARD_HANDLE (Graphic3d_CView, Graphic3d_DataStructureManager)
|
||||
@@ -267,32 +268,34 @@ public:
|
||||
//! Marks BVH tree and the set of BVH primitives of correspondent priority list with id theLayerId as outdated.
|
||||
virtual void InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) = 0;
|
||||
|
||||
//! Add a new top-level z layer with ID <theLayerId> for
|
||||
//! the view. Z layers allow drawing structures in higher layers
|
||||
//! in foreground of structures in lower layers. To add a structure
|
||||
//! to desired layer on display it is necessary to set the layer
|
||||
//! ID for the structure.
|
||||
virtual void AddZLayer (const Graphic3d_ZLayerId theLayerId) = 0;
|
||||
//! Add a layer to the view.
|
||||
//! @param theNewLayerId [in] id of new layer, should be > 0 (negative values are reserved for default layers).
|
||||
//! @param theSettings [in] new layer settings
|
||||
//! @param theLayerAfter [in] id of layer to append new layer before
|
||||
virtual void InsertLayerBefore (const Graphic3d_ZLayerId theNewLayerId,
|
||||
const Graphic3d_ZLayerSettings& theSettings,
|
||||
const Graphic3d_ZLayerId theLayerAfter) = 0;
|
||||
|
||||
//! Add a layer to the view.
|
||||
//! @param theNewLayerId [in] id of new layer, should be > 0 (negative values are reserved for default layers).
|
||||
//! @param theSettings [in] new layer settings
|
||||
//! @param theLayerBefore [in] id of layer to append new layer after
|
||||
virtual void InsertLayerAfter (const Graphic3d_ZLayerId theNewLayerId,
|
||||
const Graphic3d_ZLayerSettings& theSettings,
|
||||
const Graphic3d_ZLayerId theLayerBefore) = 0;
|
||||
|
||||
//! Returns the maximum Z layer ID.
|
||||
//! First layer ID is Graphic3d_ZLayerId_Default, last ID is ZLayerMax().
|
||||
virtual Standard_Integer ZLayerMax() const = 0;
|
||||
|
||||
//! Returns the bounding box of all structures displayed in the Z layer.
|
||||
virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const = 0;
|
||||
//! Returns the list of layers.
|
||||
virtual const NCollection_List<Handle(Graphic3d_Layer)>& Layers() const = 0;
|
||||
|
||||
//! Returns layer with given ID or NULL if undefined.
|
||||
virtual Handle(Graphic3d_Layer) Layer (const Graphic3d_ZLayerId theLayerId) const = 0;
|
||||
|
||||
//! Returns the bounding box of all structures displayed in the Z layer.
|
||||
//! @param theLayerId layer identifier
|
||||
//! @param theCamera camera definition
|
||||
//! @param theWindowWidth viewport width (for applying transformation-persistence)
|
||||
//! @param theWindowHeight viewport height (for applying transformation-persistence)
|
||||
//! @param theToIncludeAuxiliary consider also auxiliary presentations (with infinite flag or with trihedron transformation persistence)
|
||||
//! @return computed bounding box
|
||||
virtual Bnd_Box ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
|
||||
const Handle(Graphic3d_Camera)& theCamera,
|
||||
const Standard_Integer theWindowWidth,
|
||||
const Standard_Integer theWindowHeight,
|
||||
const Standard_Boolean theToIncludeAuxiliary) const = 0;
|
||||
Standard_EXPORT virtual void InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId);
|
||||
|
||||
//! Remove Z layer from the specified view. All structures
|
||||
//! displayed at the moment in layer will be displayed in default layer
|
||||
@@ -447,12 +450,6 @@ private:
|
||||
virtual void changePriority (const Handle(Graphic3d_CStructure)& theCStructure,
|
||||
const Standard_Integer theNewPriority) = 0;
|
||||
|
||||
//! Returns zoom-scale factor.
|
||||
virtual Standard_Real considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
|
||||
const Handle(Graphic3d_Camera)& theCamera,
|
||||
const Standard_Integer theWindowWidth,
|
||||
const Standard_Integer theWindowHeight) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Standard_Integer myId;
|
||||
|
@@ -103,6 +103,21 @@ Graphic3d_Camera::Graphic3d_Camera()
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther)
|
||||
: myUp (0.0, 1.0, 0.0),
|
||||
myEye (0.0, 0.0, -1500.0),
|
||||
myCenter (0.0, 0.0, 0.0),
|
||||
myAxialScale (1.0, 1.0, 1.0),
|
||||
myProjType (Projection_Orthographic),
|
||||
myFOVy (45.0),
|
||||
myFOVyTan (Tan (DTR_HALF * 45.0)),
|
||||
myZNear (DEFAULT_ZNEAR),
|
||||
myZFar (DEFAULT_ZFAR),
|
||||
myAspect (1.0),
|
||||
myScale (1000.0),
|
||||
myZFocus (1.0),
|
||||
myZFocusType (FocusType_Relative),
|
||||
myIOD (0.05),
|
||||
myIODType (IODType_Relative)
|
||||
{
|
||||
myWorldViewProjState.Initialize (this);
|
||||
|
||||
|
@@ -24,6 +24,19 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane,Standard_Transient)
|
||||
namespace
|
||||
{
|
||||
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 :
|
||||
// =======================================================================
|
||||
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 :
|
||||
// =======================================================================
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -49,27 +84,42 @@ Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_Vec4d& theEquation)
|
||||
// function : Graphic3d_ClipPlane
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Graphic3d_ClipPlane& theOther)
|
||||
: Standard_Transient (theOther)
|
||||
Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& 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();
|
||||
init (theOther.myPlane,
|
||||
theOther.myEquationRev,
|
||||
theOther.myIsOn,
|
||||
theOther.myIsCapping,
|
||||
theOther.ToOverrideCappingAspect(),
|
||||
theOther.CappingSectionStyle());
|
||||
updateInversedPlane();
|
||||
makeId();
|
||||
*myAspect = *theOther.CappingAspect();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Graphic3d_ClipPlane
|
||||
// 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();
|
||||
makeId();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -81,7 +131,7 @@ void Graphic3d_ClipPlane::SetEquation (const Graphic3d_Vec4d& theEquation)
|
||||
myPlane = gp_Pln (theEquation.x(), theEquation.y(), theEquation.z(), theEquation.w());
|
||||
myEquation = theEquation;
|
||||
updateInversedPlane();
|
||||
myOrientationDirty = Standard_True;
|
||||
myEquationMod++;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -93,7 +143,7 @@ void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
|
||||
myPlane = thePlane;
|
||||
thePlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
||||
updateInversedPlane();
|
||||
myOrientationDirty = Standard_True;
|
||||
myEquationMod++;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -128,106 +178,119 @@ Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane::Clone() const
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCappingSectionStyle
|
||||
// function : SetCappingMaterial
|
||||
// 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 :
|
||||
// =======================================================================
|
||||
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[] = {
|
||||
static_cast<Standard_ShortReal> (myEquation[0]),
|
||||
static_cast<Standard_ShortReal> (myEquation[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())
|
||||
myAspect->SetTextureMapOn();
|
||||
Handle(Graphic3d_TextureSet) aTextureSet = myAspect->TextureSet();
|
||||
if (aTextureSet.IsNull() || aTextureSet->Size() != 1)
|
||||
{
|
||||
aSide1[0] = 1.0f;
|
||||
aTextureSet = new Graphic3d_TextureSet (theTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
aSide1[0] = aDirection[2] / aMagintude;
|
||||
aSide1[2] = -aDirection[0] / aMagintude;
|
||||
aTextureSet->SetFirst (theTexture);
|
||||
}
|
||||
|
||||
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;
|
||||
myAspect->SetTextureSet (aTextureSet);
|
||||
}
|
||||
|
||||
return myOrientationMat;
|
||||
else
|
||||
{
|
||||
myAspect->SetTextureMapOff();
|
||||
myAspect->SetTextureSet (Handle(Graphic3d_TextureSet)());
|
||||
}
|
||||
++myAspectMod;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : init
|
||||
// function : SetCappingHatch
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_ClipPlane::init (const gp_Pln& thePlane,
|
||||
const Graphic3d_Vec4d& theEquationRev,
|
||||
const Standard_Boolean theIsOn,
|
||||
const Standard_Boolean theIsCapping,
|
||||
const Standard_Boolean theOverrideStyle,
|
||||
const Handle(Graphic3d_AspectFillCapping)& theStyle)
|
||||
void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle)
|
||||
{
|
||||
if (myEntityUID.IsEmpty())
|
||||
{
|
||||
myEntityUID = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
|
||||
}
|
||||
myAspect->SetHatchStyle (theStyle);
|
||||
++myAspectMod;
|
||||
}
|
||||
|
||||
myPrevInChain = NULL;
|
||||
myEquationRev = theEquationRev;
|
||||
myChainLenFwd = 1;
|
||||
myPlane = thePlane;
|
||||
myPlane.Coefficients (myEquation[0], myEquation[1], myEquation[2], myEquation[3]);
|
||||
myIsOn = theIsOn;
|
||||
myIsCapping = theIsCapping;
|
||||
myOverrideObjectStyle = theOverrideStyle;
|
||||
mySectionStyle = theStyle.IsNull() ? new Graphic3d_AspectFillCapping() : theStyle;
|
||||
myOrientationDirty = Standard_True;
|
||||
// =======================================================================
|
||||
// function : SetCappingCustomHatch
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Graphic3d_ClipPlane::SetCappingCustomHatch (const Handle(Graphic3d_HatchStyle)& theStyle)
|
||||
{
|
||||
myAspect->SetHatchStyle (theStyle);
|
||||
++myAspectMod;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// 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)
|
||||
{
|
||||
myOrientationDirty = Standard_True;
|
||||
++myEquationMod;
|
||||
if (!myNextInChain.IsNull())
|
||||
{
|
||||
myNextInChain->myPrevInChain = NULL;
|
||||
|
@@ -19,12 +19,9 @@
|
||||
#include <Aspect_HatchStyle.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <Graphic3d_AspectFillArea3d.hxx>
|
||||
#include <Graphic3d_AspectFillCapping.hxx>
|
||||
#include <Graphic3d_BndBox3d.hxx>
|
||||
#include <Graphic3d_CappingFlags.hxx>
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
#include <Graphic3d_TextureMap.hxx>
|
||||
#include <NCollection_Handle.hxx>
|
||||
#include <NCollection_Vec4.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <Standard_TypeDef.hxx>
|
||||
@@ -169,6 +166,44 @@ public:
|
||||
|
||||
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.
|
||||
//! 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.
|
||||
const TCollection_AsciiString& GetId() const
|
||||
{
|
||||
return myEntityUID;
|
||||
return myId;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Returns style used for drawing capping section.
|
||||
//! Return capping 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.
|
||||
Standard_EXPORT void SetCappingSectionStyle (const Handle(Graphic3d_AspectFillCapping)& theStyle);
|
||||
//! Assign capping aspect.
|
||||
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:
|
||||
|
||||
@@ -294,25 +352,14 @@ public: // @name modification counters
|
||||
{
|
||||
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:
|
||||
|
||||
//! Initializes plane and makes unique identifier (UID) to differentiate clipping plane entities.
|
||||
void init (const gp_Pln& thePlane = gp_Pln(),
|
||||
const Graphic3d_Vec4d& theEquationRev = Graphic3d_Vec4d(0.0, 0.0,-1.0, 0.0),
|
||||
const Standard_Boolean theIsOn = Standard_True,
|
||||
const Standard_Boolean theIsCapping = Standard_False,
|
||||
const Standard_Boolean theOverrideStyle = Standard_False,
|
||||
const Handle(Graphic3d_AspectFillCapping)& theStyle = Handle(Graphic3d_AspectFillCapping)());
|
||||
//! Generate unique object id for OpenGL graphic resource manager.
|
||||
void makeId();
|
||||
|
||||
//! Set capping flag.
|
||||
Standard_EXPORT void setCappingFlag (bool theToUse, int theFlag);
|
||||
|
||||
//! Update chain length in backward direction.
|
||||
void updateChainLen();
|
||||
@@ -327,10 +374,10 @@ 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
|
||||
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
|
||||
Graphic3d_Vec4d myEquation; //!< plane equation vector
|
||||
Graphic3d_Vec4d myEquationRev; //!< reversed plane equation
|
||||
@@ -340,9 +387,6 @@ private:
|
||||
unsigned int myAspectMod; //!< modification counter of aspect
|
||||
Standard_Boolean myIsOn; //!< state of the clipping plane
|
||||
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).
|
||||
|
||||
};
|
||||
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
#include <Graphic3d_GraphicDriver.hxx>
|
||||
|
||||
#include <Graphic3d_Layer.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_GraphicDriver,Standard_Transient)
|
||||
|
||||
// =======================================================================
|
||||
@@ -25,70 +27,85 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_GraphicDriver,Standard_Transient)
|
||||
Graphic3d_GraphicDriver::Graphic3d_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp)
|
||||
: myDisplayConnection (theDisp)
|
||||
{
|
||||
// default layers are always presented in display layer sequence it can not be removed
|
||||
// default layers are always presented in display layer sequence and cannot be removed
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings;
|
||||
aSettings.SetName ("UNDERLAY");
|
||||
aSettings.SetImmediate (Standard_False);
|
||||
aSettings.SetRaytracable (Standard_False);
|
||||
aSettings.SetEnvironmentTexture (Standard_False);
|
||||
aSettings.SetEnableDepthTest (Standard_False);
|
||||
aSettings.SetEnableDepthWrite (Standard_False);
|
||||
aSettings.SetClearDepth (Standard_False);
|
||||
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
||||
myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
|
||||
myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
|
||||
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, aSettings);
|
||||
Handle(Graphic3d_Layer) aLayer = new Graphic3d_Layer (Graphic3d_ZLayerId_BotOSD, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aLayer->SetLayerSettings (aSettings);
|
||||
myLayers.Append (aLayer);
|
||||
myLayerIds.Bind (aLayer->LayerId(), aLayer);
|
||||
}
|
||||
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings;
|
||||
aSettings.SetName ("DEFAULT");
|
||||
aSettings.SetImmediate (Standard_False);
|
||||
aSettings.SetRaytracable (Standard_True);
|
||||
aSettings.SetEnvironmentTexture (Standard_True);
|
||||
aSettings.SetEnableDepthTest (Standard_True);
|
||||
aSettings.SetEnableDepthWrite (Standard_True);
|
||||
aSettings.SetClearDepth (Standard_False);
|
||||
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
||||
myLayerIds.Add (Graphic3d_ZLayerId_Default);
|
||||
myLayerSeq.Append (Graphic3d_ZLayerId_Default);
|
||||
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Default, aSettings);
|
||||
Handle(Graphic3d_Layer) aLayer = new Graphic3d_Layer (Graphic3d_ZLayerId_Default, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aLayer->SetLayerSettings (aSettings);
|
||||
myLayers.Append (aLayer);
|
||||
myLayerIds.Bind (aLayer->LayerId(), aLayer);
|
||||
}
|
||||
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings;
|
||||
aSettings.SetName ("TOP");
|
||||
aSettings.SetImmediate (Standard_True);
|
||||
aSettings.SetRaytracable (Standard_False);
|
||||
aSettings.SetEnvironmentTexture (Standard_True);
|
||||
aSettings.SetEnableDepthTest (Standard_True);
|
||||
aSettings.SetEnableDepthWrite (Standard_True);
|
||||
aSettings.SetClearDepth (Standard_False);
|
||||
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
||||
myLayerIds.Add (Graphic3d_ZLayerId_Top);
|
||||
myLayerSeq.Append (Graphic3d_ZLayerId_Top);
|
||||
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Top, aSettings);
|
||||
Handle(Graphic3d_Layer) aLayer = new Graphic3d_Layer (Graphic3d_ZLayerId_Top, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aLayer->SetLayerSettings (aSettings);
|
||||
myLayers.Append (aLayer);
|
||||
myLayerIds.Bind (aLayer->LayerId(), aLayer);
|
||||
}
|
||||
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings;
|
||||
aSettings.SetName ("TOPMOST");
|
||||
aSettings.SetImmediate (Standard_True);
|
||||
aSettings.SetRaytracable (Standard_False);
|
||||
aSettings.SetEnvironmentTexture (Standard_True);
|
||||
aSettings.SetEnableDepthTest (Standard_True);
|
||||
aSettings.SetEnableDepthWrite (Standard_True);
|
||||
aSettings.SetClearDepth (Standard_True);
|
||||
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
||||
myLayerIds.Add (Graphic3d_ZLayerId_Topmost);
|
||||
myLayerSeq.Append (Graphic3d_ZLayerId_Topmost);
|
||||
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Topmost, aSettings);
|
||||
Handle(Graphic3d_Layer) aLayer = new Graphic3d_Layer (Graphic3d_ZLayerId_Topmost, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aLayer->SetLayerSettings (aSettings);
|
||||
myLayers.Append (aLayer);
|
||||
myLayerIds.Bind (aLayer->LayerId(), aLayer);
|
||||
}
|
||||
|
||||
{
|
||||
Graphic3d_ZLayerSettings aSettings;
|
||||
aSettings.SetName ("OVERLAY");
|
||||
aSettings.SetImmediate (Standard_True);
|
||||
aSettings.SetRaytracable (Standard_False);
|
||||
aSettings.SetEnvironmentTexture (Standard_False);
|
||||
aSettings.SetEnableDepthTest (Standard_False);
|
||||
aSettings.SetEnableDepthWrite (Standard_False);
|
||||
aSettings.SetClearDepth (Standard_False);
|
||||
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
|
||||
myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
|
||||
myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
|
||||
myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, aSettings);
|
||||
Handle(Graphic3d_Layer) aLayer = new Graphic3d_Layer (Graphic3d_ZLayerId_TopOSD, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aLayer->SetLayerSettings (aSettings);
|
||||
myLayers.Append (aLayer);
|
||||
myLayerIds.Bind (aLayer->LayerId(), aLayer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,52 +142,130 @@ void Graphic3d_GraphicDriver::RemoveIdentification(const Standard_Integer theId)
|
||||
//=======================================================================
|
||||
const Graphic3d_ZLayerSettings& Graphic3d_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId), "Graphic3d_GraphicDriver::ZLayerSettings, Layer with theLayerId does not exist");
|
||||
return myMapOfZLayerSettings.Find (theLayerId);
|
||||
const Handle(Graphic3d_Layer)* aLayer = myLayerIds.Seek (theLayerId);
|
||||
if (aLayer == NULL)
|
||||
{
|
||||
throw Standard_OutOfRange ("Graphic3d_GraphicDriver::ZLayerSettings, Layer with theLayerId does not exist");
|
||||
}
|
||||
return (*aLayer)->LayerSettings();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : addZLayerIndex
|
||||
//function : ZLayers
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
|
||||
void Graphic3d_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const
|
||||
{
|
||||
// remove index
|
||||
for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
|
||||
theLayerSeq.Clear();
|
||||
|
||||
// append normal layers
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
if (aLayerIt.Value() == theLayerId)
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
if (!aLayer->IsImmediate())
|
||||
{
|
||||
myLayerSeq.Remove (aLayerIt);
|
||||
break;
|
||||
theLayerSeq.Append (aLayer->LayerId());
|
||||
}
|
||||
}
|
||||
|
||||
if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate())
|
||||
// append immediate layers
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
myLayerSeq.Append (theLayerId);
|
||||
return;
|
||||
}
|
||||
|
||||
for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
|
||||
{
|
||||
const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value());
|
||||
if (aSettings.IsImmediate())
|
||||
const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
|
||||
if (aLayer->IsImmediate())
|
||||
{
|
||||
aLayerIt.Previous();
|
||||
if (aLayerIt.More())
|
||||
theLayerSeq.Append (aLayer->LayerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : InsertLayerBefore
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_GraphicDriver::InsertLayerBefore (const Graphic3d_ZLayerId theNewLayerId,
|
||||
const Graphic3d_ZLayerSettings& theSettings,
|
||||
const Graphic3d_ZLayerId theLayerAfter)
|
||||
{
|
||||
Standard_ASSERT_RAISE (theNewLayerId > 0,
|
||||
"Graphic3d_GraphicDriver::InsertLayerBefore, negative and zero IDs are reserved");
|
||||
Standard_ASSERT_RAISE (!myLayerIds.IsBound (theNewLayerId),
|
||||
"Graphic3d_GraphicDriver::InsertLayerBefore, Layer with theLayerId already exists");
|
||||
|
||||
Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aNewLayer->SetLayerSettings (theSettings);
|
||||
|
||||
Handle(Graphic3d_Layer) anOtherLayer;
|
||||
if (theLayerAfter != Graphic3d_ZLayerId_UNKNOWN
|
||||
&& myLayerIds.Find (theLayerAfter, anOtherLayer))
|
||||
{
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
if (aLayerIter.Value() == anOtherLayer)
|
||||
{
|
||||
myLayerSeq.InsertAfter (aLayerIt, theLayerId);
|
||||
return;
|
||||
myLayers.InsertBefore (aNewLayer, aLayerIter);
|
||||
break;
|
||||
}
|
||||
|
||||
// first non-immediate layer
|
||||
myLayerSeq.Prepend (theLayerId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myLayers.Prepend (aNewLayer);
|
||||
}
|
||||
myLayerIds.Bind (theNewLayerId, aNewLayer);
|
||||
}
|
||||
|
||||
// no immediate layers
|
||||
myLayerSeq.Append (theLayerId);
|
||||
//=======================================================================
|
||||
//function : InsertLayerAfter
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_GraphicDriver::InsertLayerAfter (const Graphic3d_ZLayerId theNewLayerId,
|
||||
const Graphic3d_ZLayerSettings& theSettings,
|
||||
const Graphic3d_ZLayerId theLayerBefore)
|
||||
{
|
||||
Standard_ASSERT_RAISE (theNewLayerId > 0,
|
||||
"Graphic3d_GraphicDriver::InsertLayerAfter, negative and zero IDs are reserved");
|
||||
Standard_ASSERT_RAISE (!myLayerIds.IsBound (theNewLayerId),
|
||||
"Graphic3d_GraphicDriver::InsertLayerAfter, Layer with theLayerId already exists");
|
||||
|
||||
Handle(Graphic3d_Layer) aNewLayer = new Graphic3d_Layer (theNewLayerId, 1, Handle(Select3D_BVHBuilder3d)());
|
||||
aNewLayer->SetLayerSettings (theSettings);
|
||||
|
||||
Handle(Graphic3d_Layer) anOtherLayer;
|
||||
if (theLayerBefore != Graphic3d_ZLayerId_UNKNOWN
|
||||
&& myLayerIds.Find (theLayerBefore, anOtherLayer))
|
||||
{
|
||||
for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next())
|
||||
{
|
||||
if (aLayerIter.Value() == anOtherLayer)
|
||||
{
|
||||
myLayers.InsertAfter (aNewLayer, aLayerIter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myLayers.Append (aNewLayer);
|
||||
}
|
||||
myLayerIds.Bind (theNewLayerId, aNewLayer);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RemoveZLayer
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Graphic3d_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
|
||||
{
|
||||
Standard_ASSERT_RAISE (theLayerId > 0,
|
||||
"Graphic3d_GraphicDriver::RemoveZLayer, negative and zero IDs are reserved and cannot be removed");
|
||||
|
||||
Handle(Graphic3d_Layer) aLayerDef;
|
||||
myLayerIds.Find (theLayerId, aLayerDef);
|
||||
Standard_ASSERT_RAISE (!aLayerDef.IsNull(),
|
||||
"Graphic3d_GraphicDriver::RemoveZLayer, Layer with theLayerId does not exist");
|
||||
myLayers.Remove (aLayerDef);
|
||||
myLayerIds.UnBind (theLayerId);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -180,20 +275,9 @@ void Graphic3d_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerI
|
||||
void Graphic3d_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
|
||||
const Graphic3d_ZLayerSettings& theSettings)
|
||||
{
|
||||
Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId);
|
||||
if (aSettings != NULL)
|
||||
{
|
||||
const bool isChanged = (aSettings->IsImmediate() != theSettings.IsImmediate());
|
||||
*aSettings = theSettings;
|
||||
if (isChanged)
|
||||
{
|
||||
addZLayerIndex (theLayerId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// abnormal case
|
||||
myMapOfZLayerSettings.Bind (theLayerId, theSettings);
|
||||
addZLayerIndex (theLayerId);
|
||||
}
|
||||
Handle(Graphic3d_Layer) aLayerDef;
|
||||
myLayerIds.Find (theLayerId, aLayerDef);
|
||||
Standard_ASSERT_RAISE (!aLayerDef.IsNull(),
|
||||
"Graphic3d_GraphicDriver::SetZLayerSettings, Layer with theLayerId does not exist");
|
||||
aLayerDef->SetLayerSettings (theSettings);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user