mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c0418c96db | ||
|
83cc25e05b | ||
|
8b536fff48 | ||
|
ac76263667 | ||
|
efc007f044 | ||
|
c45ac27846 | ||
|
4a1eddc2c9 | ||
|
f001c6f012 | ||
|
8271ac6728 | ||
|
293b9f436b | ||
|
acac44d571 | ||
|
7aaed2ce3b | ||
|
da76ea432b | ||
|
53152e6dd9 | ||
|
1a1739b200 | ||
|
fd5c113a03 | ||
|
f74f684b16 | ||
|
621ed3bc36 | ||
|
81d569625e | ||
|
6072d3093c | ||
|
e1b097eb67 | ||
|
92d22d7d62 | ||
|
1b423e3287 | ||
|
cb8519be19 | ||
|
617a2905a9 | ||
|
18559e93cf | ||
|
c2e01cc5cc | ||
|
0acc1ab47c | ||
|
b315a85dd7 | ||
|
411ad1a819 | ||
|
bbf49a300c | ||
|
0bab2704ae |
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR)
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/adm/cmake")
|
||||
|
||||
@@ -6,6 +6,10 @@ set (CMAKE_SUPPRESS_REGENERATION TRUE)
|
||||
|
||||
set (CMAKE_CONFIGURATION_TYPES Release Debug RelWithDebInfo CACHE INTERNAL "" FORCE)
|
||||
|
||||
# set using C++ standard
|
||||
set (BUILD_CPP_STANDARD "C++11" CACHE STRING "Select using c++ standard.")
|
||||
set_property(CACHE BUILD_CPP_STANDARD PROPERTY STRINGS "C++11" "C++14" "C++17" "C++20" "C++23")
|
||||
|
||||
# macro: include patched file if it exists
|
||||
macro (OCCT_INCLUDE_CMAKE_FILE BEING_INCLUDED_FILE)
|
||||
if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/${BEING_INCLUDED_FILE}.cmake")
|
||||
@@ -713,14 +717,14 @@ if (NOT DEFINED ANDROID AND CAN_USE_TBB)
|
||||
add_definitions (-DHAVE_TBB)
|
||||
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/tbb")
|
||||
else()
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBB")
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBB12")
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBBMALLOC")
|
||||
OCCT_CHECK_AND_UNSET ("INSTALL_TBB")
|
||||
endif()
|
||||
else()
|
||||
OCCT_CHECK_AND_UNSET ("USE_TBB")
|
||||
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBB")
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBB12")
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_TBBMALLOC")
|
||||
OCCT_CHECK_AND_UNSET ("INSTALL_TBB")
|
||||
endif()
|
||||
|
@@ -32,15 +32,13 @@ if(__COTIRE_INCLUDED)
|
||||
endif()
|
||||
set(__COTIRE_INCLUDED TRUE)
|
||||
|
||||
# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode
|
||||
# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid
|
||||
if (NOT CMAKE_SCRIPT_MODE_FILE)
|
||||
cmake_policy(PUSH)
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
if (NOT CMAKE_SCRIPT_MODE_FILE)
|
||||
cmake_policy(POP)
|
||||
endif()
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}")
|
||||
set (COTIRE_CMAKE_MODULE_VERSION "1.7.9")
|
||||
|
@@ -12,7 +12,7 @@ endif()
|
||||
|
||||
# TBB
|
||||
if (USE_TBB)
|
||||
set (CSF_TBB "tbb tbbmalloc")
|
||||
set (CSF_TBB "tbb12 tbbmalloc")
|
||||
else()
|
||||
set (CSF_TBB)
|
||||
endif()
|
||||
|
@@ -116,9 +116,9 @@ if (MSVC)
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "[Cc][Ll][Aa][Nn][Gg]"))
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc][Ll][Aa][Nn][Gg]")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshorten-64-to-32")
|
||||
endif()
|
||||
if (BUILD_SHARED_LIBS)
|
||||
@@ -130,14 +130,26 @@ elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMP
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
|
||||
# Set desired C++ standard
|
||||
if ("${BUILD_CPP_STANDARD}" STREQUAL "C++11")
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
elseif ("${BUILD_CPP_STANDARD}" STREQUAL "C++14")
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
elseif ("${BUILD_CPP_STANDARD}" STREQUAL "C++17")
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
elseif ("${BUILD_CPP_STANDARD}" STREQUAL "C++20")
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
elseif ("${BUILD_CPP_STANDARD}" STREQUAL "C++23")
|
||||
set (CMAKE_CXX_STANDARD 23)
|
||||
else ()
|
||||
message (FATAL_ERROR, "misprint in c++ standard name")
|
||||
endif()
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc][Ll][Aa][Nn][Gg]")
|
||||
if (APPLE)
|
||||
# CLang can be used with both libstdc++ and libc++, however on OS X libstdc++ is outdated.
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x -stdlib=libc++ ${CMAKE_CXX_FLAGS}")
|
||||
elseif(NOT WIN32)
|
||||
# CLang for Windows (at least CLang 8.0 distributed with VS 2019)
|
||||
# does not support option "-std=c++0x"
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "-stdlib=libc++ ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
# Optimize size of binaries
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,-s ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
@@ -148,14 +160,10 @@ elseif(MINGW)
|
||||
# workaround bugs in mingw with vtable export
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
|
||||
|
||||
# Require C++11
|
||||
set (CMAKE_CXX_FLAGS "-std=gnu++0x ${CMAKE_CXX_FLAGS}")
|
||||
# Optimize size of binaries
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
||||
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
|
||||
elseif (DEFINED CMAKE_COMPILER_IS_GNUCXX)
|
||||
# Require C++11
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
|
||||
# Optimize size of binaries
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
||||
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
|
||||
|
@@ -80,9 +80,9 @@ macro (OCCT_MAKE_COMPILER_SHORT_NAME)
|
||||
set (COMPILER gcc)
|
||||
elseif (DEFINED CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (COMPILER gxx)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Cc][Ll][Aa][Nn][Gg]")
|
||||
set (COMPILER clang)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Ii][Nn][Tt][Ee][Ll]")
|
||||
set (COMPILER icc)
|
||||
else()
|
||||
set (COMPILER ${CMAKE_GENERATOR})
|
||||
@@ -589,9 +589,7 @@ macro (OCCT_UPDATE_TARGET_FILE)
|
||||
endif()
|
||||
|
||||
install (CODE
|
||||
"cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0007 NEW)
|
||||
string (TOLOWER \"\${CMAKE_INSTALL_CONFIG_NAME}\" CMAKE_INSTALL_CONFIG_NAME_LOWERCASE)
|
||||
"string (TOLOWER \"\${CMAKE_INSTALL_CONFIG_NAME}\" CMAKE_INSTALL_CONFIG_NAME_LOWERCASE)
|
||||
file (GLOB ALL_OCCT_TARGET_FILES \"${INSTALL_DIR}/${INSTALL_DIR_CMAKE}/OpenCASCADE*Targets-\${CMAKE_INSTALL_CONFIG_NAME_LOWERCASE}.cmake\")
|
||||
foreach(TARGET_FILENAME \${ALL_OCCT_TARGET_FILES})
|
||||
file (STRINGS \"\${TARGET_FILENAME}\" TARGET_FILE_CONTENT)
|
||||
@@ -600,8 +598,7 @@ macro (OCCT_UPDATE_TARGET_FILE)
|
||||
string (REGEX REPLACE \"[\\\\]?[\\\$]{OCCT_INSTALL_BIN_LETTER}\" \"\${OCCT_INSTALL_BIN_LETTER}\" line \"\${line}\")
|
||||
file (APPEND \"\${TARGET_FILENAME}\" \"\${line}\\n\")
|
||||
endforeach()
|
||||
endforeach()
|
||||
cmake_policy(POP)")
|
||||
endforeach()")
|
||||
endmacro()
|
||||
|
||||
macro (OCCT_INSERT_CODE_FOR_TARGET)
|
||||
@@ -615,17 +612,14 @@ macro (OCCT_INSERT_CODE_FOR_TARGET)
|
||||
endmacro()
|
||||
|
||||
macro (OCCT_UPDATE_DRAW_DEFAULT_FILE)
|
||||
install(CODE "cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0007 NEW)
|
||||
set (DRAW_DEFAULT_FILE_NAME \"${INSTALL_DIR}/${INSTALL_DIR_RESOURCE}/DrawResources/DrawPlugin\")
|
||||
install(CODE "set (DRAW_DEFAULT_FILE_NAME \"${INSTALL_DIR}/${INSTALL_DIR_RESOURCE}/DrawResources/DrawPlugin\")
|
||||
file (STRINGS \"\${DRAW_DEFAULT_FILE_NAME}\" DRAW_DEFAULT_CONTENT)
|
||||
file (REMOVE \"\${DRAW_DEFAULT_FILE_NAME}\")
|
||||
foreach (line IN LISTS DRAW_DEFAULT_CONTENT)
|
||||
string (REGEX MATCH \": TK\([a-zA-Z]+\)$\" IS_TK_LINE \"\${line}\")
|
||||
string (REGEX REPLACE \": TK\([a-zA-Z]+\)$\" \": TK\${CMAKE_MATCH_1}${BUILD_SHARED_LIBRARY_NAME_POSTFIX}\" line \"\${line}\")
|
||||
file (APPEND \"\${DRAW_DEFAULT_FILE_NAME}\" \"\${line}\\n\")
|
||||
endforeach()
|
||||
cmake_policy(POP)")
|
||||
endforeach()")
|
||||
endmacro()
|
||||
|
||||
macro (OCCT_CREATE_SYMLINK_TO_FILE LIBRARY_NAME LINK_NAME)
|
||||
|
@@ -320,10 +320,10 @@ foreach (USED_ITEM ${USED_EXTERNLIB_AND_TOOLKITS})
|
||||
else() # get CSF_ value
|
||||
set (CURRENT_CSF ${${USED_ITEM}})
|
||||
if (NOT "x${CURRENT_CSF}" STREQUAL "x")
|
||||
if ("${CURRENT_CSF}" STREQUAL "CSF_OpenGlLibs")
|
||||
if ("${CURRENT_CSF}" STREQUAL "${CSF_OpenGlLibs}")
|
||||
add_definitions (-DHAVE_OPENGL)
|
||||
endif()
|
||||
if ("${CURRENT_CSF}" STREQUAL "CSF_OpenGlesLibs")
|
||||
if ("${CURRENT_CSF}" STREQUAL "${CSF_OpenGlesLibs}")
|
||||
add_definitions (-DHAVE_GLES2)
|
||||
endif()
|
||||
|
||||
|
@@ -69,12 +69,12 @@ else()
|
||||
set (3RDPARTY_TBB_INCLUDE_DIR "" CACHE PATH "the path to tbb.h" FORCE)
|
||||
endif()
|
||||
|
||||
# common steps for tbb and tbbmalloc
|
||||
# common steps for tbb12 and tbbmalloc
|
||||
macro (TBB_PRODUCT_SEARCH PRODUCT_LIBRARY_NAME)
|
||||
|
||||
string (TOUPPER ${PRODUCT_LIBRARY_NAME} upper_PRODUCT_LIBRARY_NAME)
|
||||
|
||||
# define required tbb/tbbmalloc variables
|
||||
# define required tbb12/tbbmalloc variables
|
||||
if (NOT DEFINED 3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY OR NOT 3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY_DIR OR NOT EXISTS "${3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY_DIR}")
|
||||
set (3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY "" CACHE FILEPATH "${upper_PRODUCT_LIBRARY_NAME} library" FORCE)
|
||||
endif()
|
||||
@@ -126,7 +126,7 @@ macro (TBB_PRODUCT_SEARCH PRODUCT_LIBRARY_NAME)
|
||||
set (${upper_PRODUCT_LIBRARY_NAME}_ARCH_NAME intel64)
|
||||
endif()
|
||||
|
||||
# tbb/tbbmalloc library
|
||||
# tbb12/tbbmalloc library
|
||||
if (NOT 3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY OR NOT EXISTS "${3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY}")
|
||||
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .lib .so .dylib .a)
|
||||
@@ -178,7 +178,7 @@ macro (TBB_PRODUCT_SEARCH PRODUCT_LIBRARY_NAME)
|
||||
set (3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_LIBRARY "" CACHE FILEPATH "The path to ${upper_PRODUCT_LIBRARY_NAME} library" FORCE)
|
||||
endif()
|
||||
|
||||
# tbb/tbbmalloc shared library
|
||||
# tbb12/tbbmalloc shared library
|
||||
if (WIN32)
|
||||
if (NOT 3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_DLL OR NOT EXISTS "${3RDPARTY_${upper_PRODUCT_LIBRARY_NAME}_DLL}")
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .dll)
|
||||
@@ -230,7 +230,7 @@ macro (TBB_PRODUCT_SEARCH PRODUCT_LIBRARY_NAME)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# install tbb/tbbmalloc
|
||||
# install tbb12/tbbmalloc
|
||||
if (INSTALL_TBB)
|
||||
OCCT_MAKE_OS_WITH_BITNESS()
|
||||
OCCT_MAKE_COMPILER_SHORT_NAME()
|
||||
@@ -286,9 +286,9 @@ endmacro()
|
||||
else()
|
||||
# the library directory for using by the executable
|
||||
if (WIN32)
|
||||
set (USED_3RDPARTY_TBB_DIR ${3RDPARTY_TBB_DLL_DIR})
|
||||
set (USED_3RDPARTY_TBB_DIR ${3RDPARTY_TBB12_DLL_DIR})
|
||||
else()
|
||||
set (USED_3RDPARTY_TBB_DIR ${3RDPARTY_TBB_LIBRARY_DIR})
|
||||
set (USED_3RDPARTY_TBB_DIR ${3RDPARTY_TBB12_LIBRARY_DIR})
|
||||
endif()
|
||||
endif()
|
||||
#endif()
|
||||
|
@@ -775,19 +775,19 @@ proc wokdep:SearchTBB {theErrInc theErrLib32 theErrLib64 theErrBin32 theErrBin64
|
||||
lappend ::CSF_OPT_LIB$anArchIter "$aPath/lib/$aSubDir/$aVcLib"
|
||||
}
|
||||
if { "$aTbbLibPath" == "" } {
|
||||
lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}tbb.${::SYS_LIB_SUFFIX}' not found (Intel TBB)"
|
||||
lappend anErrLib$anArchIter "Error: '${::SYS_LIB_PREFIX}tbb12.${::SYS_LIB_SUFFIX}' not found (Intel TBB)"
|
||||
if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
|
||||
}
|
||||
}
|
||||
if { "$::tcl_platform(platform)" == "windows" } {
|
||||
set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter"]
|
||||
set aTbbDllPath [wokdep:SearchBin "tbb12.dll" "$anArchIter"]
|
||||
if { "$aTbbDllPath" == "" } {
|
||||
set aPath [wokdep:Preferred [glob -nocomplain -directory "$::PRODUCTS_PATH" -type d *{tbb}*] $aVcLib "$anArchIter" ]
|
||||
set aTbbDllPath [wokdep:SearchBin "tbb.dll" "$anArchIter" "$aPath/bin/$aSubDir/$aVcLib"]
|
||||
set aTbbDllPath [wokdep:SearchBin "tbb12.dll" "$anArchIter" "$aPath/bin/$aSubDir/$aVcLib"]
|
||||
if { "$aTbbDllPath" != "" } {
|
||||
lappend ::CSF_OPT_BIN$anArchIter "$aPath/bin/$aSubDir/$aVcLib"
|
||||
} else {
|
||||
lappend anErrBin$anArchIter "Error: 'tbb.dll' not found (Intel TBB)"
|
||||
lappend anErrBin$anArchIter "Error: 'tbb12.dll' not found (Intel TBB)"
|
||||
if { "$::ARCH" == "$anArchIter"} { set isFound "false" }
|
||||
}
|
||||
}
|
||||
|
@@ -1437,7 +1437,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap theRelease} {
|
||||
set aLibsMap(CSF_FFmpeg) "avcodec avformat swscale avutil"
|
||||
}
|
||||
if { "$::HAVE_TBB" == "true" } {
|
||||
set aLibsMap(CSF_TBB) "tbb tbbmalloc"
|
||||
set aLibsMap(CSF_TBB) "tbb12 tbbmalloc"
|
||||
}
|
||||
if { "$::HAVE_VTK" == "true" } {
|
||||
if { "$theOS" == "wnt" } {
|
||||
|
@@ -23,7 +23,7 @@ CSF_TclLibs = -ltcl8.6
|
||||
CSF_TclTkLibs = -ltk8.6
|
||||
HAVE_FREEIMAGE { CSF_FreeImagePlus = -lfreeimage } else:win32 { CSF_FreeImagePlus = -lwindowscodecs -lole32 }
|
||||
HAVE_FFMPEG { CSF_FFmpeg = -lavcodec -lavformat -lswscale -lavutil }
|
||||
HAVE_TBB { CSF_TBB = -ltbb -ltbbmalloc }
|
||||
HAVE_TBB { CSF_TBB = -ltbb12 -ltbbmalloc }
|
||||
HAVE_ZLIB { CSF_ZLIB = -lzlib }
|
||||
HAVE_LIBLZMA { CSF_LIBLZMA = -lliblzma }
|
||||
HAVE_DRACO { CSF_Draco = -ldraco }
|
||||
|
@@ -11,7 +11,7 @@ if /I "%VCVER%" == "@COMPILER@" (
|
||||
set "FREEIMAGE_DIR=@3RDPARTY_FREEIMAGE_DLL_DIRS@"
|
||||
set "EGL_DIR=@3RDPARTY_EGL_DLL_DIRS@"
|
||||
set "GLES2_DIR=@3RDPARTY_GLES2_DLL_DIRS@"
|
||||
set "TBB_DIR=@3RDPARTY_TBB_DLL_DIR@"
|
||||
set "TBB_DIR=@3RDPARTY_TBB12_DLL_DIR@"
|
||||
set "VTK_DIR=@3RDPARTY_VTK_DLL_DIR@"
|
||||
set "FFMPEG_DIR=@3RDPARTY_FFMPEG_DLL_DIR@"
|
||||
set "OPENVR_DIR=@3RDPARTY_OPENVR_DLL_DIRS@"
|
||||
|
@@ -9,7 +9,7 @@ if [ "$1" == "@BIN_LETTER@" ]; then
|
||||
export TK_DIR="@3RDPARTY_TK_LIBRARY_DIR@"
|
||||
export FREETYPE_DIR="@3RDPARTY_FREETYPE_LIBRARY_DIR@"
|
||||
export FREEIMAGE_DIR="@3RDPARTY_FREEIMAGE_LIBRARY_DIRS@"
|
||||
export TBB_DIR="@3RDPARTY_TBB_LIBRARY_DIR@"
|
||||
export TBB_DIR="@3RDPARTY_TBB12_LIBRARY_DIR@"
|
||||
export VTK_DIR="@3RDPARTY_VTK_LIBRARY_DIR@"
|
||||
export FFMPEG_DIR="@3RDPARTY_FFMPEG_LIBRARY_DIR@"
|
||||
|
||||
|
17
dox/build/build_3rdparty/building_3rdparty.md
vendored
17
dox/build/build_3rdparty/building_3rdparty.md
vendored
@@ -128,8 +128,9 @@ You can download its sources from https://freetype.org/
|
||||
|
||||
@subsection dev_guides__building_3rdparty_win_3_1 TBB
|
||||
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/intel/tbb.
|
||||
Go to the **Download** page, find the release version you need (e.g. `tbb30_018oss`) and pick the archive for Windows platform.
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/oneapi-src/oneTBB/releases/tag/v2021.5.0.
|
||||
Go to the **Download** page, find the release version you need (e.g. `oneTBB 2021.5.0`) and pick the archive for Windows platform.
|
||||
To install, unpack the downloaded archive of TBB product (`oneapi-tbb-2021.5.0-win.zip`)
|
||||
|
||||
Unpack the downloaded archive of TBB product into the `3rdparty` folder.
|
||||
|
||||
@@ -304,9 +305,9 @@ Download the necessary archive from https://freetype.org/ and unpack it.
|
||||
|
||||
@subsection dev_guides__building_3rdparty_linux_3_1 TBB
|
||||
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/intel/tbb.
|
||||
Go to the **Download** page, find the release version you need and pick the archive for Linux platform.
|
||||
To install, unpack the downloaded archive of TBB product.
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/oneapi-src/oneTBB/releases/tag/v2021.5.0.
|
||||
Go to the **Download** page, find the release version you need (e.g. `oneTBB 2021.5.0`) and pick the archive for Linux platform.
|
||||
To install, unpack the downloaded archive of TBB product (`oneapi-tbb-2021.5.0-lin.tgz`).
|
||||
|
||||
@subsection dev_guides__building_3rdparty_linux_3_3 FreeImage
|
||||
|
||||
@@ -477,9 +478,9 @@ Download the necessary archive from https://freetype.org/ and unpack it.
|
||||
|
||||
@subsection dev_guides__building_3rdparty_osx_3_1 TBB
|
||||
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/intel/tbb.
|
||||
Go to the **Download** page, find the release version you need (e.g. `tbb30_018oss`) and pick the archive for Mac OS X platform.
|
||||
To install, unpack the downloaded archive of TBB product (`tbb30_018oss_osx.tgz`).
|
||||
This third-party product is installed with binaries from the archive that can be downloaded from https://github.com/oneapi-src/oneTBB/releases/tag/v2021.5.0.
|
||||
Go to the **Download** page, find the release version you need (e.g. `oneTBB 2021.5.0`) and pick the archive for Mac OS X platform.
|
||||
To install, unpack the downloaded archive of TBB product (`oneapi-tbb-2021.5.0-mac.tgz`).
|
||||
|
||||
@subsection dev_guides__building_3rdparty_osx_3_3 FreeImage
|
||||
|
||||
|
@@ -17,7 +17,7 @@ On Linux and macOS we recommend to use libraries maintained by distributive deve
|
||||
@section build_occt_win_cmake Building with CMake tool
|
||||
|
||||
This chapter describes the [CMake](https://cmake.org/download/)-based build process, which is now suggested as a standard way to produce the binaries of Open CASCADE Technology from sources.
|
||||
OCCT requires CMake version 2.8.12 or later.
|
||||
OCCT requires CMake version 3.1 or later.
|
||||
|
||||
CMake is a tool that generates the actual project files for the selected target build system (e.g. Unix makefiles) or IDE (e.g. Visual Studio 2010).
|
||||
Here we describe the build procedure on the example of Windows platform with Visual Studio 2010.
|
||||
@@ -113,6 +113,7 @@ The following table gives the full list of environment variables used at the con
|
||||
| BUILD_PATCH | Path | Points to the directory recognized as a "patch" for OCCT. If specified, the files from this directory take precedence over the corresponding native OCCT sources. This way you are able to introduce patches to Open CASCADE Technology not affecting the original source distribution |
|
||||
| BUILD_WITH_DEBUG | Boolean | Enables extended messages of many OCCT algorithms, usually printed to cout. These include messages on internal errors and special cases encountered, timing, etc. |
|
||||
| BUILD_ENABLE_FPE_SIGNAL_HANDLER | Boolean | Enable/Disable the floating point exceptions (FPE) during DRAW execution only. Corresponding environment variable (CSF_FPE) can be changed manually in custom.bat/sh scripts without regeneration by CMake. |
|
||||
| BUILD_CPP_STANDARD | String | Employ corresponding c++ standard (C++11, C++14, ..C++23) for building OCCT |
|
||||
| CMAKE_CONFIGURATION_TYPES | String | Semicolon-separated CMake configurations |
|
||||
| INSTALL_DIR | Path | Points to the installation directory. *INSTALL_DIR* is a synonym of *CMAKE_INSTALL_PREFIX*. The user can specify both *INSTALL_DIR* or *CMAKE_INSTALL_PREFIX* |
|
||||
| INSTALL_DIR_BIN | Path | Relative path to the binaries installation directory (absolute path is ${INSTALL_DIR}/${INSTALL_DIR_BIN}) |
|
||||
|
@@ -359,8 +359,8 @@ https://dev.opencascade.org/resources/download/3rd-party-components
|
||||
|
||||
| Component | Where to find | Used for | Purpose |
|
||||
| --------- | ------------- | -------- | -------------------- |
|
||||
| CMake 2.8+ | https://cmake.org/ | Configuration | Build from sources |
|
||||
| Intel TBB 4.x or later | https://oneapi-src.github.io/oneTBB/ | All | Parallelization of algorithms (alternative to built-in thread pool) |
|
||||
| CMake 3.1+ | https://cmake.org/ | Configuration | Build from sources |
|
||||
| Intel oneTBB 2021.5.0 | https://github.com/oneapi-src/oneTBB/releases/tag/v2021.5.0 | All | Parallelization of algorithms (alternative to built-in thread pool) |
|
||||
| OpenGL 3.3+, OpenGL ES 2.0+ | System | Visualization | Required for using 3D Viewer |
|
||||
| OpenVR 1.10+ | https://github.com/ValveSoftware/openvr | Visualization | VR (Virtual Reality) support in 3D Viewer |
|
||||
| FreeType 2.4+ | https://www.freetype.org/download.html | Visualization | Text rendering in 3D Viewer |
|
||||
@@ -572,7 +572,7 @@ FreeType 2 is released under two open-source licenses: BSD-like FreeType License
|
||||
It is a library that helps you to take advantage of multi-core processor performance without having to be a threading expert.
|
||||
Threading Building Blocks is not just a threads-replacement library. It represents a higher-level, task-based parallelism that
|
||||
abstracts platform details and threading mechanisms for scalability and performance.
|
||||
TBB version 2017 is available under Apache 2.0 license, while older versions
|
||||
oneTBB 2021.5.0 is available under Apache 2.0 license, while older versions
|
||||
until 4.4 are available under GPLv2 license with the runtime exception (https://www.threadingbuildingblocks.org).
|
||||
|
||||
**OpenGL** is an industry standard API for 3D graphics used by OCCT for
|
||||
|
@@ -91,6 +91,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy.dll</OutputFile>
|
||||
@@ -121,6 +122,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy.dll</OutputFile>
|
||||
@@ -145,6 +147,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy.dll</OutputFile>
|
||||
@@ -172,6 +175,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy.dll</OutputFile>
|
||||
|
@@ -92,6 +92,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy_D3D.dll</OutputFile>
|
||||
@@ -123,6 +124,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy_D3D.dll</OutputFile>
|
||||
@@ -147,6 +149,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy_D3D.dll</OutputFile>
|
||||
@@ -174,6 +177,7 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)OCCTProxy_D3D.dll</OutputFile>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>IE_WPF_D3D</RootNamespace>
|
||||
<AssemblyName>IE_WPF_D3D</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>IE_WPF_WinForms</RootNamespace>
|
||||
<AssemblyName>IE_WPF_WinForms</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
|
@@ -35,4 +35,4 @@
|
||||
</providers>
|
||||
</roleManager>
|
||||
</system.web>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
|
||||
|
@@ -4,7 +4,6 @@ project(glfw-occt-demo)
|
||||
|
||||
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/adm/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(APP_VERSION_MAJOR 1)
|
||||
set(APP_VERSION_MINOR 0)
|
||||
set(APP_TARGET glfwocct)
|
||||
|
@@ -39,9 +39,9 @@ elseif (DEFINED CMAKE_COMPILER_IS_GNUCC)
|
||||
set (MY_COMPILER gcc)
|
||||
elseif (DEFINED CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (MY_COMPILER gcc)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Cc][Ll][Aa][Nn][Gg]")
|
||||
set (MY_COMPILER clang)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "[Ii][Nn][Tt][Ee][Ll]")
|
||||
set (MY_COMPILER icc)
|
||||
else()
|
||||
set (MY_COMPILER ${CMAKE_GENERATOR})
|
||||
|
@@ -37,7 +37,7 @@ list(APPEND aLibDeps lib_FreeType)
|
||||
# system libraries
|
||||
list(APPEND aLibDeps EGL GLESv2 log android)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -frtti -fexceptions -fpermissive")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -frtti -fexceptions -fpermissive")
|
||||
|
||||
add_library(TKJniSample SHARED ${SOURCE_FILES})
|
||||
target_link_libraries(TKJniSample ${aLibDeps})
|
||||
|
@@ -1,4 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project (Geometry)
|
||||
|
||||
|
@@ -1,4 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project (Modeling)
|
||||
|
||||
|
@@ -1,4 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project (ImportExport)
|
||||
|
||||
|
@@ -1,4 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project (HLR)
|
||||
|
||||
|
@@ -1,4 +1,10 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
# Caution! Be careful, when increase minimal cmake version:
|
||||
# using of newer version may leads (by default) to applying
|
||||
# of some new policies. It may break compilation.
|
||||
# For canceling of applying new policies use:
|
||||
# cmake_policy(PUSH) before `cmake_minimum_required`
|
||||
# and cmake_policy(POP) after.
|
||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project (mfcsample)
|
||||
|
||||
|
@@ -51,7 +51,7 @@ unix {
|
||||
DEFINES += OCC_CONVERT_SIGNALS QT_NO_STL
|
||||
!macx | equals(MACOSX_USE_GLX, true): LIBS += -L$$QMAKE_LIBDIR_X11 $$QMAKE_LIBS_X11 -L$$QMAKE_LIBDIR_OPENGL $$QMAKE_LIBS_OPENGL $$QMAKE_LIBS_THREAD
|
||||
LIBS += -lfreeimageplus
|
||||
LIBS += -ltbb -ltbbmalloc
|
||||
LIBS += -ltbb12 -ltbbmalloc
|
||||
QMAKE_CXXFLAGS += -std=gnu++11
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
project(occt-webgl-sample)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(APP_VERSION_MAJOR 1)
|
||||
set(APP_VERSION_MINOR 0)
|
||||
set(APP_TARGET occt-webgl-sample)
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <Prs3d_Presentation.hxx>
|
||||
#include <Quantity_Color.hxx>
|
||||
#include <Select3D_SensitiveCircle.hxx>
|
||||
#include <Select3D_SensitivePoly.hxx>
|
||||
#include <SelectMgr_EntityOwner.hxx>
|
||||
#include <SelectMgr_Selection.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
@@ -41,9 +42,9 @@ IMPLEMENT_STANDARD_RTTIEXT(AIS_Circle,AIS_InteractiveObject)
|
||||
AIS_Circle::AIS_Circle(const Handle(Geom_Circle)& aComponent):
|
||||
AIS_InteractiveObject(PrsMgr_TOP_AllView),
|
||||
myComponent(aComponent),
|
||||
myUStart(0.),
|
||||
myUEnd(2*M_PI),
|
||||
myCircleIsArc(Standard_False),
|
||||
myUStart (0.0),
|
||||
myUEnd (2.0 * M_PI),
|
||||
myCircleIsArc (Standard_False),
|
||||
myIsFilledCircleSens (Standard_False)
|
||||
{
|
||||
}
|
||||
@@ -60,7 +61,7 @@ AIS_Circle::AIS_Circle(const Handle(Geom_Circle)& theComponent,
|
||||
myComponent (theComponent),
|
||||
myUStart (theUStart),
|
||||
myUEnd (theUEnd),
|
||||
myCircleIsArc (Standard_True),
|
||||
myCircleIsArc (Abs (Abs (theUEnd - theUStart) - 2.0 * M_PI) > gp::Resolution()),
|
||||
myIsFilledCircleSens (theIsFilledCircleSens)
|
||||
{
|
||||
}
|
||||
@@ -207,14 +208,14 @@ void AIS_Circle::UnsetWidth()
|
||||
//function : ComputeCircle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_Circle::ComputeCircle( const Handle(Prs3d_Presentation)& aPresentation)
|
||||
void AIS_Circle::ComputeCircle (const Handle(Prs3d_Presentation)& thePresentation)
|
||||
{
|
||||
|
||||
GeomAdaptor_Curve curv(myComponent);
|
||||
Standard_Real prevdev = myDrawer->DeviationCoefficient();
|
||||
myDrawer->SetDeviationCoefficient(1.e-5);
|
||||
StdPrs_DeflectionCurve::Add(aPresentation,curv,myDrawer);
|
||||
myDrawer->SetDeviationCoefficient(prevdev);
|
||||
myDrawer->SetDeviationCoefficient (1.e-5);
|
||||
StdPrs_DeflectionCurve::Add (thePresentation, curv, myDrawer);
|
||||
myDrawer->SetDeviationCoefficient (prevdev);
|
||||
|
||||
}
|
||||
|
||||
@@ -223,13 +224,13 @@ void AIS_Circle::ComputeCircle( const Handle(Prs3d_Presentation)& aPresentation)
|
||||
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS_Circle::ComputeArc( const Handle(Prs3d_Presentation)& aPresentation)
|
||||
void AIS_Circle::ComputeArc (const Handle(Prs3d_Presentation)& thePresentation)
|
||||
{
|
||||
GeomAdaptor_Curve curv(myComponent,myUStart,myUEnd);
|
||||
GeomAdaptor_Curve curv(myComponent, myUStart, myUEnd);
|
||||
Standard_Real prevdev = myDrawer->DeviationCoefficient();
|
||||
myDrawer->SetDeviationCoefficient(1.e-5);
|
||||
StdPrs_DeflectionCurve::Add(aPresentation,curv,myDrawer);
|
||||
myDrawer->SetDeviationCoefficient(prevdev);
|
||||
myDrawer->SetDeviationCoefficient (1.e-5);
|
||||
StdPrs_DeflectionCurve::Add (thePresentation, curv, myDrawer);
|
||||
myDrawer->SetDeviationCoefficient (prevdev);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -237,27 +238,25 @@ void AIS_Circle::ComputeArc( const Handle(Prs3d_Presentation)& aPresentation)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AIS_Circle::ComputeCircleSelection(const Handle(SelectMgr_Selection)& aSelection)
|
||||
void AIS_Circle::ComputeCircleSelection (const Handle(SelectMgr_Selection)& theSelection)
|
||||
{
|
||||
Handle(SelectMgr_EntityOwner) eown = new SelectMgr_EntityOwner(this);
|
||||
Handle(Select3D_SensitiveCircle) seg = new Select3D_SensitiveCircle (eown,
|
||||
myComponent->Circ(),
|
||||
myIsFilledCircleSens);
|
||||
aSelection->Add(seg);
|
||||
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
|
||||
Handle(Select3D_SensitiveCircle) aCirc = new Select3D_SensitiveCircle (anOwner,
|
||||
myComponent->Circ(),
|
||||
myIsFilledCircleSens);
|
||||
theSelection->Add (aCirc);
|
||||
}
|
||||
//=======================================================================
|
||||
//function : ComputeArcSelection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void AIS_Circle::ComputeArcSelection(const Handle(SelectMgr_Selection)& aSelection)
|
||||
void AIS_Circle::ComputeArcSelection (const Handle(SelectMgr_Selection)& theSelection)
|
||||
{
|
||||
|
||||
|
||||
Handle(SelectMgr_EntityOwner) eown = new SelectMgr_EntityOwner(this);
|
||||
Handle(Select3D_SensitiveCircle) seg = new Select3D_SensitiveCircle (eown,
|
||||
myComponent->Circ(),
|
||||
myUStart, myUEnd,
|
||||
myIsFilledCircleSens);
|
||||
aSelection->Add(seg);
|
||||
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
|
||||
Handle(Select3D_SensitivePoly) aSeg = new Select3D_SensitivePoly (anOwner,
|
||||
myComponent->Circ(),
|
||||
myUStart, myUEnd,
|
||||
myIsFilledCircleSens);
|
||||
theSelection->Add (aSeg);
|
||||
}
|
||||
|
@@ -84,9 +84,8 @@ namespace
|
||||
public:
|
||||
//! Main constructor.
|
||||
ManipSensCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Integer theNbPnts)
|
||||
: Select3D_SensitiveCircle (theOwnerId, theCircle, Standard_False, theNbPnts),
|
||||
const gp_Circ& theCircle)
|
||||
: Select3D_SensitiveCircle (theOwnerId, theCircle, Standard_False),
|
||||
ManipSensRotation (theCircle.Position().Direction()) {}
|
||||
|
||||
//! Checks whether the circle overlaps current selecting volume
|
||||
@@ -1168,7 +1167,7 @@ void AIS_Manipulator::ComputeSelection (const Handle(SelectMgr_Selection)& theSe
|
||||
}
|
||||
// define sensitivity by circle
|
||||
const gp_Circ aGeomCircle (gp_Ax2 (gp::Origin(), anAxis.ReferenceAxis().Direction()), anAxis.RotatorDiskRadius());
|
||||
Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle (anOwner, aGeomCircle, anAxis.FacettesNumber());
|
||||
Handle(Select3D_SensitiveCircle) aCircle = new ManipSensCircle (anOwner, aGeomCircle);
|
||||
aCircle->SetSensitivityFactor (15);
|
||||
theSelection->Add (aCircle);
|
||||
// enlarge sensitivity by triangulation
|
||||
|
@@ -124,10 +124,12 @@ void BRepMesh_DefaultRangeSplitter::computeTolerance(
|
||||
const Standard_Real aDiffU = myRangeU.second - myRangeU.first;
|
||||
const Standard_Real aDiffV = myRangeV.second - myRangeV.first;
|
||||
|
||||
// Slightly increase exact resolution so to cover links with approximate
|
||||
// length equal to resolution itself on sub-resolution differences.
|
||||
const Standard_Real aTolerance = BRep_Tool::Tolerance (myDFace->GetFace());
|
||||
const Adaptor3d_Surface& aSurface = GetSurface()->Surface();
|
||||
const Standard_Real aResU = aSurface.UResolution (aTolerance);
|
||||
const Standard_Real aResV = aSurface.VResolution (aTolerance);
|
||||
const Standard_Real aResU = aSurface.UResolution (aTolerance) * 1.1;
|
||||
const Standard_Real aResV = aSurface.VResolution (aTolerance) * 1.1;
|
||||
|
||||
const Standard_Real aDeflectionUV = 1.e-05;
|
||||
myTolerance.first = Max(Min(aDeflectionUV, aResU), 1e-7 * aDiffU);
|
||||
|
@@ -371,7 +371,7 @@ bool D3DHost_View::d3dSwap()
|
||||
}
|
||||
|
||||
const HRESULT isOK = myD3dDevice->Present (NULL, NULL, NULL, NULL);
|
||||
if (isOK != D3D_OK)
|
||||
if (isOK != D3D_OK && isOK != S_PRESENT_OCCLUDED)
|
||||
{
|
||||
myWorkspace->GetGlContext()->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString("Direct3D9, Present device failed, ") + d3dFormatError (isOK));
|
||||
|
@@ -60,6 +60,7 @@ Font_TextFormatter::Font_TextFormatter()
|
||||
myAlignY (Graphic3d_VTA_TOP),
|
||||
myTabSize (8),
|
||||
myWrappingWidth (0.0f),
|
||||
myIsWordWrapping (true),
|
||||
myLastSymbolWidth (0.0f),
|
||||
myMaxSymbolWidth (0.0f),
|
||||
//
|
||||
@@ -249,6 +250,7 @@ void Font_TextFormatter::Format()
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Utf32Char aCharPrev = 0;
|
||||
for (Font_TextFormatter::Iterator aFormatterIt(*this);
|
||||
aFormatterIt.More(); aFormatterIt.Next())
|
||||
{
|
||||
@@ -269,12 +271,30 @@ void Font_TextFormatter::Format()
|
||||
Font_Rect aBndBox;
|
||||
GlyphBoundingBox (aRectIter, aBndBox);
|
||||
const Standard_ShortReal aNextXPos = aBndBox.Right - BottomLeft (aFirstCornerId).x();
|
||||
if (aNextXPos > aMaxLineWidth) // wrap the line and do processing of the symbol
|
||||
Standard_Boolean isCurWordFits = true;
|
||||
if(myIsWordWrapping && IsSeparatorSymbol(aCharPrev))
|
||||
{
|
||||
for (Font_TextFormatter::Iterator aWordIt = aFormatterIt; aWordIt.More(); aWordIt.Next())
|
||||
{
|
||||
if (IsSeparatorSymbol(aWordIt.Symbol()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
float aWordWidthPx = myCorners[aWordIt.SymbolPosition()].x() - myCorners[aRectIter].x();
|
||||
if (aNextXPos + aWordWidthPx > aMaxLineWidth)
|
||||
{
|
||||
isCurWordFits = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNextXPos > aMaxLineWidth || !isCurWordFits) // wrap the line and do processing of the symbol
|
||||
{
|
||||
const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line
|
||||
newLine (aLastRect, aMaxLineWidth);
|
||||
}
|
||||
}
|
||||
aCharPrev = aCharThis;
|
||||
}
|
||||
|
||||
myBndWidth = aMaxLineWidth;
|
||||
|
@@ -220,6 +220,12 @@ public:
|
||||
//! Returns text maximum width, zero means that the text is not bounded by width
|
||||
Standard_ShortReal Wrapping() const { return myWrappingWidth; }
|
||||
|
||||
//! returns TRUE when trying not to break words when wrapping text
|
||||
Standard_Boolean WordWrapping () const { return myIsWordWrapping; }
|
||||
|
||||
//! returns TRUE when trying not to break words when wrapping text
|
||||
void SetWordWrapping (const Standard_Boolean theIsWordWrapping) { myIsWordWrapping = theIsWordWrapping; }
|
||||
|
||||
//! @return width of formatted text.
|
||||
inline Standard_ShortReal ResultWidth() const
|
||||
{
|
||||
@@ -274,6 +280,14 @@ public:
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//! Returns true if the symbol separates words when wrapping is enabled
|
||||
static Standard_Boolean IsSeparatorSymbol (const Standard_Utf32Char& theSymbol)
|
||||
{
|
||||
return theSymbol == '\x0A' // new line
|
||||
|| theSymbol == ' ' // space
|
||||
|| theSymbol == '\x09'; // tab
|
||||
}
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient)
|
||||
|
||||
protected: //! @name class auxiliary methods
|
||||
@@ -288,6 +302,7 @@ protected: //! @name configuration
|
||||
Graphic3d_VerticalTextAlignment myAlignY; //!< vertical alignment style
|
||||
Standard_Integer myTabSize; //!< horizontal tabulation width (number of space symbols)
|
||||
Standard_ShortReal myWrappingWidth; //!< text is wrapped by the width if defined (more 0)
|
||||
Standard_Boolean myIsWordWrapping; //!< if TRUE try not to break words when wrapping text (true by default)
|
||||
Standard_ShortReal myLastSymbolWidth; //!< width of the last symbol
|
||||
Standard_ShortReal myMaxSymbolWidth; //!< maximum symbol width of the formatter string
|
||||
|
||||
|
@@ -25,3 +25,9 @@ GeomConvert_CurveToAnaCurve.hxx
|
||||
GeomConvert_SurfToAnaSurf.cxx
|
||||
GeomConvert_SurfToAnaSurf.hxx
|
||||
GeomConvert_ConvType.hxx
|
||||
GeomConvert_FuncSphereLSDist.cxx
|
||||
GeomConvert_FuncSphereLSDist.hxx
|
||||
GeomConvert_FuncCylinderLSDist.cxx
|
||||
GeomConvert_FuncCylinderLSDist.hxx
|
||||
GeomConvert_FuncConeLSDist.cxx
|
||||
GeomConvert_FuncConeLSDist.hxx
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <ShapeAnalysis_FuncConeLSDist.hxx>
|
||||
#include <GeomConvert_FuncConeLSDist.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
@@ -21,10 +21,10 @@
|
||||
#include <ElSLib.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeAnalysis_FuncConeLSDist
|
||||
//function : GeomConvert_FuncConeLSDist
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
ShapeAnalysis_FuncConeLSDist::ShapeAnalysis_FuncConeLSDist(
|
||||
GeomConvert_FuncConeLSDist::GeomConvert_FuncConeLSDist(
|
||||
const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const gp_Dir& theDir):
|
||||
myPoints(thePoints), myDir(theDir)
|
||||
@@ -35,7 +35,7 @@ ShapeAnalysis_FuncConeLSDist::ShapeAnalysis_FuncConeLSDist(
|
||||
//function : NbVariables
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer ShapeAnalysis_FuncConeLSDist::NbVariables () const
|
||||
Standard_Integer GeomConvert_FuncConeLSDist::NbVariables () const
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ Standard_Integer ShapeAnalysis_FuncConeLSDist::NbVariables () const
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncConeLSDist::Value(const math_Vector& X, Standard_Real& F)
|
||||
Standard_Boolean GeomConvert_FuncConeLSDist::Value(const math_Vector& X, Standard_Real& F)
|
||||
{
|
||||
gp_Pnt aLoc(X(1), X(2), X(3));
|
||||
Standard_Real aSemiAngle = X(4), anR = X(5);
|
@@ -12,8 +12,8 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _ShapeAnalysis_FuncConeLSDist_HeaderFile
|
||||
#define _ShapeAnalysis_FuncConeLSDist_HeaderFile
|
||||
#ifndef _GeomConvert_FuncConeLSDist_HeaderFile
|
||||
#define _GeomConvert_FuncConeLSDist_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
@@ -28,16 +28,16 @@
|
||||
//! by least square method.
|
||||
//!
|
||||
//!
|
||||
class ShapeAnalysis_FuncConeLSDist : public math_MultipleVarFunction
|
||||
class GeomConvert_FuncConeLSDist : public math_MultipleVarFunction
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Constructor.
|
||||
Standard_EXPORT ShapeAnalysis_FuncConeLSDist() {};
|
||||
Standard_EXPORT GeomConvert_FuncConeLSDist() {};
|
||||
|
||||
Standard_EXPORT ShapeAnalysis_FuncConeLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
Standard_EXPORT GeomConvert_FuncConeLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const gp_Dir& theDir);
|
||||
|
||||
void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints)
|
||||
@@ -63,4 +63,4 @@ private:
|
||||
gp_Dir myDir;
|
||||
|
||||
};
|
||||
#endif // _ShapeAnalysis_FuncConeLSDist_HeaderFile
|
||||
#endif // _GeomConvert_FuncConeLSDist_HeaderFile
|
@@ -13,16 +13,16 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <ShapeAnalysis_FuncCylinderLSDist.hxx>
|
||||
#include <GeomConvert_FuncCylinderLSDist.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeAnalysis_FuncCylinderLSDist
|
||||
//function : GeomConvert_FuncCylinderLSDist
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
ShapeAnalysis_FuncCylinderLSDist::ShapeAnalysis_FuncCylinderLSDist(
|
||||
GeomConvert_FuncCylinderLSDist::GeomConvert_FuncCylinderLSDist(
|
||||
const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const gp_Dir& theDir):
|
||||
myPoints(thePoints), myDir(theDir)
|
||||
@@ -33,7 +33,7 @@ ShapeAnalysis_FuncCylinderLSDist::ShapeAnalysis_FuncCylinderLSDist(
|
||||
//function : NbVariables
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer ShapeAnalysis_FuncCylinderLSDist::NbVariables () const
|
||||
Standard_Integer GeomConvert_FuncCylinderLSDist::NbVariables () const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ Standard_Integer ShapeAnalysis_FuncCylinderLSDist::NbVariables () const
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Value(const math_Vector& X,Standard_Real& F)
|
||||
Standard_Boolean GeomConvert_FuncCylinderLSDist::Value(const math_Vector& X,Standard_Real& F)
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
Standard_Real anR2 = X(4)*X(4);
|
||||
@@ -64,7 +64,7 @@ Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Value(const math_Vector& X,St
|
||||
//function : Gradient
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Gradient(const math_Vector& X,math_Vector& G)
|
||||
Standard_Boolean GeomConvert_FuncCylinderLSDist::Gradient(const math_Vector& X,math_Vector& G)
|
||||
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
@@ -102,7 +102,7 @@ Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Gradient(const math_Vector& X
|
||||
//function : Values
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G)
|
||||
Standard_Boolean GeomConvert_FuncCylinderLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G)
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
Standard_Real anR = X(4), anR2 = anR * anR;
|
@@ -12,8 +12,8 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _ShapeAnalysis_FuncCylinderLSDist_HeaderFile
|
||||
#define _ShapeAnalysis_FuncCylinderLSDist_HeaderFile
|
||||
#ifndef _GeomConvert_FuncCylinderLSDist_HeaderFile
|
||||
#define _GeomConvert_FuncCylinderLSDist_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
@@ -57,16 +57,16 @@
|
||||
//! dF/dz0 : G3(...) = 2*Sum{[...]*Dz0}
|
||||
//! dF/dR : G4(...) = -4*R*Sum[...]
|
||||
//! [...] = [|(P(i) - Loc)^dir|^2 - R^2]
|
||||
class ShapeAnalysis_FuncCylinderLSDist : public math_MultipleVarFunctionWithGradient
|
||||
class GeomConvert_FuncCylinderLSDist : public math_MultipleVarFunctionWithGradient
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Constructor.
|
||||
Standard_EXPORT ShapeAnalysis_FuncCylinderLSDist() {};
|
||||
Standard_EXPORT GeomConvert_FuncCylinderLSDist() {};
|
||||
|
||||
Standard_EXPORT ShapeAnalysis_FuncCylinderLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
Standard_EXPORT GeomConvert_FuncCylinderLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const gp_Dir& theDir);
|
||||
|
||||
void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints)
|
||||
@@ -97,4 +97,4 @@ private:
|
||||
gp_Dir myDir;
|
||||
|
||||
};
|
||||
#endif // _ShapeAnalysis_FuncCylinderLSDist_HeaderFile
|
||||
#endif // _GeomConvert_FuncCylinderLSDist_HeaderFile
|
@@ -15,16 +15,16 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <ShapeAnalysis_FuncSphereLSDist.hxx>
|
||||
#include <GeomConvert_FuncSphereLSDist.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeAnalysis_FuncSphereLSDist
|
||||
//function : GeomConvert_FuncSphereLSDist
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
ShapeAnalysis_FuncSphereLSDist::ShapeAnalysis_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints):
|
||||
GeomConvert_FuncSphereLSDist::GeomConvert_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints):
|
||||
myPoints(thePoints)
|
||||
{
|
||||
}
|
||||
@@ -33,7 +33,7 @@ ShapeAnalysis_FuncSphereLSDist::ShapeAnalysis_FuncSphereLSDist(const Handle(TCol
|
||||
//function : NbVariables
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer ShapeAnalysis_FuncSphereLSDist::NbVariables () const
|
||||
Standard_Integer GeomConvert_FuncSphereLSDist::NbVariables () const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ Standard_Integer ShapeAnalysis_FuncSphereLSDist::NbVariables () const
|
||||
//function : Value
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Value(const math_Vector& X,Standard_Real& F)
|
||||
Standard_Boolean GeomConvert_FuncSphereLSDist::Value(const math_Vector& X,Standard_Real& F)
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
Standard_Real anR2 = X(4)*X(4);
|
||||
@@ -62,7 +62,7 @@ Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Value(const math_Vector& X,Stan
|
||||
//function : Gradient
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Gradient(const math_Vector& X,math_Vector& G)
|
||||
Standard_Boolean GeomConvert_FuncSphereLSDist::Gradient(const math_Vector& X,math_Vector& G)
|
||||
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
@@ -89,7 +89,7 @@ Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Gradient(const math_Vector& X,m
|
||||
//function : Values
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G)
|
||||
Standard_Boolean GeomConvert_FuncSphereLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G)
|
||||
{
|
||||
gp_XYZ aLoc(X(1), X(2), X(3));
|
||||
Standard_Real anR = X(4), anR2 = anR * anR;
|
@@ -13,8 +13,8 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _ShapeAnalysis_FuncSphereLSDist_HeaderFile
|
||||
#define _ShapeAnalysis_FuncSphereLSDist_HeaderFile
|
||||
#ifndef _GeomConvert_FuncSphereLSDist_HeaderFile
|
||||
#define _GeomConvert_FuncSphereLSDist_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
@@ -41,16 +41,16 @@
|
||||
//! dF/dR : G4(x0, y0, z0, R) = -4*R*Sum[...]
|
||||
//! [...] = [(x(i) - x0)^2 + (y(i) - y0)^2 + (z(i) - z0)^2 - R^2]
|
||||
//!
|
||||
class ShapeAnalysis_FuncSphereLSDist : public math_MultipleVarFunctionWithGradient
|
||||
class GeomConvert_FuncSphereLSDist : public math_MultipleVarFunctionWithGradient
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Constructor.
|
||||
Standard_EXPORT ShapeAnalysis_FuncSphereLSDist() {};
|
||||
Standard_EXPORT GeomConvert_FuncSphereLSDist() {};
|
||||
|
||||
Standard_EXPORT ShapeAnalysis_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints);
|
||||
Standard_EXPORT GeomConvert_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints);
|
||||
|
||||
void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints)
|
||||
{
|
||||
@@ -74,4 +74,4 @@ private:
|
||||
Handle(TColgp_HArray1OfXYZ) myPoints;
|
||||
|
||||
};
|
||||
#endif // _ShapeAnalysis_FuncSphereLSDist_HeaderFile
|
||||
#endif // _GeomConvert_FuncSphereLSDist_HeaderFile
|
@@ -47,10 +47,20 @@
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <Extrema_ExtElC.hxx>
|
||||
#include <GeomLProp_SLProps.hxx>
|
||||
#include <TColgp_HArray1OfXYZ.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
#include <math_PSO.hxx>
|
||||
#include <math_Powell.hxx>
|
||||
#include <GeomConvert_FuncCylinderLSDist.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckVTrimForRevSurf
|
||||
//purpose :
|
||||
//static method for checking surface of revolution
|
||||
//To avoid two-parts cone-like surface
|
||||
static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf,
|
||||
//=======================================================================
|
||||
void GeomConvert_SurfToAnaSurf::CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf,
|
||||
Standard_Real& V1, Standard_Real& V2)
|
||||
{
|
||||
const Handle(Geom_Curve)& aBC = aRevSurf->BasisCurve();
|
||||
@@ -96,10 +106,369 @@ static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSur
|
||||
}
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : TryCylinderCone
|
||||
//purpose :
|
||||
//static method to try create cylindrical or conical surface
|
||||
//=======================================================================
|
||||
Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryCylinerCone(const Handle(Geom_Surface)& theSurf, const Standard_Boolean theVCase,
|
||||
const Handle(Geom_Curve)& theUmidiso, const Handle(Geom_Curve)& theVmidiso,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Standard_Real theToler)
|
||||
{
|
||||
Handle(Geom_Surface) aNewSurf;
|
||||
Standard_Real param1, param2, cf1, cf2, cl1, cl2, aGap1, aGap2;
|
||||
Handle(Geom_Curve) firstiso, lastiso;
|
||||
Handle(Geom_Circle) firstisocirc, lastisocirc, midisocirc;
|
||||
gp_Dir isoline;
|
||||
if (theVCase) {
|
||||
param1 = theU1; param2 = theU2;
|
||||
firstiso = theSurf->VIso(theV1);
|
||||
lastiso = theSurf->VIso(theV2);
|
||||
midisocirc = Handle(Geom_Circle)::DownCast(theVmidiso);
|
||||
isoline = Handle(Geom_Line)::DownCast(theUmidiso)->Lin().Direction();
|
||||
}
|
||||
else {
|
||||
param1 = theV1; param2 = theV2;
|
||||
firstiso = theSurf->UIso(theU1);
|
||||
lastiso = theSurf->UIso(theU2);
|
||||
midisocirc = Handle(Geom_Circle)::DownCast(theUmidiso);
|
||||
isoline = Handle(Geom_Line)::DownCast(theVmidiso)->Lin().Direction();
|
||||
}
|
||||
firstisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(firstiso, theToler,
|
||||
param1, param2, cf1, cl1, aGap1));
|
||||
lastisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(lastiso, theToler,
|
||||
param1, param2, cf2, cl2, aGap2));
|
||||
if (!firstisocirc.IsNull() || !lastisocirc.IsNull()) {
|
||||
Standard_Real R1, R2, R3;
|
||||
gp_Pnt P1, P2, P3;
|
||||
if (!firstisocirc.IsNull()) {
|
||||
R1 = firstisocirc->Circ().Radius();
|
||||
P1 = firstisocirc->Circ().Location();
|
||||
}
|
||||
else {
|
||||
R1 = 0;
|
||||
P1 = firstiso->Value((firstiso->LastParameter() - firstiso->FirstParameter()) / 2);
|
||||
}
|
||||
R2 = midisocirc->Circ().Radius();
|
||||
P2 = midisocirc->Circ().Location();
|
||||
if (!lastisocirc.IsNull()) {
|
||||
R3 = lastisocirc->Circ().Radius();
|
||||
P3 = lastisocirc->Circ().Location();
|
||||
}
|
||||
else {
|
||||
R3 = 0;
|
||||
P3 = lastiso->Value((lastiso->LastParameter() - lastiso->FirstParameter()) / 2);
|
||||
}
|
||||
//cylinder
|
||||
if (((Abs(R2 - R1)) < theToler) && ((Abs(R3 - R1)) < theToler) &&
|
||||
((Abs(R3 - R2)) < theToler)) {
|
||||
gp_Ax3 Axes(P1, gp_Dir(gp_Vec(P1, P3)));
|
||||
aNewSurf = new Geom_CylindricalSurface(Axes, R1);
|
||||
}
|
||||
//cone
|
||||
else if ((((Abs(R1)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R3)))) ||
|
||||
(((Abs(R3)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R1))))) {
|
||||
Standard_Real radius;
|
||||
gp_Ax3 Axes;
|
||||
Standard_Real semiangle =
|
||||
gp_Vec(isoline).Angle(gp_Vec(P3, P1));
|
||||
if (semiangle > M_PI / 2) semiangle = M_PI - semiangle;
|
||||
if (R1 > R3) {
|
||||
radius = R3;
|
||||
Axes = gp_Ax3(P3, gp_Dir(gp_Vec(P3, P1)));
|
||||
}
|
||||
else {
|
||||
radius = R1;
|
||||
Axes = gp_Ax3(P1, gp_Dir(gp_Vec(P1, P3)));
|
||||
}
|
||||
aNewSurf = new Geom_ConicalSurface(Axes, semiangle, radius);
|
||||
}
|
||||
}
|
||||
return aNewSurf;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetCylByLS
|
||||
//purpose :
|
||||
//static method to create cylinrical surface using least square method
|
||||
//=======================================================================
|
||||
static void GetLSGap(const Handle(TColgp_HArray1OfXYZ)& thePoints, const gp_Ax3& thePos,
|
||||
const Standard_Real theR, Standard_Real& theGap)
|
||||
{
|
||||
theGap = 0.;
|
||||
Standard_Integer i;
|
||||
gp_XYZ aLoc = thePos.Location().XYZ();
|
||||
gp_Dir aDir = thePos.Direction();
|
||||
for (i = thePoints->Lower(); i <= thePoints->Upper(); ++i)
|
||||
{
|
||||
gp_Vec aD(thePoints->Value(i) - aLoc);
|
||||
aD.Cross(aDir);
|
||||
theGap = Max(theGap, Abs((aD.Magnitude() - theR)));
|
||||
}
|
||||
|
||||
}
|
||||
Standard_Boolean GeomConvert_SurfToAnaSurf::GetCylByLS(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const Standard_Real theTol,
|
||||
gp_Ax3& thePos, Standard_Real& theR,
|
||||
Standard_Real& theGap)
|
||||
{
|
||||
|
||||
GetLSGap(thePoints, thePos, theR, theGap);
|
||||
if (theGap <= Precision::Confusion())
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
Standard_Integer i;
|
||||
|
||||
Standard_Integer aNbVar = 4;
|
||||
|
||||
math_Vector aFBnd(1, aNbVar), aLBnd(1, aNbVar), aStartPoint(1, aNbVar);
|
||||
|
||||
Standard_Real aRelDev = 0.2; //Customer can set parameters of sample surface
|
||||
// with relative precision about aRelDev.
|
||||
// For example, if radius of sample surface is R,
|
||||
// it means, that "exact" vaue is in interav
|
||||
//[R - aRelDev*R, R + aRelDev*R]. This intrrval is set
|
||||
// for R as boundary values for dptimization algo.
|
||||
|
||||
aStartPoint(1) = thePos.Location().X();
|
||||
aStartPoint(2) = thePos.Location().Y();
|
||||
aStartPoint(3) = thePos.Location().Z();
|
||||
aStartPoint(4) = theR;
|
||||
Standard_Real aDR = aRelDev * theR;
|
||||
Standard_Real aDXYZ = aDR;
|
||||
for (i = 1; i <= 3; ++i)
|
||||
{
|
||||
aFBnd(i) = aStartPoint(i) - aDXYZ;
|
||||
aLBnd(i) = aStartPoint(i) + aDXYZ;
|
||||
}
|
||||
aFBnd(4) = aStartPoint(4) - aDR;
|
||||
aLBnd(4) = aStartPoint(4) + aDR;
|
||||
|
||||
//
|
||||
Standard_Real aTol = Precision::Confusion();
|
||||
math_MultipleVarFunction* aPFunc;
|
||||
GeomConvert_FuncCylinderLSDist aFuncCyl(thePoints, thePos.Direction());
|
||||
aPFunc = (math_MultipleVarFunction*)&aFuncCyl;
|
||||
//
|
||||
math_Vector aSteps(1, aNbVar);
|
||||
Standard_Integer aNbInt = 10;
|
||||
for (i = 1; i <= aNbVar; ++i)
|
||||
{
|
||||
aSteps(i) = (aLBnd(i) - aFBnd(i)) / aNbInt;
|
||||
}
|
||||
math_PSO aGlobSolver(aPFunc, aFBnd, aLBnd, aSteps);
|
||||
Standard_Real aLSDist;
|
||||
aGlobSolver.Perform(aSteps, aLSDist, aStartPoint);
|
||||
//
|
||||
gp_Pnt aLoc(aStartPoint(1), aStartPoint(2), aStartPoint(3));
|
||||
thePos.SetLocation(aLoc);
|
||||
theR = aStartPoint(4);
|
||||
|
||||
GetLSGap(thePoints, thePos, theR, theGap);
|
||||
if (theGap <= aTol)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
//
|
||||
math_Matrix aDirMatrix(1, aNbVar, 1, aNbVar, 0.0);
|
||||
for (i = 1; i <= aNbVar; i++)
|
||||
aDirMatrix(i, i) = 1.0;
|
||||
|
||||
//Set search direction for location to be perpendicular to axis to avoid
|
||||
//seaching along axis
|
||||
const gp_Dir aDir = thePos.Direction();
|
||||
gp_Pln aPln(thePos.Location(), aDir);
|
||||
gp_Dir aUDir = aPln.Position().XDirection();
|
||||
gp_Dir aVDir = aPln.Position().YDirection();
|
||||
for (i = 1; i <= 3; ++i)
|
||||
{
|
||||
aDirMatrix(i, 1) = aUDir.Coord(i);
|
||||
aDirMatrix(i, 2) = aVDir.Coord(i);
|
||||
gp_Dir aUVDir(aUDir.XYZ() + aVDir.XYZ());
|
||||
aDirMatrix(i, 3) = aUVDir.Coord(i);
|
||||
}
|
||||
|
||||
math_Powell aSolver(*aPFunc, aTol);
|
||||
aSolver.Perform(*aPFunc, aStartPoint, aDirMatrix);
|
||||
|
||||
if (aSolver.IsDone())
|
||||
{
|
||||
gp_Ax3 aPos2 = thePos;
|
||||
aSolver.Location(aStartPoint);
|
||||
aLoc.SetCoord(aStartPoint(1), aStartPoint(2), aStartPoint(3));
|
||||
aPos2.SetLocation(aLoc);
|
||||
Standard_Real anR2 = aStartPoint(4), aGap2 = 0.;
|
||||
//
|
||||
GetLSGap(thePoints, aPos2, anR2, aGap2);
|
||||
//
|
||||
if (aGap2 < theGap)
|
||||
{
|
||||
theGap = aGap2;
|
||||
thePos = aPos2;
|
||||
theR = anR2;
|
||||
}
|
||||
}
|
||||
if (theGap <= theTol)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TryCylinderByGaussField
|
||||
//purpose :
|
||||
//static method to try create cylinrical surface based on its Gauss field
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryCylinderByGaussField(const Handle(Geom_Surface)& theSurf,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Standard_Real theToler, const Standard_Integer theNbU, const Standard_Integer theNbV,
|
||||
const Standard_Boolean theLeastSquare)
|
||||
{
|
||||
Handle(Geom_Surface) aNewSurf;
|
||||
Standard_Real du = (theU2 - theU1) / theNbU, dv = (theV2 - theV1) / theNbV;
|
||||
Standard_Real aSigmaR = 0.;
|
||||
Standard_Real aTol = 100. * theToler;
|
||||
TColStd_Array1OfReal anRs(1, theNbU*theNbV);
|
||||
Handle(TColgp_HArray1OfXYZ) aPoints;
|
||||
if (theLeastSquare)
|
||||
{
|
||||
aPoints = new TColgp_HArray1OfXYZ(1, theNbU*theNbU);
|
||||
}
|
||||
//
|
||||
GeomLProp_SLProps aProps(theSurf, 2, Precision::Confusion());
|
||||
Standard_Real anAvMaxCurv = 0., anAvMinCurv = 0., anAvR = 0, aSign = 1.;
|
||||
gp_XYZ anAvDir;
|
||||
gp_Dir aMinD, aMaxD;
|
||||
Standard_Integer i, j, n = 0;
|
||||
Standard_Real anU, aV;
|
||||
for (i = 1, anU = theU1 + du / 2.; i <= theNbU; ++i, anU += du)
|
||||
{
|
||||
for (j = 1, aV = theV1 + dv / 2.; j <= theNbV; ++j, aV += dv)
|
||||
{
|
||||
aProps.SetParameters(anU, aV);
|
||||
if (!aProps.IsCurvatureDefined())
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
if (aProps.IsUmbilic())
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
++n;
|
||||
Standard_Real aMinCurv = aProps.MinCurvature();
|
||||
Standard_Real aMaxCurv = aProps.MaxCurvature();
|
||||
Standard_Real aGaussCurv = Abs(aProps.GaussianCurvature());
|
||||
Standard_Real aK1 = Sqrt(aGaussCurv);
|
||||
if (aK1 > theToler )
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
gp_XYZ aD;
|
||||
aProps.CurvatureDirections(aMaxD, aMinD);
|
||||
aMinCurv = Abs(aMinCurv);
|
||||
aMaxCurv = Abs(aMaxCurv);
|
||||
if (aMinCurv > aMaxCurv)
|
||||
{
|
||||
//aMinCurv < 0;
|
||||
aSign = -1.;
|
||||
std::swap(aMinCurv, aMaxCurv);
|
||||
gp_Dir aDummy = aMaxD;
|
||||
aMaxD = aMinD;
|
||||
aMinD = aDummy;
|
||||
}
|
||||
Standard_Real anR = 1. / aMaxCurv;
|
||||
Standard_Real anR2 = anR * anR;
|
||||
anRs(n) = anR;
|
||||
//
|
||||
if (n > 1)
|
||||
{
|
||||
if (Abs(aMaxCurv - anAvMaxCurv / (n - 1)) > aTol / anR2)
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
if (Abs(aMinCurv - anAvMinCurv / (n - 1)) > aTol)
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
}
|
||||
aD = aMinD.XYZ();
|
||||
anAvR += anR;
|
||||
anAvDir += aD;
|
||||
anAvMaxCurv += aMaxCurv;
|
||||
anAvMinCurv += aMinCurv;
|
||||
if (theLeastSquare)
|
||||
{
|
||||
aPoints->SetValue(n, aProps.Value().XYZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
anAvMaxCurv /= n;
|
||||
anAvMinCurv /= n;
|
||||
anAvR /= n;
|
||||
anAvDir /= n;
|
||||
//
|
||||
if (Abs(anAvMinCurv) > theToler)
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
//
|
||||
for (i = 1; i <= n; ++i)
|
||||
{
|
||||
Standard_Real d = (anRs(i) - anAvR);
|
||||
aSigmaR += d * d;
|
||||
}
|
||||
aSigmaR = Sqrt(aSigmaR / n);
|
||||
aTol = 3.*aSigmaR / Sqrt(n);
|
||||
if (aTol > 100. * theToler)
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
aProps.SetParameters(theU1, theV1);
|
||||
if (!aProps.IsCurvatureDefined())
|
||||
{
|
||||
return aNewSurf;
|
||||
}
|
||||
gp_Dir aNorm = aProps.Normal();
|
||||
gp_Pnt aLoc = aProps.Value();
|
||||
gp_Dir anAxD(anAvDir);
|
||||
gp_Vec aT(aSign*anAvR*aNorm.XYZ());
|
||||
aLoc.Translate(aT);
|
||||
gp_Ax1 anAx1(aLoc, anAxD);
|
||||
gp_Cylinder aCyl;
|
||||
aCyl.SetAxis(anAx1);
|
||||
aCyl.SetRadius(anAvR);
|
||||
|
||||
if (theLeastSquare)
|
||||
{
|
||||
gp_Ax3 aPos = aCyl.Position();
|
||||
Standard_Real anR = aCyl.Radius();
|
||||
Standard_Real aGap = 0.;
|
||||
Standard_Boolean IsDone = GetCylByLS(aPoints, theToler, aPos, anR, aGap);
|
||||
if (IsDone)
|
||||
{
|
||||
aCyl.SetPosition(aPos);
|
||||
aCyl.SetRadius(anR);
|
||||
}
|
||||
}
|
||||
|
||||
aNewSurf = new Geom_CylindricalSurface(aCyl);
|
||||
|
||||
return aNewSurf;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TryTorusSphere
|
||||
//purpose :
|
||||
// static method to try create toroidal surface.
|
||||
// In case <isTryUMajor> = Standard_True try to use V isoline radius as minor radaius.
|
||||
static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf,
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryTorusSphere(const Handle(Geom_Surface)& theSurf,
|
||||
const Handle(Geom_Circle)& circle,
|
||||
const Handle(Geom_Circle)& otherCircle,
|
||||
const Standard_Real Param1,
|
||||
@@ -181,9 +550,14 @@ static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf,
|
||||
return newSurface;
|
||||
}
|
||||
|
||||
static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf,
|
||||
//=======================================================================
|
||||
//function : ComputeGap
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real GeomConvert_SurfToAnaSurf::ComputeGap(const Handle(Geom_Surface)& theSurf,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol = RealLast())
|
||||
const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol)
|
||||
{
|
||||
GeomAdaptor_Surface aGAS(theNewSurf);
|
||||
GeomAbs_SurfaceType aSType = aGAS.GetType();
|
||||
@@ -228,7 +602,7 @@ static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf,
|
||||
Standard_Real DU2 = DU / 2., DV2 = DV / 2.;
|
||||
for (j = 1; (j < NP) && onSurface; j++) {
|
||||
Standard_Real V = theV1 + DV*(j - 1) + DV2;
|
||||
for (i = 1; i <= NP; i++) {
|
||||
for (i = 1; i < NP; i++) {
|
||||
Standard_Real U = theU1 + DU*(i - 1) + DU2;
|
||||
theSurf->D0(U, V, P3d);
|
||||
|
||||
@@ -384,7 +758,9 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa
|
||||
//
|
||||
Standard_Real toler = InitialToler;
|
||||
Handle(Geom_Surface) newSurf[5];
|
||||
Standard_Real dd[5] = { -1., -1., -1., -1., -1 };
|
||||
Standard_Real dd[5] = { RealLast(), RealLast(), RealLast(), RealLast(), RealLast() };
|
||||
GeomAbs_SurfaceType aSTypes[5] = { GeomAbs_Plane, GeomAbs_Cylinder,
|
||||
GeomAbs_Cone, GeomAbs_Sphere, GeomAbs_Torus };
|
||||
|
||||
//Check boundaries
|
||||
Standard_Real U1, U2, V1, V2;
|
||||
@@ -481,183 +857,136 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa
|
||||
//convert middle uiso and viso to canonical representation
|
||||
Standard_Real VMid = 0.5*(V1 + V2);
|
||||
Standard_Real UMid = 0.5*(U1 + U2);
|
||||
Handle(Geom_Surface) TrSurf = aTempS;
|
||||
if(!aDoSegment)
|
||||
TrSurf = new Geom_RectangularTrimmedSurface(aTempS, U1, U2, V1, V2);
|
||||
// Handle(Geom_Surface) TrSurf = aTempS;
|
||||
|
||||
Handle(Geom_Curve) UIso = TrSurf->UIso(UMid);
|
||||
Handle(Geom_Curve) VIso = TrSurf->VIso(VMid);
|
||||
Handle(Geom_Curve) UIso = aTempS->UIso(UMid);
|
||||
Handle(Geom_Curve) VIso = aTempS->VIso(VMid);
|
||||
|
||||
Standard_Real cuf, cul, cvf, cvl, aGap1, aGap2;
|
||||
Handle(Geom_Curve) umidiso = GeomConvert_CurveToAnaCurve::ComputeCurve(UIso, toler, V1, V2, cuf, cul, aGap1);
|
||||
Handle(Geom_Curve) vmidiso = GeomConvert_CurveToAnaCurve::ComputeCurve(VIso, toler, U1, U2, cvf, cvl, aGap2);
|
||||
if (umidiso.IsNull() || vmidiso.IsNull()) {
|
||||
return newSurf[isurf];
|
||||
}
|
||||
|
||||
//
|
||||
Standard_Boolean VCase = Standard_False;
|
||||
|
||||
if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle)))
|
||||
if (!umidiso.IsNull() && !vmidiso.IsNull())
|
||||
{
|
||||
aToroidSphere = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Cylinder || myTarget == GeomAbs_Cone))
|
||||
|
||||
//
|
||||
Standard_Boolean VCase = Standard_False;
|
||||
|
||||
if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle)))
|
||||
{
|
||||
isurf = 1;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
aToroidSphere = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Cylinder || myTarget == GeomAbs_Cone))
|
||||
{
|
||||
isurf = 1;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
}
|
||||
isurf = 3; // set sphere
|
||||
}
|
||||
isurf = 3; // set sphere
|
||||
}
|
||||
else if (umidiso->IsKind(STANDARD_TYPE(Geom_Line)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) {
|
||||
aCylinderConus = Standard_True; VCase = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus))
|
||||
else if (umidiso->IsKind(STANDARD_TYPE(Geom_Line)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) {
|
||||
aCylinderConus = Standard_True; VCase = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus))
|
||||
{
|
||||
isurf = 3;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
}
|
||||
isurf = 1;// set cylinder
|
||||
}
|
||||
else if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Line)))
|
||||
{
|
||||
isurf = 3;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
aCylinderConus = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus))
|
||||
{
|
||||
isurf = 3;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
}
|
||||
isurf = 1;// set cylinder
|
||||
}
|
||||
|
||||
|
||||
//case of torus-sphere
|
||||
if (aToroidSphere) {
|
||||
|
||||
isurf = 3; // Set spherical surface
|
||||
|
||||
Handle(Geom_Circle) Ucircle = Handle(Geom_Circle)::DownCast(umidiso);
|
||||
Handle(Geom_Circle) Vcircle = Handle(Geom_Circle)::DownCast(vmidiso);
|
||||
// torus
|
||||
// try when V isolines is with same radius
|
||||
Handle(Geom_Surface) anObject =
|
||||
TryTorusSphere(mySurf, Vcircle, Ucircle, V1, V2, U1, U2, toler, Standard_True);
|
||||
if (anObject.IsNull()) // try when U isolines is with same radius
|
||||
anObject = TryTorusSphere(mySurf, Ucircle, Vcircle, U1, U2, V1, V2, toler, Standard_False);
|
||||
|
||||
if (!anObject.IsNull())
|
||||
{
|
||||
if (anObject->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
|
||||
{
|
||||
isurf = 4; // set torus
|
||||
}
|
||||
newSurf[isurf] = anObject;
|
||||
if (myConvType == GeomConvert_Target && (myTarget != aSTypes[isurf]))
|
||||
{
|
||||
myGap = RealLast();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myGap = dd[isurf];
|
||||
}
|
||||
}
|
||||
//case of cone - cylinder
|
||||
else if (aCylinderConus) {
|
||||
isurf = 1; //set cylindrical surface
|
||||
Handle(Geom_Surface) anObject = TryCylinerCone(aTempS, VCase, umidiso, vmidiso,
|
||||
U1, U2, V1, V2, toler);
|
||||
if (!anObject.IsNull())
|
||||
{
|
||||
if (anObject->IsKind(STANDARD_TYPE(Geom_ConicalSurface)))
|
||||
{
|
||||
isurf = 2; // set conical surface
|
||||
}
|
||||
if (myConvType == GeomConvert_Target && (myTarget != aSTypes[isurf]))
|
||||
{
|
||||
myGap = RealLast();
|
||||
return NULL;
|
||||
}
|
||||
newSurf[isurf] = anObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
myGap = dd[isurf];
|
||||
}
|
||||
}
|
||||
isurf = 1;// set cylinder
|
||||
}
|
||||
else if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Line)))
|
||||
//Additional checking for case of cylinder
|
||||
if (!aCylinderConus && !aToroidSphere)
|
||||
{
|
||||
aCylinderConus = Standard_True;
|
||||
if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus))
|
||||
{
|
||||
isurf = 3;
|
||||
myGap = dd[isurf];
|
||||
return newSurf[isurf];
|
||||
}
|
||||
isurf = 1;// set cylinder
|
||||
}
|
||||
Standard_Real cl = 0.0;
|
||||
//case of torus-sphere
|
||||
if (aToroidSphere) {
|
||||
|
||||
isurf = 3; // Set spherical surface
|
||||
|
||||
Handle(Geom_Circle) Ucircle = Handle(Geom_Circle)::DownCast(umidiso);
|
||||
Handle(Geom_Circle) Vcircle = Handle(Geom_Circle)::DownCast(vmidiso);
|
||||
// torus
|
||||
// try when V isolines is with same radius
|
||||
Handle(Geom_Surface) anObject =
|
||||
TryTorusSphere(mySurf, Vcircle, Ucircle, V1, V2, U1, U2, toler, Standard_True);
|
||||
if (anObject.IsNull()) // try when U isolines is with same radius
|
||||
anObject = TryTorusSphere(mySurf, Ucircle, Vcircle, U1, U2, V1, V2, toler, Standard_False);
|
||||
|
||||
//Try cylinder using Gauss field
|
||||
Standard_Integer aNbU = 7, aNbV = 7;
|
||||
Standard_Boolean aLeastSquare = Standard_True;
|
||||
Handle(Geom_Surface) anObject = TryCylinderByGaussField(aTempS, U1, U2, V1, V2, toler,
|
||||
aNbU, aNbV, aLeastSquare);
|
||||
if (!anObject.IsNull())
|
||||
{
|
||||
if (anObject->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)))
|
||||
{
|
||||
isurf = 4; // set torus
|
||||
}
|
||||
isurf = 1;
|
||||
newSurf[isurf] = anObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
myGap = dd[isurf];
|
||||
}
|
||||
}
|
||||
//case of cone - cylinder
|
||||
else if (aCylinderConus) {
|
||||
Standard_Real param1, param2, cf1, cf2;
|
||||
Handle(Geom_Curve) firstiso, lastiso;
|
||||
Handle(Geom_Circle) firstisocirc, lastisocirc, midisocirc;
|
||||
gp_Dir isoline;
|
||||
if (VCase) {
|
||||
param1 = U1; param2 = U2;
|
||||
firstiso = TrSurf->VIso(V1);
|
||||
lastiso = TrSurf->VIso(V2);
|
||||
midisocirc = Handle(Geom_Circle)::DownCast(vmidiso);
|
||||
isoline = Handle(Geom_Line)::DownCast(umidiso)->Lin().Direction();
|
||||
}
|
||||
else {
|
||||
param1 = V1; param2 = V2;
|
||||
firstiso = TrSurf->UIso(U1);
|
||||
lastiso = TrSurf->UIso(U2);
|
||||
midisocirc = Handle(Geom_Circle)::DownCast(umidiso);
|
||||
isoline = Handle(Geom_Line)::DownCast(vmidiso)->Lin().Direction();
|
||||
}
|
||||
firstisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(firstiso, toler, param1, param2, cf1, cl, aGap1));
|
||||
lastisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(lastiso, toler, param1, param2, cf2, cl, aGap2));
|
||||
if (!firstisocirc.IsNull() || !lastisocirc.IsNull()) {
|
||||
Standard_Real R1, R2, R3;
|
||||
gp_Pnt P1, P2, P3;
|
||||
if (!firstisocirc.IsNull()) {
|
||||
R1 = firstisocirc->Circ().Radius();
|
||||
P1 = firstisocirc->Circ().Location();
|
||||
}
|
||||
else {
|
||||
R1 = 0;
|
||||
P1 = firstiso->Value((firstiso->LastParameter() - firstiso->FirstParameter()) / 2);
|
||||
}
|
||||
R2 = midisocirc->Circ().Radius();
|
||||
P2 = midisocirc->Circ().Location();
|
||||
if (!lastisocirc.IsNull()) {
|
||||
R3 = lastisocirc->Circ().Radius();
|
||||
P3 = lastisocirc->Circ().Location();
|
||||
}
|
||||
else {
|
||||
R3 = 0;
|
||||
P3 = lastiso->Value((lastiso->LastParameter() - lastiso->FirstParameter()) / 2);
|
||||
}
|
||||
//cylinder
|
||||
if (((Abs(R2 - R1)) < toler) && ((Abs(R3 - R1)) < toler) &&
|
||||
((Abs(R3 - R2)) < toler)) {
|
||||
isurf = 1;
|
||||
gp_Ax3 Axes(P1, gp_Dir(gp_Vec(P1, P3)));
|
||||
Handle(Geom_CylindricalSurface) anObject =
|
||||
new Geom_CylindricalSurface(Axes, R1);
|
||||
if (myConvType == GeomConvert_Target && myTarget != GeomAbs_Cylinder)
|
||||
{
|
||||
return newSurf[isurf];
|
||||
}
|
||||
newSurf[isurf] = anObject;
|
||||
}
|
||||
//cone
|
||||
else if ((((Abs(R1)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R3)))) ||
|
||||
(((Abs(R3)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R1))))) {
|
||||
Standard_Real radius;
|
||||
gp_Ax3 Axes;
|
||||
Standard_Real semiangle =
|
||||
gp_Vec(isoline).Angle(gp_Vec(P3, P1));
|
||||
if (semiangle>M_PI / 2) semiangle = M_PI - semiangle;
|
||||
if (R1 > R3) {
|
||||
radius = R3;
|
||||
Axes = gp_Ax3(P3, gp_Dir(gp_Vec(P3, P1)));
|
||||
}
|
||||
else {
|
||||
radius = R1;
|
||||
Axes = gp_Ax3(P1, gp_Dir(gp_Vec(P1, P3)));
|
||||
}
|
||||
Handle(Geom_ConicalSurface) anObject =
|
||||
new Geom_ConicalSurface(Axes, semiangle, radius);
|
||||
isurf = 2;
|
||||
if (myConvType == GeomConvert_Target && myTarget != GeomAbs_Cone)
|
||||
{
|
||||
return newSurf[isurf];
|
||||
}
|
||||
newSurf[isurf] = anObject;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myGap = dd[isurf];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
// verification
|
||||
//---------------------------------------------------------------------
|
||||
GeomAbs_SurfaceType aSTypes[5] = { GeomAbs_Plane, GeomAbs_Cylinder,
|
||||
GeomAbs_Cone, GeomAbs_Sphere, GeomAbs_Torus };
|
||||
Standard_Integer imin = -1;
|
||||
Standard_Real aDmin = RealLast();
|
||||
for (isurf = 0; isurf < 5; ++isurf)
|
||||
{
|
||||
if (newSurf[isurf].IsNull())
|
||||
continue;
|
||||
dd[isurf] = ComputeGap(TrSurf, U1, U2, V1, V2, newSurf[isurf], toler);
|
||||
dd[isurf] = ComputeGap(aTempS, U1, U2, V1, V2, newSurf[isurf], toler);
|
||||
if (dd[isurf] <= toler)
|
||||
{
|
||||
if (myConvType == GeomConvert_Simplest || (myConvType == GeomConvert_Target && myTarget == aSTypes[isurf]))
|
||||
@@ -682,7 +1011,7 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa
|
||||
return newSurf[imin];
|
||||
}
|
||||
|
||||
return newSurf[0];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -25,8 +25,10 @@
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <GeomConvert_ConvType.hxx>
|
||||
#include <GeomAbs_SurfaceType.hxx>
|
||||
#include <TColgp_HArray1OfXYZ.hxx>
|
||||
class Geom_Surface;
|
||||
|
||||
class Geom_SurfaceOfRevolution;
|
||||
class Geom_Circle;
|
||||
|
||||
//! Converts a surface to the analitical form with given
|
||||
//! precision. Conversion is done only the surface is bspline
|
||||
@@ -75,6 +77,48 @@ public:
|
||||
//! Returns true, if surface is canonical
|
||||
Standard_EXPORT static Standard_Boolean IsCanonical (const Handle(Geom_Surface)& S);
|
||||
|
||||
private:
|
||||
//!static method for checking surface of revolution
|
||||
//!To avoid two-parts cone-like surface
|
||||
static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf,
|
||||
Standard_Real& V1, Standard_Real& V2);
|
||||
|
||||
//!static method to try create cylindrical or conical surface
|
||||
static Handle(Geom_Surface) TryCylinerCone(const Handle(Geom_Surface)& theSurf, const Standard_Boolean theVCase,
|
||||
const Handle(Geom_Curve)& theUmidiso, const Handle(Geom_Curve)& theVmidiso,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Standard_Real theToler);
|
||||
|
||||
//!static method to try create cylinrical surface using least square method
|
||||
static Standard_Boolean GetCylByLS(const Handle(TColgp_HArray1OfXYZ)& thePoints,
|
||||
const Standard_Real theTol,
|
||||
gp_Ax3& thePos, Standard_Real& theR,
|
||||
Standard_Real& theGap);
|
||||
|
||||
//!static method to try create cylinrical surface based on its Gauss field
|
||||
static Handle(Geom_Surface) TryCylinderByGaussField(const Handle(Geom_Surface)& theSurf,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Standard_Real theToler, const Standard_Integer theNbU = 20, const Standard_Integer theNbV = 20,
|
||||
const Standard_Boolean theLeastSquare = Standard_False);
|
||||
|
||||
//! static method to try create toroidal surface.
|
||||
//! In case <isTryUMajor> = Standard_True try to use V isoline radius as minor radaius.
|
||||
static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf,
|
||||
const Handle(Geom_Circle)& circle,
|
||||
const Handle(Geom_Circle)& otherCircle,
|
||||
const Standard_Real Param1,
|
||||
const Standard_Real Param2,
|
||||
const Standard_Real aParam1ToCrv,
|
||||
const Standard_Real aParam2ToCrv,
|
||||
const Standard_Real toler,
|
||||
const Standard_Boolean isTryUMajor);
|
||||
|
||||
static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf,
|
||||
const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2,
|
||||
const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol = RealLast());
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@@ -1547,7 +1547,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
|
||||
}
|
||||
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
aProgramSrc->SetPBR (theIsPBR);
|
||||
aProgramSrc->SetPBR (theIsPBR); // should be set before defaultGlslVersion()
|
||||
|
||||
TCollection_AsciiString aSrcVert, aSrcVertExtraFunc, aSrcVertExtraMain;
|
||||
TCollection_AsciiString aSrcFrag, aSrcFragGetVertColor, aSrcFragExtraMain;
|
||||
@@ -1987,6 +1987,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getPBREnvBakingProgram
|
||||
{
|
||||
Standard_ASSERT_RAISE (theIndex >= 0 && theIndex <= 2,"");
|
||||
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
|
||||
aProgramSrc->SetPBR (true); // should be set before defaultGlslVersion()
|
||||
|
||||
Graphic3d_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
|
||||
|
||||
TCollection_AsciiString aSrcVert = TCollection_AsciiString()
|
||||
@@ -2033,7 +2035,6 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getPBREnvBakingProgram
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbShadowMaps (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->SetPBR (true);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
|
||||
return aProgramSrc;
|
||||
|
@@ -82,7 +82,7 @@ void Interface_Static::Standards ()
|
||||
Interface_Static::Init("XSTEP" ,"write.surfacecurve.mode", '&',"eval Off");
|
||||
Interface_Static::Init("XSTEP" ,"write.surfacecurve.mode", '&',"eval On");
|
||||
// Interface_Static::Init("XSTEP" ,"write.surfacecurve.mode", '&',"eval NoAnalytic");
|
||||
Interface_Static::SetIVal ("write.surfacecurve.mode",0);
|
||||
Interface_Static::SetIVal ("write.surfacecurve.mode",1);
|
||||
|
||||
// lastpreci : pour recuperer la derniere valeur codee (cf XSControl)
|
||||
// (0 pour dire : pas codee)
|
||||
|
@@ -625,7 +625,10 @@ void MeshVS_ElementalColorPrsBuilder::Build ( const Handle(Prs3d_Presentation)&
|
||||
}
|
||||
|
||||
aGroup2->AddPrimitiveArray (aFaceTriangles);
|
||||
aSGroup->AddPrimitiveArray (anEdgeSegments);
|
||||
if (anEdgeOn)
|
||||
{
|
||||
aSGroup->AddPrimitiveArray (anEdgeSegments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <Standard_OutOfMemory.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_TypeMismatch.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
//! Defines an array of values of configurable size.
|
||||
//! For instance, this class allows defining an array of 32-bit or 64-bit integer values with bitness determined in runtime.
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
}
|
||||
|
||||
//! Move constructor
|
||||
NCollection_AliasedArray (NCollection_AliasedArray&& theOther) noexcept
|
||||
NCollection_AliasedArray (NCollection_AliasedArray&& theOther) Standard_Noexcept
|
||||
: myData (theOther.myData), myStride (theOther.myStride), mySize (theOther.mySize), myDeletable (theOther.myDeletable)
|
||||
{
|
||||
theOther.myDeletable = false;
|
||||
|
@@ -125,10 +125,10 @@ protected:
|
||||
|
||||
// Since C++20 inheritance from std::iterator is deprecated, so define predefined types manually:
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = UniversalIterator;
|
||||
using value_type = IteratorInterface*;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = UniversalIterator*;
|
||||
using reference = UniversalIterator&;
|
||||
using pointer = value_type;
|
||||
using reference = value_type;
|
||||
|
||||
UniversalIterator() {}
|
||||
|
||||
@@ -171,18 +171,8 @@ protected:
|
||||
return aValue;
|
||||
}
|
||||
|
||||
const UniversalIterator& operator* () const { return *this; }
|
||||
UniversalIterator& operator* () { return *this; }
|
||||
|
||||
const UniversalIterator* operator->() const { return this; }
|
||||
UniversalIterator* operator->() { return this; }
|
||||
|
||||
// type cast to actual iterator
|
||||
template <typename Iterator>
|
||||
const Iterator& DownCast () const
|
||||
{
|
||||
return dynamic_cast<OSD_Parallel::IteratorWrapper<Iterator>*>(myPtr.get())->Value();
|
||||
}
|
||||
const reference operator* () const { return myPtr.get(); }
|
||||
reference operator* () { return myPtr.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<IteratorInterface> myPtr;
|
||||
@@ -196,7 +186,14 @@ protected:
|
||||
public:
|
||||
virtual ~FunctorInterface() {}
|
||||
|
||||
virtual void operator () (UniversalIterator& theIterator) const = 0;
|
||||
virtual void operator () (IteratorInterface* theIterator) const = 0;
|
||||
|
||||
// type cast to actual iterator
|
||||
template <typename Iterator>
|
||||
static const Iterator& DownCast(IteratorInterface* theIterator)
|
||||
{
|
||||
return dynamic_cast<OSD_Parallel::IteratorWrapper<Iterator>*>(theIterator)->Value();
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -211,9 +208,9 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (UniversalIterator& theIterator) const Standard_OVERRIDE
|
||||
virtual void operator() (IteratorInterface* theIterator) const Standard_OVERRIDE
|
||||
{
|
||||
const Iterator& anIt = theIterator.DownCast<Iterator>();
|
||||
const Iterator& anIt = DownCast<Iterator>(theIterator);
|
||||
myFunctor(*anIt);
|
||||
}
|
||||
|
||||
@@ -233,9 +230,9 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (UniversalIterator& theIterator) const Standard_OVERRIDE
|
||||
virtual void operator() (IteratorInterface* theIterator) const Standard_OVERRIDE
|
||||
{
|
||||
Standard_Integer anIndex = theIterator.DownCast<Standard_Integer>();
|
||||
Standard_Integer anIndex = DownCast<Standard_Integer>(theIterator);
|
||||
myFunctor(anIndex);
|
||||
}
|
||||
|
||||
|
@@ -100,7 +100,7 @@ namespace
|
||||
{
|
||||
for (OSD_Parallel::UniversalIterator anIter = myRange.It(); anIter != myRange.End(); anIter = myRange.It())
|
||||
{
|
||||
myPerformer (anIter);
|
||||
myPerformer (*anIter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <NCollection_AliasedArray.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec3f.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
//! Defines an array of 3D nodes of single/double precision configurable at construction time.
|
||||
class Poly_ArrayOfNodes : public NCollection_AliasedArray<>
|
||||
@@ -85,14 +86,14 @@ public:
|
||||
Poly_ArrayOfNodes& operator= (const Poly_ArrayOfNodes& theOther) { return Assign (theOther); }
|
||||
|
||||
//! Move constructor
|
||||
Poly_ArrayOfNodes (Poly_ArrayOfNodes&& theOther) noexcept
|
||||
Poly_ArrayOfNodes (Poly_ArrayOfNodes&& theOther) Standard_Noexcept
|
||||
: NCollection_AliasedArray (std::move (theOther))
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//! Move assignment operator; @sa Move()
|
||||
Poly_ArrayOfNodes& operator= (Poly_ArrayOfNodes&& theOther) noexcept
|
||||
Poly_ArrayOfNodes& operator= (Poly_ArrayOfNodes&& theOther) Standard_Noexcept
|
||||
{
|
||||
return Move (theOther);
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <NCollection_AliasedArray.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2f.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
//! Defines an array of 2D nodes of single/double precision configurable at construction time.
|
||||
class Poly_ArrayOfUVNodes : public NCollection_AliasedArray<>
|
||||
@@ -85,14 +86,14 @@ public:
|
||||
Poly_ArrayOfUVNodes& operator= (const Poly_ArrayOfUVNodes& theOther) { return Assign (theOther); }
|
||||
|
||||
//! Move constructor
|
||||
Poly_ArrayOfUVNodes (Poly_ArrayOfUVNodes&& theOther) noexcept
|
||||
Poly_ArrayOfUVNodes (Poly_ArrayOfUVNodes&& theOther) Standard_Noexcept
|
||||
: NCollection_AliasedArray (std::move (theOther))
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//! Move assignment operator; @sa Move()
|
||||
Poly_ArrayOfUVNodes& operator= (Poly_ArrayOfUVNodes&& theOther) noexcept
|
||||
Poly_ArrayOfUVNodes& operator= (Poly_ArrayOfUVNodes&& theOther) Standard_Noexcept
|
||||
{
|
||||
return Move (theOther);
|
||||
}
|
||||
|
@@ -213,37 +213,39 @@ void PrsDim_ConcentricRelation::ComputeTwoEdgesConcentric(const Handle(Prs3d_Pre
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void PrsDim_ConcentricRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
|
||||
const Standard_Integer)
|
||||
void PrsDim_ConcentricRelation::ComputeSelection (const Handle(SelectMgr_Selection)& aSelection,
|
||||
const Standard_Integer)
|
||||
{
|
||||
Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
|
||||
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this,7);
|
||||
|
||||
//Creation of 2 sensitive circles
|
||||
// the greater
|
||||
gp_Ax2 ax(myCenter, myDir);
|
||||
gp_Circ aCirc (ax, myRad);
|
||||
Handle(Select3D_SensitiveCircle) sensit = new Select3D_SensitiveCircle (own, aCirc);
|
||||
aSelection->Add(sensit);
|
||||
// the smaller
|
||||
aCirc.SetRadius(myRad/2);
|
||||
sensit = new Select3D_SensitiveCircle (own, aCirc);
|
||||
aSelection->Add(sensit);
|
||||
|
||||
// the greater
|
||||
gp_Ax2 anAx (myCenter, myDir);
|
||||
gp_Circ aCirc (anAx, myRad);
|
||||
Handle(Select3D_SensitiveCircle) sensit = new Select3D_SensitiveCircle (anOwner, aCirc);
|
||||
aSelection->Add (sensit);
|
||||
|
||||
// the smaller
|
||||
aCirc.SetRadius (myRad / 2);
|
||||
sensit = new Select3D_SensitiveCircle (anOwner, aCirc);
|
||||
aSelection->Add (sensit);
|
||||
|
||||
//Creation of 2 segments sensitive for the cross
|
||||
Handle(Select3D_SensitiveSegment) seg;
|
||||
gp_Pnt otherPnt = myPnt.Mirrored(myCenter);
|
||||
seg = new Select3D_SensitiveSegment(own,
|
||||
otherPnt,
|
||||
myPnt);
|
||||
aSelection->Add(seg);
|
||||
seg = new Select3D_SensitiveSegment(anOwner,
|
||||
otherPnt,
|
||||
myPnt);
|
||||
aSelection->Add (seg);
|
||||
|
||||
gp_Ax1 RotateAxis(myCenter, myDir);
|
||||
gp_Pnt FPnt = myCenter.Rotated(RotateAxis, M_PI/2);
|
||||
gp_Pnt SPnt = myCenter.Rotated(RotateAxis, -M_PI/2);
|
||||
seg = new Select3D_SensitiveSegment(own,
|
||||
FPnt,
|
||||
SPnt);
|
||||
aSelection->Add(seg);
|
||||
gp_Pnt FPnt = myCenter.Rotated (RotateAxis, M_PI_2);
|
||||
gp_Pnt SPnt = myCenter.Rotated (RotateAxis, -M_PI_2);
|
||||
seg = new Select3D_SensitiveSegment(anOwner,
|
||||
FPnt,
|
||||
SPnt);
|
||||
aSelection->Add (seg);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include <Prs3d_Drawer.hxx>
|
||||
#include <Prs3d_Presentation.hxx>
|
||||
#include <Select3D_SensitiveBox.hxx>
|
||||
#include <Select3D_SensitiveCircle.hxx>
|
||||
#include <Select3D_SensitivePoly.hxx>
|
||||
#include <Select3D_SensitiveSegment.hxx>
|
||||
#include <SelectMgr_EntityOwner.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
@@ -202,124 +202,141 @@ void PrsDim_EqualDistanceRelation::Compute (const Handle(PrsMgr_PresentationMana
|
||||
|
||||
//=======================================================================
|
||||
//function : ComputeSelection
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void PrsDim_EqualDistanceRelation::ComputeSelection( const Handle( SelectMgr_Selection )& aSelection,
|
||||
const Standard_Integer )
|
||||
void PrsDim_EqualDistanceRelation::ComputeSelection (const Handle( SelectMgr_Selection )& aSelection,
|
||||
const Standard_Integer)
|
||||
{
|
||||
Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
|
||||
Handle( Select3D_SensitiveSegment ) seg;
|
||||
|
||||
seg = new Select3D_SensitiveSegment( own, myPoint1, myPoint2 );
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
|
||||
seg = new Select3D_SensitiveSegment( own, myPoint3, myPoint4 );
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
|
||||
// Line between two middles
|
||||
gp_Pnt Middle12( (myPoint1.XYZ() + myPoint2.XYZ()) * 0.5 ),
|
||||
gp_Pnt Middle12( (myPoint1.XYZ() + myPoint2.XYZ()) * 0.5 ),
|
||||
Middle34( (myPoint3.XYZ() + myPoint4.XYZ()) *0.5 );
|
||||
seg = new Select3D_SensitiveSegment( own, Middle12, Middle34 );
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
|
||||
gp_Pnt Middle((Middle12.XYZ() + Middle34.XYZ())*0.5);
|
||||
Standard_Real SmallDist = .001;
|
||||
Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
|
||||
Middle.X() - SmallDist,
|
||||
Middle.Y() - SmallDist,
|
||||
Middle.Z() - SmallDist,
|
||||
Middle.X() + SmallDist,
|
||||
Middle.Y() + SmallDist,
|
||||
Middle.Z() + SmallDist );
|
||||
aSelection->Add(box);
|
||||
Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox(own,
|
||||
Middle.X() - SmallDist,
|
||||
Middle.Y() - SmallDist,
|
||||
Middle.Z() - SmallDist,
|
||||
Middle.X() + SmallDist,
|
||||
Middle.Y() + SmallDist,
|
||||
Middle.Z() + SmallDist);
|
||||
aSelection->Add (box);
|
||||
|
||||
if (myFShape.ShapeType() == TopAbs_EDGE){
|
||||
if (myFShape.ShapeType() == TopAbs_EDGE)
|
||||
{
|
||||
BRepAdaptor_Curve aCurve(TopoDS::Edge(myFShape));
|
||||
if (aCurve.GetType() == GeomAbs_Line){
|
||||
//add sensetive element - line
|
||||
if (aCurve.GetType() == GeomAbs_Line)
|
||||
{
|
||||
//add sensetive element - line
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint1, myPoint1);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
else if (aCurve.GetType() == GeomAbs_Circle){
|
||||
else if (aCurve.GetType() == GeomAbs_Circle)
|
||||
{
|
||||
Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
|
||||
Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint1),
|
||||
LastPar = ElCLib::Parameter(aCircle->Circ(), myPoint1);
|
||||
if (LastPar < FirstPar ) LastPar+=M_PI*2;
|
||||
Handle(Select3D_SensitiveCircle) circ = new Select3D_SensitiveCircle (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add( circ );
|
||||
if (LastPar < FirstPar ) LastPar += M_PI * 2;
|
||||
Handle(Select3D_SensitivePoly) circ = new Select3D_SensitivePoly (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add (circ);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint1, myPoint1);
|
||||
aSelection->Add( seg );
|
||||
}
|
||||
|
||||
if (mySShape.ShapeType() == TopAbs_EDGE){
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
|
||||
if (mySShape.ShapeType() == TopAbs_EDGE)
|
||||
{
|
||||
BRepAdaptor_Curve aCurve(TopoDS::Edge(mySShape));
|
||||
if (aCurve.GetType() == GeomAbs_Line) {
|
||||
if (aCurve.GetType() == GeomAbs_Line)
|
||||
{
|
||||
//add sensetive element - line
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint2, myPoint2);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
else if (aCurve.GetType() == GeomAbs_Circle){
|
||||
else if (aCurve.GetType() == GeomAbs_Circle)
|
||||
{
|
||||
Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
|
||||
Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint2),
|
||||
LastPar = ElCLib::Parameter(aCircle->Circ(), myPoint2);
|
||||
if (LastPar < FirstPar ) LastPar+=M_PI*2;
|
||||
Handle(Select3D_SensitiveCircle) circ = new Select3D_SensitiveCircle (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add( circ );
|
||||
if (LastPar < FirstPar) LastPar += M_PI * 2;
|
||||
Handle(Select3D_SensitivePoly) circ = new Select3D_SensitivePoly (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add (circ);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint2, myPoint2);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
|
||||
if (myShape3.ShapeType() == TopAbs_EDGE){
|
||||
if (myShape3.ShapeType() == TopAbs_EDGE)
|
||||
{
|
||||
BRepAdaptor_Curve aCurve(TopoDS::Edge(myShape3));
|
||||
if (aCurve.GetType() == GeomAbs_Line) {
|
||||
if (aCurve.GetType() == GeomAbs_Line)
|
||||
{
|
||||
//add sensetive element - line
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
else if (aCurve.GetType() == GeomAbs_Circle){
|
||||
else if (aCurve.GetType() == GeomAbs_Circle)
|
||||
{
|
||||
Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
|
||||
Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint3),
|
||||
LastPar = ElCLib::Parameter(aCircle->Circ(), myPoint3);
|
||||
if (LastPar < FirstPar ) LastPar+=M_PI*2;
|
||||
Handle(Select3D_SensitiveCircle) circ = new Select3D_SensitiveCircle (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add( circ );
|
||||
if (LastPar < FirstPar) LastPar += M_PI * 2;
|
||||
Handle(Select3D_SensitivePoly) circ = new Select3D_SensitivePoly (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add (circ);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
|
||||
if (myShape4.ShapeType() == TopAbs_EDGE){
|
||||
if (myShape4.ShapeType() == TopAbs_EDGE)
|
||||
{
|
||||
BRepAdaptor_Curve aCurve(TopoDS::Edge(myShape4));
|
||||
if (aCurve.GetType() == GeomAbs_Line) {
|
||||
if (aCurve.GetType() == GeomAbs_Line)
|
||||
{
|
||||
//add sensetive element - line
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint4, myPoint4);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
else if (aCurve.GetType() == GeomAbs_Circle){
|
||||
else if (aCurve.GetType() == GeomAbs_Circle)
|
||||
{
|
||||
Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
|
||||
Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint4),
|
||||
LastPar = ElCLib::Parameter(aCircle->Circ(), myPoint4);
|
||||
if (LastPar < FirstPar ) LastPar+=M_PI*2;
|
||||
Handle(Select3D_SensitiveCircle) circ = new Select3D_SensitiveCircle (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
if (LastPar < FirstPar) LastPar += M_PI * 2;
|
||||
Handle(Select3D_SensitivePoly) circ = new Select3D_SensitivePoly (own, aCircle->Circ(), FirstPar, LastPar);
|
||||
aSelection->Add( circ );
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
seg = new Select3D_SensitiveSegment( own, myAttachPoint4, myPoint4);
|
||||
aSelection->Add( seg );
|
||||
aSelection->Add (seg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <OSD_FileSystem.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <RWGltf_GltfAccessorLayout.hxx>
|
||||
@@ -45,7 +46,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DRACO
|
||||
#include <Standard_WarningsDisable.hxx>
|
||||
#include <draco/compression/encode.h>
|
||||
#include <Standard_WarningsRestore.hxx>
|
||||
#endif
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(RWGltf_CafWriter, Standard_Transient)
|
||||
@@ -168,6 +171,72 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_DRACO
|
||||
//! Functor for parallel execution of encoding meshes to Draco buffers.
|
||||
class DracoEncodingFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
DracoEncodingFunctor (const Message_ProgressRange& theProgress,
|
||||
draco::Encoder& theDracoEncoder,
|
||||
const std::vector<std::shared_ptr<RWGltf_CafWriter::Mesh>>& theMeshes,
|
||||
std::vector<std::shared_ptr<draco::EncoderBuffer>>& theEncoderBuffers)
|
||||
: myProgress(theProgress, "Draco compression", Max(1, int(theMeshes.size()))),
|
||||
myDracoEncoder(&theDracoEncoder),
|
||||
myRanges(0, int(theMeshes.size()) - 1),
|
||||
myMeshes(&theMeshes),
|
||||
myEncoderBuffers(&theEncoderBuffers)
|
||||
{
|
||||
for (int anIndex = 0; anIndex != int(theMeshes.size()); ++anIndex)
|
||||
{
|
||||
myRanges.SetValue(anIndex, myProgress.Next());
|
||||
}
|
||||
}
|
||||
|
||||
void operator () (int theMeshIndex) const
|
||||
{
|
||||
const std::shared_ptr<RWGltf_CafWriter::Mesh>& aCurrentMesh = myMeshes->at(theMeshIndex);
|
||||
if (aCurrentMesh->NodesVec.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Message_ProgressScope aScope(myRanges[theMeshIndex], NULL, 1);
|
||||
|
||||
draco::Mesh aMesh;
|
||||
writeNodesToDracoMesh (aMesh, aCurrentMesh->NodesVec);
|
||||
|
||||
if (!aCurrentMesh->NormalsVec.empty())
|
||||
{
|
||||
writeNormalsToDracoMesh (aMesh, aCurrentMesh->NormalsVec);
|
||||
}
|
||||
|
||||
if (!aCurrentMesh->TexCoordsVec.empty())
|
||||
{
|
||||
writeTexCoordsToDracoMesh (aMesh, aCurrentMesh->TexCoordsVec);
|
||||
}
|
||||
|
||||
writeIndicesToDracoMesh (aMesh, aCurrentMesh->IndicesVec);
|
||||
|
||||
std::shared_ptr<draco::EncoderBuffer> anEncoderBuffer = std::make_shared<draco::EncoderBuffer>();
|
||||
draco::Status aStatus = myDracoEncoder->EncodeMeshToBuffer (aMesh, anEncoderBuffer.get());
|
||||
if (aStatus.ok())
|
||||
{
|
||||
myEncoderBuffers->at(theMeshIndex) = anEncoderBuffer;
|
||||
}
|
||||
|
||||
aScope.Next();
|
||||
}
|
||||
|
||||
private:
|
||||
Message_ProgressScope myProgress;
|
||||
draco::Encoder* myDracoEncoder;
|
||||
NCollection_Array1<Message_ProgressRange> myRanges;
|
||||
const std::vector<std::shared_ptr<RWGltf_CafWriter::Mesh>>* myMeshes;
|
||||
std::vector<std::shared_ptr<draco::EncoderBuffer>>* myEncoderBuffers;
|
||||
};
|
||||
#endif
|
||||
|
||||
//================================================================
|
||||
// Function : Constructor
|
||||
// Purpose :
|
||||
@@ -183,7 +252,8 @@ RWGltf_CafWriter::RWGltf_CafWriter (const TCollection_AsciiString& theFile,
|
||||
myToEmbedTexturesInGlb (true),
|
||||
myToMergeFaces (false),
|
||||
myToSplitIndices16 (false),
|
||||
myBinDataLen64 (0)
|
||||
myBinDataLen64 (0),
|
||||
myToParallel (false)
|
||||
{
|
||||
myCSTrsf.SetOutputLengthUnit (1.0); // meters
|
||||
myCSTrsf.SetOutputCoordinateSystem (RWMesh_CoordinateSystem_glTF);
|
||||
@@ -535,6 +605,8 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument
|
||||
myBinDataMap.Clear();
|
||||
myBinDataLen64 = 0;
|
||||
|
||||
Message_ProgressScope aScope(theProgress, "Write binary data", myDracoParameters.DracoCompression ? 2 : 1);
|
||||
|
||||
const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
|
||||
std::shared_ptr<std::ostream> aBinFile = aFileSystem->OpenOStream (myBinFileNameFull, std::ios::out | std::ios::binary);
|
||||
if (aBinFile.get() == NULL
|
||||
@@ -544,7 +616,7 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument
|
||||
return false;
|
||||
}
|
||||
|
||||
Message_ProgressScope aPSentryBin (theProgress, "Binary data", 4);
|
||||
Message_ProgressScope aPSentryBin (aScope.Next(), "Binary data", 4);
|
||||
const RWGltf_GltfArrayType anArrTypes[4] =
|
||||
{
|
||||
RWGltf_GltfArrayType_Position,
|
||||
@@ -795,7 +867,6 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument
|
||||
#ifdef HAVE_DRACO
|
||||
OSD_Timer aDracoTimer;
|
||||
aDracoTimer.Start();
|
||||
int aBuffId = 0;
|
||||
draco::Encoder aDracoEncoder;
|
||||
aDracoEncoder.SetAttributeQuantization (draco::GeometryAttribute::POSITION, myDracoParameters.QuantizePositionBits);
|
||||
aDracoEncoder.SetAttributeQuantization (draco::GeometryAttribute::NORMAL, myDracoParameters.QuantizeNormalBits);
|
||||
@@ -803,38 +874,23 @@ bool RWGltf_CafWriter::writeBinData (const Handle(TDocStd_Document)& theDocument
|
||||
aDracoEncoder.SetAttributeQuantization (draco::GeometryAttribute::COLOR, myDracoParameters.QuantizeColorBits);
|
||||
aDracoEncoder.SetAttributeQuantization (draco::GeometryAttribute::GENERIC, myDracoParameters.QuantizeGenericBits);
|
||||
aDracoEncoder.SetSpeedOptions (myDracoParameters.CompressionLevel, myDracoParameters.CompressionLevel);
|
||||
for (size_t aMeshInd = 0; aMeshInd != aMeshes.size(); ++aMeshInd)
|
||||
|
||||
std::vector<std::shared_ptr<draco::EncoderBuffer>> anEncoderBuffers(aMeshes.size());
|
||||
DracoEncodingFunctor aFunctor (aScope.Next(), aDracoEncoder, aMeshes, anEncoderBuffers);
|
||||
OSD_Parallel::For (0, int(aMeshes.size()), aFunctor, !myToParallel);
|
||||
|
||||
for (size_t aBuffInd = 0; aBuffInd != anEncoderBuffers.size(); ++aBuffInd)
|
||||
{
|
||||
const std::shared_ptr<RWGltf_CafWriter::Mesh>& aCurrentMesh = aMeshes[aMeshInd];
|
||||
if (aCurrentMesh->NodesVec.empty())
|
||||
if (anEncoderBuffers.at(aBuffInd).get() == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
draco::Mesh aDracoMesh;
|
||||
writeNodesToDracoMesh (aDracoMesh, aCurrentMesh->NodesVec);
|
||||
if (!aCurrentMesh->NormalsVec.empty())
|
||||
{
|
||||
writeNormalsToDracoMesh (aDracoMesh, aCurrentMesh->NormalsVec);
|
||||
}
|
||||
if (!aCurrentMesh->TexCoordsVec.empty())
|
||||
{
|
||||
writeTexCoordsToDracoMesh (aDracoMesh, aCurrentMesh->TexCoordsVec);
|
||||
}
|
||||
writeIndicesToDracoMesh (aDracoMesh, aCurrentMesh->IndicesVec);
|
||||
|
||||
draco::EncoderBuffer anEncoderBuff;
|
||||
draco::Status aStatus = aDracoEncoder.EncodeMeshToBuffer (aDracoMesh, &anEncoderBuff);
|
||||
if (!aStatus.ok())
|
||||
{
|
||||
Message::SendFail (TCollection_AsciiString("Error: mesh cannot be encoded in draco buffer."));
|
||||
Message::SendFail(TCollection_AsciiString("Error: mesh not encoded in draco buffer."));
|
||||
return false;
|
||||
}
|
||||
|
||||
RWGltf_GltfBufferView aBuffViewDraco;
|
||||
aBuffViewDraco.Id = aBuffId++;
|
||||
aBuffViewDraco.Id = (int)aBuffInd;
|
||||
aBuffViewDraco.ByteOffset = aBinFile->tellp();
|
||||
aBinFile->write (anEncoderBuff.data(), std::streamsize(anEncoderBuff.size()));
|
||||
const draco::EncoderBuffer& anEncoderBuff = *anEncoderBuffers.at(aBuffInd);
|
||||
aBinFile->write(anEncoderBuff.data(), std::streamsize(anEncoderBuff.size()));
|
||||
if (!aBinFile->good())
|
||||
{
|
||||
Message::SendFail (TCollection_AsciiString("File '") + myBinFileNameFull + "' cannot be written");
|
||||
|
@@ -125,6 +125,12 @@ public:
|
||||
//! May reduce binary data size thanks to smaller triangle indexes.
|
||||
void SetSplitIndices16 (bool theToSplit) { myToSplitIndices16 = theToSplit; }
|
||||
|
||||
//! Return TRUE if multithreaded optimizations are allowed; FALSE by default.
|
||||
bool ToParallel() const { return myToParallel; }
|
||||
|
||||
//! Setup multithreaded execution.
|
||||
void SetParallel (bool theToParallel) { myToParallel = theToParallel; }
|
||||
|
||||
//! Return Draco parameters
|
||||
const RWGltf_DracoParameters& CompressionParameters() const { return myDracoParameters; }
|
||||
|
||||
@@ -397,6 +403,7 @@ protected:
|
||||
int64_t myBinDataLen64; //!< length of binary file
|
||||
|
||||
std::vector<RWGltf_GltfBufferView> myBuffViewsDraco; //!< vector of buffers view with compression data
|
||||
Standard_Boolean myToParallel; //!< flag to use multithreading; FALSE by default
|
||||
RWGltf_DracoParameters myDracoParameters; //!< Draco parameters
|
||||
};
|
||||
|
||||
|
@@ -56,14 +56,6 @@ bool RWPly_ConfigurationNode::Load(const Handle(DE_ConfigurationContext)& theRes
|
||||
InternalParameters.FileCS =
|
||||
(RWMesh_CoordinateSystem)(theResource->IntegerVal("file.cs", (int)InternalParameters.SystemCS, aScope) % 2);
|
||||
|
||||
InternalParameters.WritePntSet =
|
||||
theResource->BooleanVal("write.pnt.set", InternalParameters.WritePntSet, aScope);
|
||||
InternalParameters.WriteDistance =
|
||||
theResource->RealVal("write.distance", InternalParameters.WriteDistance, aScope);
|
||||
InternalParameters.WriteDensity =
|
||||
theResource->RealVal("write.density", InternalParameters.WriteDensity, aScope);
|
||||
InternalParameters.WriteTolerance =
|
||||
theResource->RealVal("write.tolerance", InternalParameters.WriteTolerance, aScope);
|
||||
InternalParameters.WriteNormals =
|
||||
theResource->BooleanVal("write.normals", InternalParameters.WriteNormals, aScope);
|
||||
InternalParameters.WriteColors =
|
||||
@@ -118,30 +110,6 @@ TCollection_AsciiString RWPly_ConfigurationNode::Save() const
|
||||
aResult += "!Write parameters:\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Flag for write point cloud instead without triangulation indices\n";
|
||||
aResult += "!Default value: 0(false). Available values: 0(false), 1(true)\n";
|
||||
aResult += aScope + "write.pnt.set :\t " + InternalParameters.WritePntSet + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Distance from shape into the range [0, Value]\n";
|
||||
aResult += "!Default value: 0. Available values: [0, Value]\n";
|
||||
aResult += aScope + "write.distance :\t " + InternalParameters.WriteDistance + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Density of points to generate randomly on surface\n";
|
||||
aResult += "!Default value: 2.e+100. Available values: [0, inf]\n";
|
||||
aResult += aScope + "write.density :\t " + InternalParameters.WriteDensity + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Internal tolerance\n";
|
||||
aResult += "!Default value: 1.e-7. Available values: [0, inf]\n";
|
||||
aResult += aScope + "write.tolerance :\t " + InternalParameters.WriteTolerance + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Flag for write normals\n";
|
||||
aResult += "!Default value: 1(true). Available values: 0(false), 1(true)\n";
|
||||
|
@@ -94,10 +94,6 @@ public:
|
||||
RWMesh_CoordinateSystem SystemCS = RWMesh_CoordinateSystem_Zup; //!< System origin coordinate system to perform conversion into during read
|
||||
RWMesh_CoordinateSystem FileCS = RWMesh_CoordinateSystem_Yup; //!< File origin coordinate system to perform conversion during read
|
||||
// Writing
|
||||
bool WritePntSet = false; //!< Flag for write point cloud instead without triangulation indices
|
||||
double WriteDistance = 0.0; //!< Distance from shape into the range [0, Value]
|
||||
double WriteDensity = Precision::Infinite(); //!< Density of points to generate randomly on surface
|
||||
double WriteTolerance = Precision::Confusion(); //!< Internal tolerance
|
||||
bool WriteNormals = true; //!< Flag for write normals
|
||||
bool WriteColors = true; //!< Flag for write colors
|
||||
bool WriteTexCoords = false; //!< Flag for write UV / texture coordinates
|
||||
|
@@ -14,7 +14,6 @@
|
||||
#include <RWPly_Provider.hxx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepLib_PointCloudShape.hxx>
|
||||
#include <DE_Wrapper.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <RWPly_ConfigurationNode.hxx>
|
||||
@@ -80,122 +79,34 @@ bool RWPly_Provider::Write(const TCollection_AsciiString& thePath,
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (aNode->InternalParameters.WritePntSet)
|
||||
TColStd_IndexedDataMapOfStringString aFileInfo;
|
||||
if (!aNode->InternalParameters.WriteAuthor.IsEmpty())
|
||||
{
|
||||
class PointCloudPlyWriter : public BRepLib_PointCloudShape, public RWPly_PlyWriterContext
|
||||
{
|
||||
public:
|
||||
PointCloudPlyWriter(Standard_Real theTol)
|
||||
: BRepLib_PointCloudShape(TopoDS_Shape(), theTol)
|
||||
{}
|
||||
|
||||
void AddFaceColor(const TopoDS_Shape& theFace, const Graphic3d_Vec4ub& theColor)
|
||||
{
|
||||
myFaceColor.Bind(theFace, theColor);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void addPoint(const gp_Pnt& thePoint,
|
||||
const gp_Vec& theNorm,
|
||||
const gp_Pnt2d& theUV,
|
||||
const TopoDS_Shape& theFace)
|
||||
{
|
||||
Graphic3d_Vec4ub aColor;
|
||||
myFaceColor.Find(theFace, aColor);
|
||||
RWPly_PlyWriterContext::WriteVertex(thePoint,
|
||||
Graphic3d_Vec3((float)theNorm.X(), (float)theNorm.Y(), (float)theNorm.Z()),
|
||||
Graphic3d_Vec2((float)theUV.X(), (float)theUV.Y()),
|
||||
aColor);
|
||||
}
|
||||
|
||||
private:
|
||||
NCollection_DataMap<TopoDS_Shape, Graphic3d_Vec4ub> myFaceColor;
|
||||
};
|
||||
|
||||
PointCloudPlyWriter aPlyCtx(aNode->InternalParameters.WriteTolerance);
|
||||
aPlyCtx.SetNormals(aNode->InternalParameters.WriteNormals);
|
||||
aPlyCtx.SetColors(aNode->InternalParameters.WriteColors);
|
||||
aPlyCtx.SetTexCoords(aNode->InternalParameters.WriteTexCoords);
|
||||
|
||||
TopoDS_Compound aComp;
|
||||
BRep_Builder().MakeCompound(aComp);
|
||||
for (XCAFPrs_DocumentExplorer aDocExplorer(theDocument, aRootLabels, XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes);
|
||||
aDocExplorer.More(); aDocExplorer.Next())
|
||||
{
|
||||
const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
|
||||
for (RWMesh_FaceIterator aFaceIter(aDocNode.RefLabel, aDocNode.Location, true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next())
|
||||
{
|
||||
BRep_Builder().Add(aComp, aFaceIter.Face());
|
||||
Graphic3d_Vec4ub aColorVec(255);
|
||||
if (aFaceIter.HasFaceColor())
|
||||
{
|
||||
Graphic3d_Vec4 aColorF = aFaceIter.FaceColor();
|
||||
aColorVec.SetValues((unsigned char)int(aColorF.r() * 255.0f),
|
||||
(unsigned char)int(aColorF.g() * 255.0f),
|
||||
(unsigned char)int(aColorF.b() * 255.0f),
|
||||
(unsigned char)int(aColorF.a() * 255.0f));
|
||||
}
|
||||
aPlyCtx.AddFaceColor(aFaceIter.Face(), aColorVec);
|
||||
}
|
||||
}
|
||||
aPlyCtx.SetShape(aComp);
|
||||
Standard_Integer aNbPoints = aNode->InternalParameters.WriteDensity > 0
|
||||
? aPlyCtx.NbPointsByDensity(aNode->InternalParameters.WriteDensity)
|
||||
: aPlyCtx.NbPointsByTriangulation();
|
||||
if (aNbPoints <= 0)
|
||||
{
|
||||
Message::SendFail() << "Error in the RWPly_Provider during writing the file " <<
|
||||
thePath << "\t: Incorrect number of points";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aPlyCtx.Open(thePath)
|
||||
|| !aPlyCtx.WriteHeader(aNbPoints, 0, TColStd_IndexedDataMapOfStringString()))
|
||||
{
|
||||
Message::SendFail() << "Error in the RWPly_Provider during writing the file " << thePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
Standard_Boolean isDone = aNode->InternalParameters.WriteDensity > 0
|
||||
? aPlyCtx.GeneratePointsByDensity(aNode->InternalParameters.WriteDensity)
|
||||
: aPlyCtx.GeneratePointsByTriangulation();
|
||||
if (!isDone)
|
||||
{
|
||||
Message::SendFail() << "Error in the RWPly_Provider during writing the file "
|
||||
<< thePath << "\t: Error during generating point process";
|
||||
return false;
|
||||
}
|
||||
aFileInfo.Add("Author", aNode->InternalParameters.WriteAuthor);
|
||||
}
|
||||
else
|
||||
if (!aNode->InternalParameters.WriteComment.IsEmpty())
|
||||
{
|
||||
TColStd_IndexedDataMapOfStringString aFileInfo;
|
||||
if (!aNode->InternalParameters.WriteAuthor.IsEmpty())
|
||||
{
|
||||
aFileInfo.Add("Author", aNode->InternalParameters.WriteAuthor);
|
||||
}
|
||||
if (!aNode->InternalParameters.WriteComment.IsEmpty())
|
||||
{
|
||||
aFileInfo.Add("Comments", aNode->InternalParameters.WriteComment);
|
||||
}
|
||||
RWMesh_CoordinateSystemConverter aConverter;
|
||||
aConverter.SetInputLengthUnit(aNode->GlobalParameters.LengthUnit / 1000);
|
||||
aConverter.SetInputCoordinateSystem(aNode->InternalParameters.SystemCS);
|
||||
aConverter.SetOutputLengthUnit(aNode->InternalParameters.FileLengthUnit);
|
||||
aConverter.SetOutputCoordinateSystem(aNode->InternalParameters.FileCS);
|
||||
|
||||
RWPly_CafWriter aPlyCtx(thePath);
|
||||
aPlyCtx.SetNormals(aNode->InternalParameters.WriteNormals);
|
||||
aPlyCtx.SetColors(aNode->InternalParameters.WriteColors);
|
||||
aPlyCtx.SetTexCoords(aNode->InternalParameters.WriteTexCoords);
|
||||
aPlyCtx.SetPartId(aNode->InternalParameters.WritePartId);
|
||||
aPlyCtx.SetFaceId(aNode->InternalParameters.WriteFaceId);
|
||||
if (!aPlyCtx.Perform(theDocument, aFileInfo, theProgress))
|
||||
{
|
||||
Message::SendFail() << "Error in the RWPly_Provider during writing the file "
|
||||
<< thePath << "\t: Cannot perform the document";
|
||||
return false;
|
||||
}
|
||||
aFileInfo.Add("Comments", aNode->InternalParameters.WriteComment);
|
||||
}
|
||||
RWMesh_CoordinateSystemConverter aConverter;
|
||||
aConverter.SetInputLengthUnit(aNode->GlobalParameters.LengthUnit / 1000);
|
||||
aConverter.SetInputCoordinateSystem(aNode->InternalParameters.SystemCS);
|
||||
aConverter.SetOutputLengthUnit(aNode->InternalParameters.FileLengthUnit);
|
||||
aConverter.SetOutputCoordinateSystem(aNode->InternalParameters.FileCS);
|
||||
|
||||
RWPly_CafWriter aPlyCtx(thePath);
|
||||
aPlyCtx.SetNormals(aNode->InternalParameters.WriteNormals);
|
||||
aPlyCtx.SetColors(aNode->InternalParameters.WriteColors);
|
||||
aPlyCtx.SetTexCoords(aNode->InternalParameters.WriteTexCoords);
|
||||
aPlyCtx.SetPartId(aNode->InternalParameters.WritePartId);
|
||||
aPlyCtx.SetFaceId(aNode->InternalParameters.WriteFaceId);
|
||||
if (!aPlyCtx.Perform(theDocument, aFileInfo, theProgress))
|
||||
{
|
||||
Message::SendFail() << "Error in the RWPly_Provider during writing the file "
|
||||
<< thePath << "\t: Cannot perform the document";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -99,11 +99,42 @@ namespace
|
||||
return aPoly;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Clear()
|
||||
{
|
||||
myNodes.Clear();
|
||||
myTriangles.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
NCollection_Vector<gp_XYZ> myNodes;
|
||||
NCollection_Vector<Poly_Triangle> myTriangles;
|
||||
};
|
||||
|
||||
class MultiDomainReader : public Reader
|
||||
{
|
||||
public:
|
||||
//! Add new solid
|
||||
//! Add triangulation to triangulation list for multi-domain case
|
||||
virtual void AddSolid() Standard_OVERRIDE
|
||||
{
|
||||
if (Handle(Poly_Triangulation) aCurrentTri = GetTriangulation())
|
||||
{
|
||||
myTriangulationList.Append(aCurrentTri);
|
||||
}
|
||||
Clear();
|
||||
}
|
||||
|
||||
//! Returns triangulation list for multi-domain case
|
||||
NCollection_Sequence<Handle(Poly_Triangulation)>& ChangeTriangulationList()
|
||||
{
|
||||
return myTriangulationList;
|
||||
}
|
||||
|
||||
private:
|
||||
NCollection_Sequence<Handle(Poly_Triangulation)> myTriangulationList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
@@ -122,6 +153,22 @@ Handle(Poly_Triangulation) RWStl::ReadFile (const Standard_CString theFile,
|
||||
return aReader.GetTriangulation();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ReadFile
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
void RWStl::ReadFile(const Standard_CString theFile,
|
||||
const Standard_Real theMergeAngle,
|
||||
NCollection_Sequence<Handle(Poly_Triangulation)>& theTriangList,
|
||||
const Message_ProgressRange& theProgress)
|
||||
{
|
||||
MultiDomainReader aReader;
|
||||
aReader.SetMergeAngle (theMergeAngle);
|
||||
aReader.Read (theFile, theProgress);
|
||||
theTriangList.Clear();
|
||||
theTriangList.Append (aReader.ChangeTriangulationList());
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ReadFile
|
||||
//purpose :
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <Message_ProgressScope.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
//! This class provides methods to read and write triangulation from / to the STL files.
|
||||
class RWStl
|
||||
@@ -61,7 +62,17 @@ public:
|
||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile,
|
||||
const Standard_Real theMergeAngle,
|
||||
const Message_ProgressRange& theProgress = Message_ProgressRange());
|
||||
|
||||
|
||||
//! Read specified STL file and fills triangulation list for multi-domain case.
|
||||
//! @param[in] theFile file path to read
|
||||
//! @param[in] theMergeAngle maximum angle in radians between triangles to merge equal nodes; M_PI/2 means ignore angle
|
||||
//! @param[out] theTriangList triangulation list for multi-domain case
|
||||
//! @param[in] theProgress progress indicator
|
||||
Standard_EXPORT static void ReadFile(const Standard_CString theFile,
|
||||
const Standard_Real theMergeAngle,
|
||||
NCollection_Sequence<Handle(Poly_Triangulation)>& theTriangList,
|
||||
const Message_ProgressRange& theProgress = Message_ProgressRange());
|
||||
|
||||
//! Read triangulation from a binary STL file
|
||||
//! In case of error, returns Null handle.
|
||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadBinary (const OSD_Path& thePath,
|
||||
|
@@ -180,6 +180,7 @@ Standard_Boolean RWStl_Reader::Read (const char* theFile,
|
||||
}
|
||||
}
|
||||
*aStream >> std::ws; // skip any white spaces
|
||||
AddSolid();
|
||||
}
|
||||
return ! aStream->fail();
|
||||
}
|
||||
@@ -300,6 +301,11 @@ Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream,
|
||||
|
||||
// skip header "solid ..."
|
||||
aLine = theBuffer.ReadLine (theStream, aLineLen);
|
||||
// skip empty lines
|
||||
while (aLine && !*aLine)
|
||||
{
|
||||
aLine = theBuffer.ReadLine (theStream, aLineLen);
|
||||
}
|
||||
if (aLine == NULL)
|
||||
{
|
||||
Message::SendFail ("Error: premature end of file");
|
||||
|
@@ -39,7 +39,8 @@ public:
|
||||
Standard_EXPORT RWStl_Reader();
|
||||
|
||||
//! Reads data from STL file (either binary or Ascii).
|
||||
//! This function supports reading multi-domain STL files formed by concatenation of several "plain" files.
|
||||
//! This function supports reading multi-domain STL files formed by concatenation
|
||||
//! of several "plain" files.
|
||||
//! The mesh nodes are not merged between domains.
|
||||
//! Unicode paths can be given in UTF-8 encoding.
|
||||
//! Format is recognized automatically by analysis of the file header.
|
||||
@@ -84,6 +85,9 @@ public:
|
||||
//! Should create new triangle built on specified nodes in the target model.
|
||||
virtual void AddTriangle (Standard_Integer theN1, Standard_Integer theN2, Standard_Integer theN3) = 0;
|
||||
|
||||
//! Callback function to be implemented in descendant.
|
||||
//! Should create a new triangulation for a solid in multi-domain case.
|
||||
virtual void AddSolid() {}
|
||||
public:
|
||||
|
||||
//! Return merge tolerance; M_PI/2 by default - all nodes are merged regardless angle between triangles.
|
||||
|
@@ -3365,17 +3365,17 @@ static void setDimObjectToXCAF(const Handle(Standard_Transient)& theEnt,
|
||||
if (anUnit.IsNull()) continue;
|
||||
if (!(anUnit.CaseNum(anUnit.Value()) == 1)) continue;
|
||||
Handle(StepBasic_NamedUnit) NU = anUnit.NamedUnit();
|
||||
STEPConstruct_UnitContext anUnitCtx;
|
||||
anUnitCtx.ComputeFactors(NU);
|
||||
if (aMWU->IsKind(STANDARD_TYPE(StepBasic_LengthMeasureWithUnit)) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI)))
|
||||
{
|
||||
aVal = aVal * anUnitCtx.LengthFactor();
|
||||
}
|
||||
else if (aMWU->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) ||
|
||||
STEPConstruct_UnitContext anUnitCtxUpperBound;
|
||||
anUnitCtxUpperBound.ComputeFactors(NU);
|
||||
if (aMWU->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI)))
|
||||
{
|
||||
convertAngleValue(anUnitCtx, aVal);
|
||||
convertAngleValue(anUnitCtxUpperBound, aVal);
|
||||
}
|
||||
else if ((aMWU->IsKind(STANDARD_TYPE(StepBasic_MeasureWithUnit)) && anUnitCtxUpperBound.LengthFactor() > 0.) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI)))
|
||||
{
|
||||
aVal = aVal * anUnitCtxUpperBound.LengthFactor();
|
||||
}
|
||||
aDim3 = aVal;
|
||||
|
||||
@@ -3401,16 +3401,17 @@ static void setDimObjectToXCAF(const Handle(Standard_Transient)& theEnt,
|
||||
if (anUnit.IsNull()) continue;
|
||||
if (!(anUnit.CaseNum(anUnit.Value()) == 1)) continue;
|
||||
NU = anUnit.NamedUnit();
|
||||
anUnitCtx.ComputeFactors(NU);
|
||||
if (aMWU->IsKind(STANDARD_TYPE(StepBasic_LengthMeasureWithUnit)) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI)))
|
||||
{
|
||||
aVal = aVal * anUnitCtx.LengthFactor();
|
||||
}
|
||||
else if (aMWU->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) ||
|
||||
STEPConstruct_UnitContext anUnitCtxLowerBound;
|
||||
anUnitCtxLowerBound.ComputeFactors(NU);
|
||||
if (aMWU->IsKind(STANDARD_TYPE(StepBasic_PlaneAngleMeasureWithUnit)) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI)))
|
||||
{
|
||||
convertAngleValue(anUnitCtx, aVal);
|
||||
convertAngleValue(anUnitCtxLowerBound, aVal);
|
||||
}
|
||||
else if ((aMWU->IsKind(STANDARD_TYPE(StepBasic_MeasureWithUnit)) && anUnitCtxLowerBound.LengthFactor() > 0.) ||
|
||||
aMWU->IsKind(STANDARD_TYPE(StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI)))
|
||||
{
|
||||
aVal = aVal * anUnitCtxLowerBound.LengthFactor();
|
||||
}
|
||||
aDim2 = Abs(aVal);
|
||||
}
|
||||
|
@@ -341,6 +341,43 @@ void STEPControl_ActorWrite::mergeInfoForNM(const Handle(Transfer_FinderProcess)
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : separateShapeToSoloVertex
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean STEPControl_ActorWrite::separateShapeToSoloVertex(const TopoDS_Shape& theShape,
|
||||
TopTools_SequenceOfShape& theVertices)
|
||||
{
|
||||
if (theShape.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
switch (theShape.ShapeType())
|
||||
{
|
||||
case TopAbs_COMPOUND:
|
||||
{
|
||||
for (TopoDS_Iterator anIter(theShape); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (!separateShapeToSoloVertex(anIter.Value(), theVertices))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TopAbs_VERTEX:
|
||||
{
|
||||
theVertices.Append(theShape);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
theVertices.Clear();
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetMode
|
||||
@@ -814,42 +851,49 @@ Handle(Transfer_Binder) STEPControl_ActorWrite::TransferShape
|
||||
|
||||
// create a list of items to translate
|
||||
Handle(TopTools_HSequenceOfShape) RepItemSeq = new TopTools_HSequenceOfShape();
|
||||
|
||||
Standard_Boolean isSeparateVertices =
|
||||
|
||||
Standard_Boolean isSeparateVertices =
|
||||
Interface_Static::IVal("write.step.vertex.mode") == 0;//bug 23950
|
||||
// PTV 16.09.2002 OCC725 separate shape from solo vertices.
|
||||
Standard_Boolean isOnlyVertices = Standard_False;
|
||||
if (theShape.ShapeType() == TopAbs_COMPOUND) {
|
||||
Standard_Integer countVrtx = 0;
|
||||
Standard_Integer countSh = 0;
|
||||
if (theShape.ShapeType() == TopAbs_COMPOUND && isSeparateVertices)
|
||||
{
|
||||
TopoDS_Compound aNewShape, aCompOfVrtx;
|
||||
BRep_Builder aB;
|
||||
aB.MakeCompound(aNewShape);
|
||||
aB.MakeCompound(aCompOfVrtx);
|
||||
TopoDS_Iterator anCompIt(theShape);
|
||||
if (isSeparateVertices) {
|
||||
for (; anCompIt.More(); anCompIt.Next()) {
|
||||
TopoDS_Shape aCurSh = anCompIt.Value();
|
||||
if (aCurSh.ShapeType() != TopAbs_VERTEX) {
|
||||
aB.Add(aNewShape, aCurSh);
|
||||
countSh++;
|
||||
BRep_Builder aBuilder;
|
||||
aBuilder.MakeCompound(aNewShape);
|
||||
aBuilder.MakeCompound(aCompOfVrtx);
|
||||
TopTools_SequenceOfShape aVertices;
|
||||
isOnlyVertices = separateShapeToSoloVertex(theShape, aVertices);
|
||||
if (!isOnlyVertices)
|
||||
{
|
||||
for (TopoDS_Iterator anCompIt(theShape); anCompIt.More(); anCompIt.Next())
|
||||
{
|
||||
const TopoDS_Shape& aCurSh = anCompIt.Value();
|
||||
TopTools_SequenceOfShape aVerticesOfSubSh;
|
||||
if (separateShapeToSoloVertex(aCurSh, aVerticesOfSubSh))
|
||||
{
|
||||
aVertices.Append(aVerticesOfSubSh);
|
||||
}
|
||||
else {
|
||||
aB.Add(aCompOfVrtx, aCurSh);
|
||||
countVrtx++;
|
||||
else
|
||||
{
|
||||
aBuilder.Add(aNewShape, aCurSh);
|
||||
}
|
||||
}
|
||||
// replace the shapes
|
||||
if (countSh)
|
||||
theShape = aNewShape;
|
||||
if (countVrtx)
|
||||
RepItemSeq->Append(aCompOfVrtx);
|
||||
if (countSh == 0)
|
||||
isOnlyVertices = Standard_True;
|
||||
theShape = aNewShape;
|
||||
}
|
||||
}
|
||||
|
||||
if (theShape.ShapeType() == TopAbs_COMPOUND) {
|
||||
for (TopTools_HSequenceOfShape::Iterator anIterV(aVertices);
|
||||
anIterV.More(); anIterV.Next())
|
||||
{
|
||||
aBuilder.Add(aCompOfVrtx, anIterV.Value());
|
||||
}
|
||||
if (!aVertices.IsEmpty())
|
||||
{
|
||||
RepItemSeq->Append(aCompOfVrtx);
|
||||
}
|
||||
}
|
||||
|
||||
if (theShape.ShapeType() == TopAbs_COMPOUND)
|
||||
{
|
||||
TopExp_Explorer SolidExp, ShellExp, FaceExp;
|
||||
if (mymode != STEPControl_GeometricCurveSet) {
|
||||
for (SolidExp.Init(theShape, TopAbs_SOLID);
|
||||
|
@@ -117,6 +117,15 @@ private:
|
||||
//! bind already written shared faces to STEP entity for non-manifold
|
||||
Standard_EXPORT void mergeInfoForNM(const Handle(Transfer_FinderProcess)& theFP, const Handle(Standard_Transient) &theInfo) const;
|
||||
|
||||
//! Gets sequence of vertices of all compounds level by recursive
|
||||
//! @param[in] theShape shape to iterate, checked for compound type and sub shapes vertex type
|
||||
//! @param[out] theVertices sequence of found vertices via recursively iterate of shape
|
||||
//! @return TRUE if one or more vertex was found and all shapes were compound or vertex
|
||||
Standard_Boolean separateShapeToSoloVertex(const TopoDS_Shape& theShape,
|
||||
TopTools_SequenceOfShape& theVertices);
|
||||
|
||||
|
||||
|
||||
Standard_Integer mygroup;
|
||||
Standard_Real mytoler;
|
||||
STEPConstruct_ContextTool myContext;
|
||||
|
@@ -141,13 +141,18 @@ static Standard_Integer tolerance
|
||||
static Standard_Integer projface
|
||||
(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
||||
{
|
||||
if (argc < 4) { di<<"Give FACE name and X Y [Z]\n"; return 1 /* Error */; }
|
||||
if (argc < 4)
|
||||
{
|
||||
di << "Give FACE name and X Y [Z]\n";
|
||||
return 1;
|
||||
}
|
||||
Standard_CString arg1 = argv[1];
|
||||
TopoDS_Shape Shape = DBRep::Get(arg1);
|
||||
if (Shape.IsNull()) { di<<"Shape unknown : "<<arg1<<"\n"; return 1 /* Error */; }
|
||||
if (Shape.ShapeType() != TopAbs_FACE) { di<<"Not a face\n"; return 1 /* Error */; }
|
||||
TopoDS_Face F = TopoDS::Face (Shape);
|
||||
Handle(Geom_Surface) thesurf = BRep_Tool::Surface (F); // pas locface
|
||||
BRepTopAdaptor_FClass2d aClassifier (F, Precision::Confusion());
|
||||
// On y va
|
||||
Standard_Real X,Y,Z,U,V;
|
||||
X = U = Draw::Atof (argv[2]);
|
||||
@@ -167,28 +172,52 @@ static Standard_Integer projface
|
||||
|
||||
GeomAPI_ProjectPointOnSurf proj(P3D, thesurf, uf-du, ul+du, vf-dv, vl+dv);
|
||||
Standard_Integer sol, nPSurf = proj.NbPoints();
|
||||
di<<" Found "<<nPSurf<<" Points\n";
|
||||
Standard_Integer anIndSol = 0, anIndMin = 0;
|
||||
Standard_Real aMinDist = RealLast();
|
||||
for (sol = 1; sol <= nPSurf; sol ++) {
|
||||
di<<"n0 "<<sol<<" Distance "<<proj.Distance(sol);
|
||||
|
||||
proj.Parameters(sol, U,V);
|
||||
di<<" U = "<<U<<" V = "<<V<<"\n";
|
||||
TopAbs_State aStatus = aClassifier.Perform (gp_Pnt2d (U,V));
|
||||
if (aStatus == TopAbs_OUT)
|
||||
continue;
|
||||
|
||||
anIndSol++;
|
||||
Standard_Real aDist = proj.Distance(sol);
|
||||
di << "n0 " << anIndSol << " Distance " << aDist;
|
||||
di << " U = " << U << " V = " << V << "\n";
|
||||
|
||||
if (aDist < aMinDist)
|
||||
{
|
||||
aMinDist = aDist;
|
||||
anIndMin = sol;
|
||||
}
|
||||
|
||||
// reprojection
|
||||
P3D = thesurf->Value (U,V);
|
||||
di<<" => reproj X = "<<P3D.X()<<" Y = "<<P3D.Y()<<" Z = "<<P3D.Z()<<"\n";
|
||||
}
|
||||
// Que donne ShapeTool ?
|
||||
P3D.SetCoord (X,Y,Z);
|
||||
Handle(ShapeAnalysis_Surface) su = new ShapeAnalysis_Surface(thesurf);
|
||||
gp_Pnt2d suval = su->ValueOfUV (P3D,BRep_Tool::Tolerance(F));
|
||||
suval.Coord(U,V);
|
||||
di<<"** ShapeAnalysis_Surface gives U = "<<U<<" V = "<<V<<"\n";
|
||||
P3D = thesurf->Value(U,V);
|
||||
di<<" => reproj X = "<<P3D.X()<<" Y = "<<P3D.Y()<<" Z = "<<P3D.Z()<<"\n";
|
||||
di<<" Found "<<anIndSol<<" Points\n";
|
||||
|
||||
} else {
|
||||
di<<" Point UV U = "<<U<<" V = "<<V<<"\n";
|
||||
gp_Pnt P3D = thesurf->Value(U,V);
|
||||
di<<" => proj X = "<<P3D.X()<<" Y = "<<P3D.Y()<<" Z = "<<P3D.Z()<<"\n";
|
||||
if (anIndMin != 0) //there is at least one suitable solution
|
||||
{
|
||||
di << "** Minimal distance to face = " << aMinDist << "\n";
|
||||
proj.Parameters(anIndMin, U,V);
|
||||
di << "** Solution of minimal distance: U = " << U << " V = " << V << "\n";
|
||||
P3D = thesurf->Value(U,V);
|
||||
di<<" => reproj X = "<<P3D.X()<<" Y = "<<P3D.Y()<<" Z = "<<P3D.Z()<<"\n";
|
||||
}
|
||||
}
|
||||
else //Check 2D point
|
||||
{
|
||||
di << " Point UV U = " << U << " V = " << V << "\n";
|
||||
TopAbs_State aStatus = aClassifier.Perform (gp_Pnt2d (U,V));
|
||||
if (aStatus == TopAbs_OUT)
|
||||
di << "does not belong to the face" << "\n";
|
||||
else
|
||||
{
|
||||
gp_Pnt P3D = thesurf->Value(U,V);
|
||||
di << " => proj X = " << P3D.X() << " Y = " << P3D.Y() << " Z = " << P3D.Z() << "\n";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1199,7 +1228,7 @@ Standard_Integer getanacurve(Draw_Interpretor& di,
|
||||
Standard_CString g = SWDRAW::GroupName();
|
||||
|
||||
theCommands.Add ("tolerance","shape [tolmin tolmax:real]", __FILE__,tolerance,g);
|
||||
theCommands.Add ("projface","nom_face X Y [Z]", __FILE__,projface,g);
|
||||
theCommands.Add ("projface","nom_face X Y [Z] - returns the closest orthogonal projection if exists", __FILE__,projface,g);
|
||||
theCommands.Add ("projcurve","nom_edge | curve3d | curve3d first last + X Y Z",
|
||||
__FILE__,projcurve,g);
|
||||
theCommands.Add("projpcurve", "edge face tol x y z [start_param]",
|
||||
|
@@ -16,195 +16,29 @@
|
||||
|
||||
#include <Select3D_SensitiveCircle.hxx>
|
||||
|
||||
#include <ElCLib.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Select3D_SensitiveTriangle.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle,Select3D_SensitivePoly)
|
||||
|
||||
namespace
|
||||
{
|
||||
static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle,
|
||||
const Standard_Integer theNbPnts)
|
||||
{
|
||||
// Check if number of points is invalid.
|
||||
// In this case myPolyg raises Standard_ConstructionError
|
||||
// exception (see constructor below).
|
||||
if (theNbPnts <= 0)
|
||||
return 0;
|
||||
|
||||
if (theCircle.Radius() > Precision::Confusion())
|
||||
return 2 * theNbPnts + 1;
|
||||
|
||||
// The radius is too small and circle degenerates into point
|
||||
return 1;
|
||||
}
|
||||
|
||||
//! Definition of circle polyline
|
||||
static void initCircle (Select3D_PointData& thePolygon,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Integer theNbPnts)
|
||||
{
|
||||
const Standard_Real aStep = (theU2 - theU1) / theNbPnts;
|
||||
const Standard_Real aRadius = theCircle.Radius();
|
||||
Standard_Integer aPntIdx = 0;
|
||||
Standard_Real aCurU = theU1;
|
||||
gp_Pnt aP1;
|
||||
gp_Vec aV1;
|
||||
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep)
|
||||
{
|
||||
ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1);
|
||||
thePolygon.SetPnt (aPntIdx++, aP1);
|
||||
|
||||
aV1.Normalize();
|
||||
const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius;
|
||||
thePolygon.SetPnt (aPntIdx++, aP2);
|
||||
}
|
||||
aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius());
|
||||
thePolygon.SetPnt (theNbPnts * 2, aP1);
|
||||
}
|
||||
}
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_SensitiveCircle (constructor)
|
||||
//purpose : Definition of a sensitive circle
|
||||
//=======================================================================
|
||||
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const Standard_Integer theNbPnts)
|
||||
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
|
||||
myCircle (theCircle),
|
||||
myStart (0.0),
|
||||
myEnd (2.0 * M_PI)
|
||||
{
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
myCenter3D = theCircle.Position().Location();
|
||||
if (myPolyg.Size() != 1)
|
||||
{
|
||||
initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
|
||||
}
|
||||
// Radius = 0.0
|
||||
else
|
||||
{
|
||||
myPolyg.SetPnt (0, theCircle.Position().Location());
|
||||
}
|
||||
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
SetSensitivityFactor (6);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_SensitiveCircle (constructor)
|
||||
//purpose : Definition of a sensitive arc
|
||||
//=======================================================================
|
||||
Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const Standard_Integer theNbPnts)
|
||||
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
|
||||
myCircle (theCircle),
|
||||
myStart (Min (theU1, theU2)),
|
||||
myEnd (Max (theU1, theU2))
|
||||
const Standard_Boolean theIsFilled)
|
||||
: Select3D_SensitiveEntity (theOwnerId)
|
||||
{
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
myCenter3D = theCircle.Position().Location();
|
||||
if (myPolyg.Size() != 1)
|
||||
{
|
||||
initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts);
|
||||
}
|
||||
else
|
||||
{
|
||||
myPolyg.SetPnt (0, theCircle.Position().Location());
|
||||
}
|
||||
myRadius = theCircle.Radius();
|
||||
myTrsf.SetTransformation (theCircle.Position(), gp::XOY());
|
||||
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
SetSensitivityFactor (6);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_SensitiveCircle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
|
||||
const Standard_Boolean theIsFilled)
|
||||
: Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
|
||||
myStart (0),
|
||||
myEnd (0)
|
||||
{
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
|
||||
if (myPolyg.Size() != 1)
|
||||
computeCenter3D();
|
||||
else
|
||||
myCenter3D = myPolyg.Pnt (0);
|
||||
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
SetSensitivityFactor (6);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select3D_SensitiveCircle
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const TColgp_Array1OfPnt& thePnts3d,
|
||||
const Standard_Boolean theIsFilled)
|
||||
: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled),
|
||||
myStart (0),
|
||||
myEnd (0)
|
||||
{
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
|
||||
if (myPolyg.Size() != 1)
|
||||
computeCenter3D();
|
||||
else
|
||||
myCenter3D = myPolyg.Pnt (0);
|
||||
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
SetSensitivityFactor (6);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : BVH
|
||||
// purpose : Builds BVH tree for a circle's edge segments if needed
|
||||
//=======================================================================
|
||||
void Select3D_SensitiveCircle::BVH()
|
||||
{
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
Select3D_SensitivePoly::BVH();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : ToBuildBVH
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Select3D_SensitiveCircle::ToBuildBVH() const
|
||||
{
|
||||
if (mySensType != Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
return Select3D_SensitivePoly::ToBuildBVH();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Matches
|
||||
// purpose : Checks whether the circle overlaps current selecting volume
|
||||
@@ -212,40 +46,26 @@ Standard_Boolean Select3D_SensitiveCircle::ToBuildBVH() const
|
||||
Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
{
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
const Standard_Boolean aIsFilled = mySensType == Select3D_TOS_INTERIOR;
|
||||
|
||||
if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point)
|
||||
{
|
||||
if (!Select3D_SensitivePoly::Matches (theMgr, thePickResult))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else if (mySensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
|
||||
Points3D (anArrayOfPnt);
|
||||
if (!theMgr.IsOverlapAllowed())
|
||||
{
|
||||
if (theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Polyline)
|
||||
{
|
||||
SelectBasics_PickResult aDummy;
|
||||
return theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), mySensType, aDummy);
|
||||
}
|
||||
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
|
||||
{
|
||||
if (!theMgr.OverlapsPoint (anArrayOfPnt->Value(aPntIdx)))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
bool isInside = true;
|
||||
return theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, &isInside) && isInside;
|
||||
}
|
||||
|
||||
if (!theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), Select3D_TOS_INTERIOR, thePickResult))
|
||||
else
|
||||
{
|
||||
return Standard_False;
|
||||
return theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, NULL);
|
||||
}
|
||||
thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr));
|
||||
}
|
||||
if (!theMgr.OverlapsCircle (myRadius, myTrsf, aIsFilled, thePickResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
thePickResult.SetDistToGeomCenter (theMgr.DistToGeometryCenter (CenterOfGeometry()));
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -254,81 +74,36 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
|
||||
//function : GetConnected
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected()
|
||||
{
|
||||
Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR;
|
||||
// Create a copy of this
|
||||
Handle(Select3D_SensitiveEntity) aNewEntity;
|
||||
// this was constructed using Handle(Geom_Circle)
|
||||
if (!Precision::IsInfinite (myCircle.Radius()))
|
||||
{
|
||||
if ((myEnd - myStart) > Precision::Confusion())
|
||||
{
|
||||
// Arc
|
||||
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Circle
|
||||
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled);
|
||||
}
|
||||
}
|
||||
// this was constructed using TColgp_Array1OfPnt
|
||||
else
|
||||
{
|
||||
Standard_Integer aSize = myPolyg.Size();
|
||||
TColgp_Array1OfPnt aPolyg (1, aSize);
|
||||
for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
|
||||
{
|
||||
aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1));
|
||||
}
|
||||
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled);
|
||||
}
|
||||
|
||||
Standard_Boolean anIsFilled = mySensType == Select3D_TOS_INTERIOR;
|
||||
Handle(Select3D_SensitiveEntity) aNewEntity = new Select3D_SensitiveCircle (myOwnerId,
|
||||
Circle(),
|
||||
anIsFilled);
|
||||
return aNewEntity;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : computeCenter3D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Select3D_SensitiveCircle::computeCenter3D()
|
||||
//==================================================
|
||||
// Function: BoundingBox
|
||||
// Purpose :
|
||||
//==================================================
|
||||
Select3D_BndBox3d Select3D_SensitiveCircle::BoundingBox()
|
||||
{
|
||||
gp_XYZ aCenter;
|
||||
Standard_Integer aNbPnts = myPolyg.Size();
|
||||
if (aNbPnts != 1)
|
||||
{
|
||||
// The mass of points system
|
||||
Standard_Integer aMass = aNbPnts - 1;
|
||||
// Find the circle barycenter
|
||||
for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex)
|
||||
{
|
||||
aCenter += myPolyg.Pnt(anIndex);
|
||||
}
|
||||
myCenter3D = aCenter / aMass;
|
||||
}
|
||||
else
|
||||
{
|
||||
myCenter3D = myPolyg.Pnt(0);
|
||||
}
|
||||
Graphic3d_Mat4d aTrsf;
|
||||
myTrsf.GetMat4 (aTrsf);
|
||||
|
||||
Select3D_BndBox3d aBox (SelectMgr_Vec3 (-myRadius, -myRadius, 0),
|
||||
SelectMgr_Vec3 (myRadius, myRadius, 0));
|
||||
aBox.Transform (aTrsf);
|
||||
|
||||
return aBox;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : CenterOfGeometry
|
||||
// purpose : Returns center of the circle. If location transformation
|
||||
// is set, it will be applied
|
||||
//=======================================================================
|
||||
//==================================================
|
||||
// Function: CenterOfGeometry
|
||||
// Purpose :
|
||||
//==================================================
|
||||
gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const
|
||||
{
|
||||
return myCenter3D;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : distanceToCOG
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Real Select3D_SensitiveCircle::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
|
||||
{
|
||||
return theMgr.DistToGeometryCenter (myCenter3D);
|
||||
return gp_Pnt (myTrsf.TranslationPart());
|
||||
}
|
||||
|
@@ -17,93 +17,70 @@
|
||||
#ifndef _Select3D_SensitiveCircle_HeaderFile
|
||||
#define _Select3D_SensitiveCircle_HeaderFile
|
||||
|
||||
#include <gp_Circ.hxx>
|
||||
#include <Select3D_SensitivePoly.hxx>
|
||||
#include <Select3D_TypeOfSensitivity.hxx>
|
||||
#include <SelectMgr_SelectingVolumeManager.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <Select3D_SensitiveEntity.hxx>
|
||||
|
||||
//! A framework to define sensitive 3D arcs and circles.
|
||||
//! In some cases this class can raise Standard_ConstructionError and
|
||||
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
|
||||
class Select3D_SensitiveCircle : public Select3D_SensitivePoly
|
||||
#include <gp_Circ.hxx>
|
||||
|
||||
//! A framework to define sensitive 3D circles.
|
||||
class Select3D_SensitiveCircle : public Select3D_SensitiveEntity
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitivePoly)
|
||||
DEFINE_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
|
||||
public:
|
||||
|
||||
//! Constructs the sensitive circle object defined by the
|
||||
//! owner theOwnerId, the circle theCircle and the boolean theIsFilled.
|
||||
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Boolean theIsFilled = Standard_False);
|
||||
|
||||
//! Constructs the sensitive circle object defined by the
|
||||
//! owner theOwnerId, the circle theCircle, the boolean
|
||||
//! theIsFilled and the number of points theNbPnts.
|
||||
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Boolean theIsFilled = Standard_False,
|
||||
const Standard_Integer theNbPnts = 12);
|
||||
|
||||
//! Constructs the sensitive arc object defined by the
|
||||
//! owner theOwnerId, the circle theCircle, the parameters theU1
|
||||
//! and theU2, the boolean theIsFilled and the number of points theNbPnts.
|
||||
//! theU1 and theU2 define the first and last points of the arc on theCircle.
|
||||
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled = Standard_False,
|
||||
const Standard_Integer theNbPnts = 12);
|
||||
|
||||
//! Constructs the sensitive circle object defined by the
|
||||
//! owner theOwnerId, the array of triangles thePnts3d, and the boolean theIsFilled.
|
||||
//! thePnts3d is an array of consecutive triangles on the
|
||||
//! circle. The triangle i+1 lies on the intersection of the
|
||||
//! tangents to the circle of i and i+2. Note, that the first point of thePnts3d
|
||||
//! must be equal to the last point of thePnts3d.
|
||||
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
|
||||
const Standard_Boolean theIsFilled = Standard_False);
|
||||
|
||||
//! Constructs the sensitive circle object defined by the
|
||||
//! owner theOwnerId, the array of points thePnts3d, and the boolean theIsFilled.
|
||||
//! If the length of thePnts3d is more then 1, the first point of thePnts3d
|
||||
//! must be equal to the last point of thePnts3d.
|
||||
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const TColgp_Array1OfPnt& thePnts3d,
|
||||
const Standard_Boolean theIsFilled = Standard_False);
|
||||
Standard_DEPRECATED("Deprecated constructor, theNbPnts parameter will be ignored")
|
||||
Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const Standard_Integer /*theNbPnts*/)
|
||||
: Select3D_SensitiveCircle (theOwnerId, theCircle, theIsFilled)
|
||||
{ }
|
||||
|
||||
//! Checks whether the circle overlaps current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
|
||||
//! Returns a copy of this sensitive circle
|
||||
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
|
||||
|
||||
//! Returns center of the circle. If location
|
||||
//! transformation is set, it will be applied
|
||||
//! Returns bounding box of the circle.
|
||||
//! If location transformation is set, it will be applied
|
||||
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
|
||||
|
||||
//! Always returns Standard_False
|
||||
virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE { return Standard_False; }
|
||||
|
||||
//! Returns the amount of points
|
||||
virtual Standard_Integer NbSubElements() const Standard_OVERRIDE { return 1; }
|
||||
|
||||
//! Returns center of the circle with transformation applied
|
||||
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
|
||||
|
||||
//! Builds BVH tree for a circle's edge segments if needed
|
||||
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
||||
//! The transformation for gp::XOY() with center in gp::Origin(),
|
||||
//! it specifies the position and orientation of the circle.
|
||||
const gp_Trsf& Transformation() const { return myTrsf; }
|
||||
|
||||
//! Returns TRUE if BVH tree is in invalidated state
|
||||
Standard_EXPORT virtual Standard_Boolean ToBuildBVH() const Standard_OVERRIDE;
|
||||
//! Returns circle
|
||||
gp_Circ Circle() const { return gp_Circ (gp::XOY().Transformed (myTrsf), myRadius); }
|
||||
|
||||
protected:
|
||||
|
||||
//! Calculates distance from the 3d projection of used-picked screen point
|
||||
//! to center of the geometry
|
||||
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
|
||||
//! Returns circle radius
|
||||
Standard_Real Radius() const { return myRadius; }
|
||||
|
||||
private:
|
||||
|
||||
//! Computes myCenter3D as the barycenter of points from mypolyg3d
|
||||
void computeCenter3D();
|
||||
|
||||
private:
|
||||
|
||||
Select3D_TypeOfSensitivity mySensType; //!< True if type of selection is interior, false otherwise
|
||||
gp_Pnt myCenter3D; //!< Center of a circle
|
||||
gp_Circ myCircle; //!< Points of the circle
|
||||
Standard_Real myStart; //!< Sensitive arc parameter
|
||||
Standard_Real myEnd; //!< Sensitive arc parameter
|
||||
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior
|
||||
gp_Trsf myTrsf; //!< Circle transformation to apply
|
||||
Standard_Real myRadius; //!< Circle radius
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitivePoly)
|
||||
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitiveEntity)
|
||||
|
||||
#endif // _Select3D_SensitiveCircle_HeaderFile
|
||||
|
@@ -25,12 +25,14 @@ Select3D_SensitiveCylinder::Select3D_SensitiveCylinder (const Handle(SelectMgr_E
|
||||
const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf)
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow)
|
||||
: Select3D_SensitiveEntity (theOwnerId),
|
||||
myTrsf (theTrsf),
|
||||
myBottomRadius (theBottomRad),
|
||||
myTopRadius (theTopRad),
|
||||
myHeight (theHeight)
|
||||
myHeight (theHeight),
|
||||
myIsHollow (theIsHollow)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,14 +48,14 @@ Standard_Boolean Select3D_SensitiveCylinder::Matches (SelectBasics_SelectingVolu
|
||||
if (!theMgr.IsOverlapAllowed())
|
||||
{
|
||||
bool isInside = true;
|
||||
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, &isInside) && isInside;
|
||||
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, &isInside) && isInside;
|
||||
}
|
||||
else
|
||||
{
|
||||
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, NULL);
|
||||
return theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, NULL);
|
||||
}
|
||||
}
|
||||
if (!theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, thePickResult))
|
||||
if (!theMgr.OverlapsCylinder (myBottomRadius, myTopRadius, myHeight, myTrsf, myIsHollow, thePickResult))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -81,17 +83,14 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveCylinder::GetConnected()
|
||||
Select3D_BndBox3d Select3D_SensitiveCylinder::BoundingBox()
|
||||
{
|
||||
Standard_Real aMaxRad = Max (myBottomRadius, myTopRadius);
|
||||
gp_Pnt aCenterBottom (0, 0, 0);
|
||||
gp_Pnt aCenterTop (0, 0, myHeight);
|
||||
aCenterBottom.Transform (myTrsf);
|
||||
aCenterTop.Transform (myTrsf);
|
||||
const SelectMgr_Vec3 aMinPnt (Min (aCenterBottom.X(), aCenterTop.X()) - aMaxRad,
|
||||
Min (aCenterBottom.Y(), aCenterTop.Y()) - aMaxRad,
|
||||
Min (aCenterBottom.Z(), aCenterTop.Z()) - aMaxRad);
|
||||
const SelectMgr_Vec3 aMaxPnt (Max (aCenterBottom.X(), aCenterTop.X()) + aMaxRad,
|
||||
Max (aCenterBottom.Y(), aCenterTop.Y()) + aMaxRad,
|
||||
Max (aCenterBottom.Z(), aCenterTop.Z()) + aMaxRad);
|
||||
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
|
||||
Graphic3d_Mat4d aTrsf;
|
||||
myTrsf.GetMat4 (aTrsf);
|
||||
|
||||
Select3D_BndBox3d aBox (SelectMgr_Vec3 (-aMaxRad, -aMaxRad, 0),
|
||||
SelectMgr_Vec3 (aMaxRad, aMaxRad, myHeight));
|
||||
aBox.Transform (aTrsf);
|
||||
|
||||
return aBox;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
|
@@ -32,7 +32,8 @@ public:
|
||||
const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf);
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow = Standard_False);
|
||||
|
||||
//! Checks whether the cylinder overlaps current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
@@ -54,11 +55,27 @@ public:
|
||||
//! Returns center of the cylinder with transformation applied
|
||||
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
|
||||
|
||||
//! Returns cylinder transformation
|
||||
const gp_Trsf& Transformation() const { return myTrsf; }
|
||||
|
||||
//! Returns cylinder top radius
|
||||
Standard_Real TopRadius() const { return myTopRadius; }
|
||||
|
||||
//! Returns cylinder bottom radius
|
||||
Standard_Real BottomRadius() const { return myBottomRadius; }
|
||||
|
||||
//! Returns cylinder height
|
||||
Standard_Real Height() const { return myHeight; }
|
||||
|
||||
//! Returns true if the cylinder is empty inside
|
||||
Standard_Boolean IsHollow() const { return myIsHollow; }
|
||||
|
||||
protected:
|
||||
gp_Trsf myTrsf; //!< cylinder transformation to apply
|
||||
Standard_Real myBottomRadius; //!< cylinder bottom radius
|
||||
Standard_Real myTopRadius; //!< cylinder top radius
|
||||
Standard_Real myHeight; //!< cylinder height
|
||||
gp_Trsf myTrsf; //!< cylinder transformation to apply
|
||||
Standard_Real myBottomRadius; //!< cylinder bottom radius
|
||||
Standard_Real myTopRadius; //!< cylinder top radius
|
||||
Standard_Real myHeight; //!< cylinder height
|
||||
Standard_Boolean myIsHollow; //!< true if the cylinder is empty inside
|
||||
};
|
||||
|
||||
#endif // _Select3D_SensitiveSphere_HeaderFile
|
||||
|
@@ -13,8 +13,71 @@
|
||||
|
||||
#include <Select3D_SensitivePoly.hxx>
|
||||
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly,Select3D_SensitiveSet)
|
||||
|
||||
namespace
|
||||
{
|
||||
static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle,
|
||||
const Standard_Integer theNbPnts,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled)
|
||||
{
|
||||
// Check if number of points is invalid.
|
||||
// In this case myPolyg raises Standard_ConstructionError
|
||||
// exception (see constructor below).
|
||||
if (theNbPnts <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (theCircle.Radius() > Precision::Confusion())
|
||||
{
|
||||
const Standard_Boolean isSector = theIsFilled && Abs (Abs (theU2 - theU1) - 2.0 * M_PI) > gp::Resolution();
|
||||
return 2 * theNbPnts + 1 + (isSector ? 2 : 0);
|
||||
}
|
||||
|
||||
// The radius is too small and circle degenerates into point
|
||||
return 1;
|
||||
}
|
||||
|
||||
//! Definition of circle polyline
|
||||
static void initCircle (Select3D_PointData& thePolygon,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const Standard_Integer theNbPnts)
|
||||
{
|
||||
const Standard_Real aStep = (theU2 - theU1) / theNbPnts;
|
||||
const Standard_Real aRadius = theCircle.Radius();
|
||||
Standard_Integer aPntIdx = 0;
|
||||
Standard_Real aCurU = theU1;
|
||||
gp_Pnt aP1;
|
||||
gp_Vec aV1;
|
||||
|
||||
const Standard_Boolean isSector = Abs (theU2 - theU1 - 2.0 * M_PI) > gp::Resolution();
|
||||
|
||||
if (isSector && theIsFilled) { thePolygon.SetPnt (aPntIdx++, theCircle.Location()); }
|
||||
|
||||
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep)
|
||||
{
|
||||
ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1);
|
||||
thePolygon.SetPnt (aPntIdx++, aP1);
|
||||
|
||||
aV1.Normalize();
|
||||
const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius;
|
||||
thePolygon.SetPnt (aPntIdx++, aP2);
|
||||
}
|
||||
aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius());
|
||||
thePolygon.SetPnt (aPntIdx++, aP1);
|
||||
|
||||
if (isSector && theIsFilled) { thePolygon.SetPnt (aPntIdx++, theCircle.Location()); }
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================
|
||||
// Function: Select3D_SensitivePoly
|
||||
// Purpose :
|
||||
@@ -23,7 +86,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
|
||||
const TColgp_Array1OfPnt& thePoints,
|
||||
const Standard_Boolean theIsBVHEnabled)
|
||||
: Select3D_SensitiveSet (theOwnerId),
|
||||
myPolyg (thePoints.Upper() - thePoints.Lower() + 1)
|
||||
myPolyg (thePoints.Upper() - thePoints.Lower() + 1),
|
||||
mySensType (Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
Standard_Integer aLowerIdx = thePoints.Lower();
|
||||
Standard_Integer anUpperIdx = thePoints.Upper();
|
||||
@@ -64,7 +128,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
|
||||
const Handle(TColgp_HArray1OfPnt)& thePoints,
|
||||
const Standard_Boolean theIsBVHEnabled)
|
||||
: Select3D_SensitiveSet (theOwnerId),
|
||||
myPolyg (thePoints->Upper() - thePoints->Lower() + 1)
|
||||
myPolyg (thePoints->Upper() - thePoints->Lower() + 1),
|
||||
mySensType (Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
Standard_Integer aLowerIdx = thePoints->Lower();
|
||||
Standard_Integer anUpperIdx = thePoints->Upper();
|
||||
@@ -105,7 +170,8 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
|
||||
const Standard_Boolean theIsBVHEnabled,
|
||||
const Standard_Integer theNbPnts)
|
||||
: Select3D_SensitiveSet (theOwnerId),
|
||||
myPolyg (theNbPnts)
|
||||
myPolyg (theNbPnts),
|
||||
mySensType (Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
if (theIsBVHEnabled)
|
||||
{
|
||||
@@ -119,6 +185,80 @@ Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwn
|
||||
myIsComputed = Standard_False;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
// Function: Creation
|
||||
// Purpose :
|
||||
//==================================================
|
||||
Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const Standard_Integer theNbPnts)
|
||||
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts, theU1, theU2, theIsFilled))
|
||||
{
|
||||
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
|
||||
|
||||
if (myPolyg.Size() != 1)
|
||||
{
|
||||
initCircle (myPolyg, theCircle, Min (theU1, theU2), Max (theU1, theU2), theIsFilled, theNbPnts);
|
||||
}
|
||||
else
|
||||
{
|
||||
myPolyg.SetPnt (0, theCircle.Position().Location());
|
||||
}
|
||||
|
||||
if (!theIsFilled)
|
||||
{
|
||||
SetSensitivityFactor (6);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Matches
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Select3D_SensitivePoly::Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult)
|
||||
{
|
||||
if (mySensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
if (!Select3D_SensitiveSet::Matches (theMgr, thePickResult))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
else if (mySensType == Select3D_TOS_INTERIOR)
|
||||
{
|
||||
Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
|
||||
Points3D (anArrayOfPnt);
|
||||
if (!theMgr.IsOverlapAllowed())
|
||||
{
|
||||
if (theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Polyline)
|
||||
{
|
||||
SelectBasics_PickResult aDummy;
|
||||
return theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), mySensType, aDummy);
|
||||
}
|
||||
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
|
||||
{
|
||||
if (!theMgr.OverlapsPoint (anArrayOfPnt->Value(aPntIdx)))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (!theMgr.OverlapsPolygon (anArrayOfPnt->Array1(), Select3D_TOS_INTERIOR, thePickResult))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
thePickResult.SetDistToGeomCenter (distanceToCOG(theMgr));
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//==================================================
|
||||
// function : BoundingBox
|
||||
// purpose : Returns bounding box of a polygon. If location
|
||||
|
@@ -14,13 +14,13 @@
|
||||
#ifndef _Select3D_SensitivePoly_HeaderFile
|
||||
#define _Select3D_SensitivePoly_HeaderFile
|
||||
|
||||
#include <gp_Circ.hxx>
|
||||
#include <Select3D_PointData.hxx>
|
||||
#include <Select3D_SensitiveSet.hxx>
|
||||
#include <Select3D_TypeOfSensitivity.hxx>
|
||||
#include <TColStd_HArray1OfInteger.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
|
||||
|
||||
//! Sensitive Entity to make a face selectable.
|
||||
//! In some cases this class can raise Standard_ConstructionError and
|
||||
//! Standard_OutOfRange exceptions from its member Select3D_PointData
|
||||
@@ -46,13 +46,28 @@ public:
|
||||
const Handle(TColgp_HArray1OfPnt)& thePoints,
|
||||
const Standard_Boolean theIsBVHEnabled);
|
||||
|
||||
//! Constructs the sensitive circle object defined by the
|
||||
//! owner OwnerId, the circle Circle, the Boolean
|
||||
//! FilledCircle and the number of points NbOfPoints.
|
||||
//! Constructs the sensitive arc object defined by the
|
||||
//! owner theOwnerId, the circle theCircle, the parameters theU1
|
||||
//! and theU2, the boolean theIsFilled and the number of points theNbPnts.
|
||||
//! theU1 and theU2 define the first and last points of the arc on theCircle.
|
||||
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const gp_Circ& theCircle,
|
||||
const Standard_Real theU1,
|
||||
const Standard_Real theU2,
|
||||
const Standard_Boolean theIsFilled = Standard_False,
|
||||
const Standard_Integer theNbPnts = 12);
|
||||
|
||||
//! Constructs a sensitive curve or arc object defined by the
|
||||
//! owner theOwnerId, the theIsBVHEnabled flag, and the
|
||||
//! maximum number of points on the curve: theNbPnts.
|
||||
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId,
|
||||
const Standard_Boolean theIsBVHEnabled,
|
||||
const Standard_Integer theNbPnts = 6);
|
||||
|
||||
//! Checks whether the poly overlaps current selecting volume
|
||||
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
|
||||
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
|
||||
|
||||
//! Returns the amount of segments in poly
|
||||
Standard_EXPORT virtual Standard_Integer NbSubElements() const Standard_OVERRIDE;
|
||||
|
||||
@@ -128,11 +143,12 @@ protected:
|
||||
|
||||
protected:
|
||||
|
||||
Select3D_PointData myPolyg; //!< Points of the poly
|
||||
mutable gp_Pnt myCOG; //!< Center of the poly
|
||||
Handle(TColStd_HArray1OfInteger) mySegmentIndexes; //!< Segment indexes for BVH tree build
|
||||
Select3D_BndBox3d myBndBox; //!< Bounding box of the poly
|
||||
mutable Standard_Boolean myIsComputed; //!< Is true if all the points and data structures of polygon are initialized
|
||||
Select3D_PointData myPolyg; //!< Points of the poly
|
||||
mutable gp_Pnt myCOG; //!< Center of the poly
|
||||
Handle(TColStd_HArray1OfInteger) mySegmentIndexes; //!< Segment indexes for BVH tree build
|
||||
Select3D_BndBox3d myBndBox; //!< Bounding box of the poly
|
||||
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior
|
||||
mutable Standard_Boolean myIsComputed; //!< Is true if all the points and data structures of polygon are initialized
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Select3D_SensitivePoly, Select3D_SensitiveSet)
|
||||
|
@@ -96,21 +96,41 @@ public:
|
||||
Standard_Boolean* theInside = NULL) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses theBottomRad
|
||||
//! and theTopRad, height theHeight and transformation to apply theTrsf.
|
||||
//! and theTopRad, height theHeight, the boolean theIsHollow and transformation to apply theTrsf.
|
||||
virtual Standard_Boolean OverlapsCylinder (const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
SelectBasics_PickResult& thePickResult) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses theBottomRad
|
||||
//! and theTopRad, height theHeight and transformation to apply theTrsf.
|
||||
//! and theTopRad, height theHeight, the boolean theIsHollow and transformation to apply theTrsf.
|
||||
virtual Standard_Boolean OverlapsCylinder (const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! the boolean theIsFilled, and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
SelectBasics_PickResult& thePickResult) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! the boolean theIsFilled, and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
//! Calculates distance from 3d projection of user-defined selection point
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <SelectMgr.hxx>
|
||||
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Graphic3d_ArrayOfPoints.hxx>
|
||||
#include <Graphic3d_AspectMarker3d.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
@@ -22,6 +23,8 @@
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <TColgp_SequenceOfPnt.hxx>
|
||||
#include <Select3D_SensitiveBox.hxx>
|
||||
#include <Select3D_SensitiveCircle.hxx>
|
||||
#include <Select3D_SensitiveCylinder.hxx>
|
||||
#include <Select3D_SensitiveEntity.hxx>
|
||||
#include <Select3D_SensitiveFace.hxx>
|
||||
#include <Select3D_SensitivePoint.hxx>
|
||||
@@ -130,6 +133,58 @@ namespace
|
||||
theSeqLines.Append (aPoints);
|
||||
}
|
||||
}
|
||||
|
||||
//! Fill in circle polylines.
|
||||
static void addCircle (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
||||
const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Real theHeight = 0)
|
||||
{
|
||||
const Standard_Real anUStep = 0.1;
|
||||
gp_XYZ aVec (0, 0, theHeight);
|
||||
|
||||
Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
|
||||
Geom_Circle aGeom (gp_Ax2(), theRadius);
|
||||
for (Standard_Real anU = 0.0f; anU < (2.0 * M_PI + anUStep); anU += anUStep)
|
||||
{
|
||||
gp_Pnt aCircPnt = aGeom.Value (anU).Coord() + aVec;
|
||||
aCircPnt.Transform (theTrsf);
|
||||
aPoints->Append (aCircPnt);
|
||||
}
|
||||
theSeqLines.Append (aPoints);
|
||||
}
|
||||
|
||||
//! Fill in cylinder polylines.
|
||||
static void addCylinder (Prs3d_NListOfSequenceOfPnt& theSeqLines,
|
||||
const Handle(Select3D_SensitiveCylinder)& theSensCyl,
|
||||
const gp_Trsf& theLoc)
|
||||
{
|
||||
Handle(TColgp_HSequenceOfPnt) aVertLine1 = new TColgp_HSequenceOfPnt();
|
||||
Handle(TColgp_HSequenceOfPnt) aVertLine2 = new TColgp_HSequenceOfPnt();
|
||||
|
||||
const gp_Trsf& aTrsf = theLoc.Multiplied (theSensCyl->Transformation());
|
||||
const Standard_Real aHeight = theSensCyl->Height();
|
||||
|
||||
for (int aCircNum = 0; aCircNum < 3; aCircNum++)
|
||||
{
|
||||
Standard_Real aRadius = 0.5 * (2 - aCircNum) * theSensCyl->BottomRadius()
|
||||
+ 0.5 * aCircNum * theSensCyl->TopRadius();
|
||||
const gp_XYZ aVec (0, 0, aHeight * 0.5 * aCircNum);
|
||||
|
||||
if (aCircNum != 1)
|
||||
{
|
||||
aVertLine1->Append (gp_Pnt (gp_XYZ (aRadius, 0, 0) + aVec).Transformed (aTrsf));
|
||||
aVertLine2->Append (gp_Pnt (gp_XYZ (-aRadius, 0, 0) + aVec).Transformed (aTrsf));
|
||||
}
|
||||
|
||||
if (aRadius > Precision::Confusion())
|
||||
{
|
||||
addCircle (theSeqLines, aRadius, aTrsf, aVec.Z());
|
||||
}
|
||||
}
|
||||
theSeqLines.Append (aVertLine1);
|
||||
theSeqLines.Append (aVertLine2);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -152,6 +207,14 @@ void SelectMgr::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& thePrs,
|
||||
{
|
||||
addBoundingBox (aSeqLines, aSensBox, theLoc);
|
||||
}
|
||||
else if (Handle(Select3D_SensitiveCylinder) aSensCyl = Handle(Select3D_SensitiveCylinder)::DownCast (anEnt))
|
||||
{
|
||||
addCylinder (aSeqLines, aSensCyl, theLoc);
|
||||
}
|
||||
else if (Handle(Select3D_SensitiveCircle) aSensCircle = Handle(Select3D_SensitiveCircle)::DownCast (anEnt))
|
||||
{
|
||||
addCircle (aSeqLines, aSensCircle->Radius(), theLoc.Multiplied (aSensCircle->Transformation()));
|
||||
}
|
||||
else if (Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(anEnt))
|
||||
{
|
||||
Handle(TColgp_HArray1OfPnt) aSensPnts;
|
||||
|
@@ -227,7 +227,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsBox (const SelectMgr_Vec3& t
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsBox() should be called after selection axis initialization");
|
||||
|
||||
(void )theInside;
|
||||
Standard_Real aTimeEnter, aTimeLeave;
|
||||
@@ -252,7 +252,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsBox (const SelectMgr_Vec3& t
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsBox() should be called after selection axis initialization");
|
||||
|
||||
Standard_Real aTimeEnter, aTimeLeave;
|
||||
if (!hasIntersection (theBoxMin, theBoxMax, aTimeEnter, aTimeLeave))
|
||||
@@ -283,7 +283,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsPoint (const gp_Pnt& thePnt,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsPoint() should be called after selection axis initialization");
|
||||
|
||||
Standard_Real aDepth = 0.0;
|
||||
if (!hasIntersection (thePnt, aDepth))
|
||||
@@ -304,7 +304,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsPoint (const gp_Pnt& thePnt,
|
||||
Standard_Boolean SelectMgr_AxisIntersector::OverlapsPoint (const gp_Pnt& thePnt) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsPoint() should be called after selection axis initialization");
|
||||
|
||||
Standard_Real aDepth = 0.0;
|
||||
return hasIntersection (thePnt, aDepth);
|
||||
@@ -320,7 +320,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsSegment (const gp_Pnt& thePn
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsSegment() should be called after selection axis initialization");
|
||||
|
||||
if (!raySegmentDistance (thePnt1, thePnt2, thePickResult))
|
||||
{
|
||||
@@ -340,7 +340,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsPolygon (const TColgp_Array1
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsPolygon() should be called after selection axis initialization");
|
||||
|
||||
if (theSensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
@@ -400,7 +400,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsTriangle (const gp_Pnt& theP
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE(mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsTriangle() should be called after selection axis initialization");
|
||||
|
||||
if (theSensType == Select3D_TOS_BOUNDARY)
|
||||
{
|
||||
@@ -503,7 +503,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsSphere (const gp_Pnt& theCen
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsSphere() should be called after selection axis initialization");
|
||||
(void )theInside;
|
||||
Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
|
||||
if (!RaySphereIntersection (theCenter, theRadius, myAxis.Location(), myAxis.Direction(), aTimeEnter, aTimeLeave))
|
||||
@@ -527,7 +527,7 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsSphere (const gp_Pnt& theCen
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsSphere() should be called after selection axis initialization");
|
||||
Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
|
||||
if (!RaySphereIntersection (theCenter, theRadius, myAxis.Location(), myAxis.Direction(), aTimeEnter, aTimeLeave))
|
||||
{
|
||||
@@ -558,22 +558,24 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsCylinder (const Standard_Rea
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsCylinder() should be called after selection axis initialization");
|
||||
Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
|
||||
gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
gp_Pnt aLoc = myAxis.Location() .Transformed (aTrsfInv);
|
||||
gp_Dir aRayDir = myAxis.Direction().Transformed (aTrsfInv);
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, aTimeEnter, aTimeLeave))
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir,
|
||||
theIsHollow, aTimeEnter, aTimeLeave))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Standard_Real aDepth = 0.0;
|
||||
Bnd_Range aRange (Max (aTimeEnter, 0.0), aTimeLeave);
|
||||
Bnd_Range aRange (Max (aTimeEnter, 0.0), Max (aTimeEnter, aTimeLeave));
|
||||
aRange.GetMin (aDepth);
|
||||
if (!theClipRange.GetNearestDepth (aRange, aDepth))
|
||||
{
|
||||
@@ -606,15 +608,17 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsCylinder (const Standard_Rea
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
Standard_Boolean* theInside) const
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::Overlaps() should be called after selection axis initialization");
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsCylinder() should be called after selection axis initialization");
|
||||
Standard_Real aTimeEnter = 0.0, aTimeLeave = 0.0;
|
||||
gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
gp_Pnt aLoc = myAxis.Location() .Transformed (aTrsfInv);
|
||||
gp_Dir aRayDir = myAxis.Direction().Transformed (aTrsfInv);
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, aTimeEnter, aTimeLeave))
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir,
|
||||
theIsHollow, aTimeEnter, aTimeLeave))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -625,6 +629,74 @@ Standard_Boolean SelectMgr_AxisIntersector::OverlapsCylinder (const Standard_Rea
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_AxisIntersector::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsCircle() should be called after selection axis initialization");
|
||||
Standard_Real aTime = 0.0;
|
||||
gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
gp_Pnt aLoc = myAxis.Location().Transformed (aTrsfInv);
|
||||
gp_Dir aRayDir = myAxis.Direction().Transformed (aTrsfInv);
|
||||
if (!RayCircleIntersection (theRadius, aLoc, aRayDir, theIsFilled, aTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Standard_Real aDepth = Max (aTime, 0.0);
|
||||
if (theClipRange.IsClipped (aDepth))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const gp_Pnt aPntOnCylinder = aLoc.XYZ() + aRayDir.XYZ() * aDepth;
|
||||
thePickResult.SetDepth (aDepth);
|
||||
thePickResult.SetPickedPoint (aPntOnCylinder.Transformed (theTrsf));
|
||||
if (Abs (aPntOnCylinder.Z()) < Precision::Confusion())
|
||||
{
|
||||
thePickResult.SetSurfaceNormal (-gp::DZ().Transformed (theTrsf));
|
||||
}
|
||||
else
|
||||
{
|
||||
thePickResult.SetSurfaceNormal (gp_Vec (aPntOnCylinder.X(), aPntOnCylinder.Y(), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_AxisIntersector::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point,
|
||||
"Error! SelectMgr_AxisIntersector::OverlapsCircle() should be called after selection axis initialization");
|
||||
Standard_Real aTime = 0.0;
|
||||
gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
gp_Pnt aLoc = myAxis.Location().Transformed (aTrsfInv);
|
||||
gp_Dir aRayDir = myAxis.Direction().Transformed (aTrsfInv);
|
||||
if (!RayCircleIntersection (theRadius, aLoc, aRayDir, theIsFilled, aTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside &= (aTime >= 0.0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : GetNearPnt
|
||||
// purpose :
|
||||
|
@@ -117,6 +117,7 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
@@ -126,8 +127,28 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
public:
|
||||
|
||||
//! Measures distance between start axis point and given point theCOG.
|
||||
|
@@ -176,15 +176,15 @@ Standard_Boolean SelectMgr_BaseIntersector::RayCylinderIntersection (const Stand
|
||||
const Standard_Real theHeight,
|
||||
const gp_Pnt& theLoc,
|
||||
const gp_Dir& theRayDir,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Real& theTimeEnter,
|
||||
Standard_Real& theTimeLeave) const
|
||||
{
|
||||
Standard_Integer aNbIntersections = 0;
|
||||
Standard_Real anIntersections[4] = { RealLast(), RealLast(), RealLast(), RealLast() };
|
||||
//NCollection_Vector<Standard_Real> anIntersections; // vector for all intersections
|
||||
// Check intersections with end faces
|
||||
// point of intersection theRayDir and z = 0
|
||||
if (theRayDir.Z() != 0)
|
||||
if (!theIsHollow && theRayDir.Z() != 0)
|
||||
{
|
||||
const Standard_Real aTime1 = (0 - theLoc.Z()) / theRayDir.Z();
|
||||
const Standard_Real aX1 = theLoc.X() + theRayDir.X() * aTime1;
|
||||
@@ -293,6 +293,33 @@ Standard_Boolean SelectMgr_BaseIntersector::RayCylinderIntersection (const Stand
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : RayCircleIntersection
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_BaseIntersector::RayCircleIntersection (const Standard_Real theRadius,
|
||||
const gp_Pnt& theLoc,
|
||||
const gp_Dir& theRayDir,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Real& theTime) const
|
||||
{
|
||||
if (theRayDir.Z() != 0)
|
||||
{
|
||||
const Standard_Real aTime = (0 - theLoc.Z()) / theRayDir.Z();
|
||||
const Standard_Real aX1 = theLoc.X() + theRayDir.X() * aTime;
|
||||
const Standard_Real anY1 = theLoc.Y() + theRayDir.Y() * aTime;
|
||||
|
||||
const Standard_Real aK = aX1 * aX1 + anY1 * anY1;
|
||||
if ((theIsFilled && aK <= theRadius * theRadius)
|
||||
|| (!theIsFilled && Abs (sqrt (aK) - theRadius) <= Precision::Confusion()))
|
||||
{
|
||||
theTime = aTime;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : DistToGeometryCenter
|
||||
// purpose :
|
||||
|
@@ -187,6 +187,7 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const = 0;
|
||||
|
||||
@@ -196,8 +197,28 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const = 0;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
//! Measures distance between 3d projection of user-picked
|
||||
@@ -224,15 +245,37 @@ public:
|
||||
Standard_Real& theTimeLeave) const;
|
||||
|
||||
//! Checks whether the ray that starts at the point theLoc and directs with the direction theRayDir intersects
|
||||
//! with the cylinder (or cone) with radiuses theBottomRad and theTopRad and height theHeights
|
||||
//! with the hollow cylinder (or cone)
|
||||
//! @param[in] theBottomRadius the bottom cylinder radius
|
||||
//! @param[in] theTopRadius the top cylinder radius
|
||||
//! @param[in] theHeight the cylinder height
|
||||
//! @param[in] theLoc the location of the ray
|
||||
//! @param[in] theRayDir the ray direction
|
||||
//! @param[in] theIsHollow true if the cylinder is hollow
|
||||
//! @param[out] theTimeEnter the entering the intersection
|
||||
//! @param[out] theTimeLeave the leaving the intersection
|
||||
Standard_EXPORT virtual Standard_Boolean RayCylinderIntersection (const Standard_Real theBottomRadius,
|
||||
const Standard_Real theTopRadius,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Pnt& theLoc,
|
||||
const gp_Dir& theRayDir,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Real& theTimeEnter,
|
||||
Standard_Real& theTimeLeave) const;
|
||||
|
||||
//! Checks whether the ray that starts at the point theLoc and directs with the direction theRayDir intersects
|
||||
//! with the circle
|
||||
//! @param[in] theRadius the circle radius
|
||||
//! @param[in] theLoc the location of the ray
|
||||
//! @param[in] theRayDir the ray direction
|
||||
//! @param[in] theIsFilled true if it's a circle, false if it's a circle outline
|
||||
//! @param[out] theTime the intersection
|
||||
Standard_EXPORT virtual Standard_Boolean RayCircleIntersection (const Standard_Real theRadius,
|
||||
const gp_Pnt& theLoc,
|
||||
const gp_Dir& theRayDir,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Real& theTime) const;
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(SelectMgr_BaseIntersector,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
@@ -98,11 +98,25 @@ protected:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const;
|
||||
|
||||
//! Intersection test between defined volume and given circle.
|
||||
Standard_Boolean hasCircleOverlap (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const;
|
||||
|
||||
//! Returns True if all vertices (theVertices) are inside the top and bottom sides of the cylinder.
|
||||
Standard_Boolean isInsideCylinderEndFace (const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const;
|
||||
|
||||
//! Checking whether the point thePnt is inside the shape with borders theVertices.
|
||||
//! thePnt and theVertices lie in the same plane.
|
||||
Standard_Boolean IsDotInside (const gp_Pnt& thePnt,
|
||||
Standard_Boolean isDotInside (const gp_Pnt& thePnt,
|
||||
const TColgp_Array1OfPnt& theVertices) const;
|
||||
|
||||
private:
|
||||
@@ -116,10 +130,10 @@ private:
|
||||
|
||||
//! Checking whether the borders theVertices of the shape intersect
|
||||
//! the cylinder (or cone) end face with the center theCenter and radius theRadius
|
||||
Standard_Boolean isIntersectCylinderEndFace (const Standard_Real theRad,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const;
|
||||
Standard_Boolean isIntersectCircle (const Standard_Real theRadius,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const;
|
||||
|
||||
//! Checks if AABB and frustum are separated along the given axis
|
||||
Standard_Boolean isSeparated (const SelectMgr_Vec3& theBoxMin,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Created on: 2015-03-16
|
||||
// Created on: 2015-03-16
|
||||
// Created by: Varvara POSKONINA
|
||||
// Copyright (c) 2005-2014 OPEN CASCADE SAS
|
||||
//
|
||||
@@ -520,7 +520,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasSphereOverlap (const gp_Pnt& thePnt,
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::IsDotInside (const gp_Pnt& thePnt,
|
||||
Standard_Boolean SelectMgr_Frustum<N>::isDotInside (const gp_Pnt& thePnt,
|
||||
const TColgp_Array1OfPnt& theVertices) const
|
||||
{
|
||||
Standard_Real anAngle = 0.0;
|
||||
@@ -598,14 +598,14 @@ Standard_Boolean SelectMgr_Frustum<N>::isSegmentsIntersect (const gp_Pnt& thePnt
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : isIntersectCylinderEndFace
|
||||
// function : isIntersectCircle
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::isIntersectCylinderEndFace (const Standard_Real theRad,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const
|
||||
Standard_Boolean SelectMgr_Frustum<N>::isIntersectCircle (const Standard_Real theRadius,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const
|
||||
{
|
||||
const gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
const gp_Dir aRayDir = gp_Dir (myEdgeDirs[N == 4 ? 4 : 0]).Transformed (aTrsfInv);
|
||||
@@ -633,7 +633,7 @@ Standard_Boolean SelectMgr_Frustum<N>::isIntersectCylinderEndFace (const Standar
|
||||
// Solving quadratic equation anA * T^2 + 2 * aK * T + aC = 0
|
||||
const Standard_Real anA = (aX1 - aX2) * (aX1 - aX2) + (anY1 - anY2) * (anY1 - anY2);
|
||||
const Standard_Real aK = aX1 * (aX2 - aX1) + anY1 * (anY2 - anY1);
|
||||
const Standard_Real aC = aX1 * aX1 + anY1 * anY1 - theRad * theRad;
|
||||
const Standard_Real aC = aX1 * aX1 + anY1 * anY1 - theRadius * theRadius;
|
||||
|
||||
const Standard_Real aDiscr = aK * aK - anA * aC;
|
||||
if (aDiscr >= 0.0)
|
||||
@@ -649,6 +649,47 @@ Standard_Boolean SelectMgr_Frustum<N>::isIntersectCylinderEndFace (const Standar
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : isInsideCylinderEndFace
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::isInsideCylinderEndFace (const Standard_Real theBottomRad,
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const
|
||||
{
|
||||
const gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
const gp_Dir aRayDir = gp_Dir (myEdgeDirs[N == 4 ? 4 : 0]).Transformed (aTrsfInv);
|
||||
if (aRayDir.Z() == 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Standard_Integer anIdx = theVertices.Lower(); anIdx <= theVertices.Upper(); anIdx++)
|
||||
{
|
||||
const gp_Pnt aLoc = theVertices.Value (anIdx).Transformed (aTrsfInv);
|
||||
|
||||
const Standard_Real aTime1 = (0 - aLoc.Z()) / aRayDir.Z();
|
||||
const Standard_Real aX1 = aLoc.X() + aRayDir.X() * aTime1;
|
||||
const Standard_Real anY1 = aLoc.Y() + aRayDir.Y() * aTime1;
|
||||
|
||||
const Standard_Real aTime2 = (theHeight - aLoc.Z()) / aRayDir.Z();
|
||||
const Standard_Real aX2 = aLoc.X() + aRayDir.X() * aTime2;
|
||||
const Standard_Real anY2 = aLoc.Y() + aRayDir.Y() * aTime2;
|
||||
|
||||
if (aX1 * aX1 + anY1 * anY1 <= theBottomRad * theBottomRad
|
||||
&& aX2 * aX2 + anY2 * anY2 <= theTopRad * theTopRad)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : hasCylinderOverlap
|
||||
// purpose :
|
||||
@@ -658,8 +699,37 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCylinderOverlap (const Standard_Real t
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
gp_Pnt aVerticesBuf[N];
|
||||
TColgp_Array1OfPnt aVertices (aVerticesBuf[0], 0, N - 1);
|
||||
const Standard_Integer anIncFactor = (Camera()->IsOrthographic() && N == 4) ? 2 : 1;
|
||||
if (anIncFactor == 2)
|
||||
{
|
||||
const Standard_Integer anIndices[] = { 0, 2, 6, 4 };
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIndices[anIdx]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIdx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (theIsHollow && isInsideCylinderEndFace (theBottomRad, theTopRad, theHeight, theTrsf, aVertices))
|
||||
{
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const gp_Dir aCylNorm (gp::DZ().Transformed (theTrsf));
|
||||
const gp_Pnt aBottomCenter (gp::Origin().Transformed (theTrsf));
|
||||
const gp_Pnt aTopCenter = aBottomCenter.XYZ() + aCylNorm.XYZ() * theHeight;
|
||||
@@ -698,29 +768,11 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCylinderOverlap (const Standard_Real t
|
||||
aPoints[5] = aBottomCenterProject.XYZ() - aDirEndFaces.XYZ() * theBottomRad;
|
||||
const TColgp_Array1OfPnt aPointsArr (aPoints[0], 0, 5);
|
||||
|
||||
gp_Pnt aVerticesBuf[N];
|
||||
TColgp_Array1OfPnt aVertices (aVerticesBuf[0], 0, N - 1);
|
||||
const Standard_Integer anIncFactor = (Camera()->IsOrthographic() && N == 4) ? 2 : 1;
|
||||
if (anIncFactor == 2)
|
||||
{
|
||||
const Standard_Integer anIndices[] = { 0, 2, 6, 4 };
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIndices[anIdx]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIdx]);
|
||||
}
|
||||
}
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
if ((aCylNormProject.Dot (aCylNormProject) == 0.0
|
||||
&& aVertices.Value (anIdx).Distance (aPoints[0]) <= Max (theTopRad, theBottomRad))
|
||||
|| IsDotInside (aVertices.Value (anIdx), aPointsArr))
|
||||
|| isDotInside (aVertices.Value (anIdx), aPointsArr))
|
||||
{
|
||||
if (theInside != NULL)
|
||||
{
|
||||
@@ -747,8 +799,9 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCylinderOverlap (const Standard_Real t
|
||||
}
|
||||
}
|
||||
|
||||
if (isIntersectCylinderEndFace (theBottomRad, gp_Pnt (0, 0, 0), theTrsf, aVertices)
|
||||
|| isIntersectCylinderEndFace (theTopRad, gp_Pnt (0, 0, theHeight), theTrsf, aVertices))
|
||||
if (!theIsHollow
|
||||
&& (isIntersectCircle (theBottomRad, gp_Pnt (0, 0, 0), theTrsf, aVertices)
|
||||
|| isIntersectCircle (theTopRad, gp_Pnt (0, 0, theHeight), theTrsf, aVertices)))
|
||||
{
|
||||
if (theInside != NULL)
|
||||
{
|
||||
@@ -759,7 +812,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCylinderOverlap (const Standard_Real t
|
||||
bool isCylInsideRec = true;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
isCylInsideRec &= IsDotInside (aPoints[i], aVertices);
|
||||
isCylInsideRec &= isDotInside (aPoints[i], aVertices);
|
||||
}
|
||||
if (theInside != NULL)
|
||||
{
|
||||
@@ -768,6 +821,82 @@ Standard_Boolean SelectMgr_Frustum<N>::hasCylinderOverlap (const Standard_Real t
|
||||
return isCylInsideRec;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : hasCircleOverlap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<int N>
|
||||
Standard_Boolean SelectMgr_Frustum<N>::hasCircleOverlap (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
gp_Pnt aVerticesBuf[N];
|
||||
TColgp_Array1OfPnt aVertices (aVerticesBuf[0], 0, N - 1);
|
||||
const Standard_Integer anIncFactor = (Camera()->IsOrthographic() && N == 4) ? 2 : 1;
|
||||
if (anIncFactor == 2)
|
||||
{
|
||||
const Standard_Integer anIndices[] = { 0, 2, 6, 4 };
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIndices[anIdx]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Standard_Integer anIdx = 0; anIdx < N; anIdx++)
|
||||
{
|
||||
aVertices.SetValue (anIdx, myVertices[anIdx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isIntersectCircle (theRadius, gp_Pnt (0, 0, 0), theTrsf, aVertices))
|
||||
{
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
gp_Pnt aCircCenter = gp::Origin();//.Transformed (theTrsf);
|
||||
const gp_Dir aViewRayDir = gp_Dir (myEdgeDirs[N == 4 ? 4 : 0]);
|
||||
const gp_Pln aPln (myVertices[0], aViewRayDir);
|
||||
Standard_Real aCoefA, aCoefB, aCoefC, aCoefD;
|
||||
aPln.Coefficients (aCoefA, aCoefB, aCoefC, aCoefD);
|
||||
|
||||
const Standard_Real aTCenter = -(aCircCenter.XYZ().Dot (aViewRayDir.XYZ()) + aCoefD);
|
||||
const gp_Pnt aCenterProject (aCoefA * aTCenter,
|
||||
aCoefB * aTCenter,
|
||||
aCoefC * aTCenter);
|
||||
if (isDotInside (aCenterProject, aVertices))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Standard_Boolean isInside = true;
|
||||
for (Standard_Integer anIdx = aVertices.Lower(); anIdx <= aVertices.Upper(); anIdx++)
|
||||
{
|
||||
if (aVertices.Value (anIdx).Distance (aCenterProject) > theRadius)
|
||||
{
|
||||
isInside = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside = false;
|
||||
}
|
||||
|
||||
if (!theIsFilled && isInside)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return isInside;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DumpJson
|
||||
//purpose :
|
||||
|
@@ -748,6 +748,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
@@ -757,7 +758,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
|
||||
const gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
const gp_Pnt aLoc = myNearPickedPnt.Transformed (aTrsfInv);
|
||||
const gp_Dir aRayDir = myViewRayDir .Transformed (aTrsfInv);
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, aTimes[0], aTimes[1]))
|
||||
if (!RayCylinderIntersection (theBottomRad, theTopRad, theHeight, aLoc, aRayDir, theIsHollow, aTimes[0], aTimes[1]))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -787,6 +788,165 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
|
||||
return !theClipRange.IsClipped (thePickResult.Depth());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point || mySelectionType == SelectMgr_SelectionType_Box,
|
||||
"Error! SelectMgr_RectangularFrustum::Overlaps() should be called after selection frustum initialization");
|
||||
Standard_Real aTime = 0.0;
|
||||
const gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
const gp_Pnt aLoc = myNearPickedPnt.Transformed (aTrsfInv);
|
||||
const gp_Dir aRayDir = myViewRayDir.Transformed (aTrsfInv);
|
||||
if (!theIsFilled)
|
||||
{
|
||||
if (!hasCircleOverlap (theRadius, theTrsf, theIsFilled, NULL))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
if (aRayDir.Z() != 0)
|
||||
{
|
||||
aTime = (0 - aLoc.Z()) / aRayDir.Z();
|
||||
}
|
||||
}
|
||||
else if (!RayCircleIntersection (theRadius, aLoc, aRayDir, theIsFilled, aTime))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
thePickResult.SetDepth (aTime * myScale);
|
||||
if (theClipRange.IsClipped (thePickResult.Depth()))
|
||||
{
|
||||
thePickResult.SetDepth (aTime * myScale);
|
||||
}
|
||||
|
||||
const gp_Pnt aPntOnCircle = aLoc.XYZ() + aRayDir.XYZ() * aTime;
|
||||
if (Abs (aPntOnCircle.Z()) < Precision::Confusion())
|
||||
{
|
||||
thePickResult.SetSurfaceNormal (-gp::DZ().Transformed (theTrsf));
|
||||
}
|
||||
else
|
||||
{
|
||||
thePickResult.SetSurfaceNormal (gp_Vec (aPntOnCircle.X(), aPntOnCircle.Y(), 0.0).Transformed (theTrsf));
|
||||
}
|
||||
thePickResult.SetPickedPoint (aPntOnCircle.Transformed (theTrsf));
|
||||
return !theClipRange.IsClipped (thePickResult.Depth());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : isIntersectCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::isIntersectCircle (const Standard_Real theRadius,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const
|
||||
{
|
||||
const gp_Trsf aTrsfInv = theTrsf.Inverted();
|
||||
const gp_Dir aRayDir = gp_Dir (myEdgeDirs[4 == 4 ? 4 : 0]).Transformed (aTrsfInv);
|
||||
if (aRayDir.Z() == 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Standard_Integer anIdx = theVertices.Lower(); anIdx <= theVertices.Upper(); anIdx++)
|
||||
{
|
||||
const gp_Pnt aPntStart = theVertices.Value (anIdx).Transformed (aTrsfInv);
|
||||
const gp_Pnt aPntFinish = anIdx == theVertices.Upper()
|
||||
? theVertices.Value (theVertices.Lower()).Transformed (aTrsfInv)
|
||||
: theVertices.Value (anIdx + 1).Transformed (aTrsfInv);
|
||||
|
||||
// Project points on the end face plane
|
||||
const Standard_Real aParam1 = (theCenter.Z() - aPntStart.Z()) / aRayDir.Z();
|
||||
const Standard_Real aX1 = aPntStart.X() + aRayDir.X() * aParam1;
|
||||
const Standard_Real anY1 = aPntStart.Y() + aRayDir.Y() * aParam1;
|
||||
|
||||
const Standard_Real aParam2 = (theCenter.Z() - aPntFinish.Z()) / aRayDir.Z();
|
||||
const Standard_Real aX2 = aPntFinish.X() + aRayDir.X() * aParam2;
|
||||
const Standard_Real anY2 = aPntFinish.Y() + aRayDir.Y() * aParam2;
|
||||
|
||||
// Solving quadratic equation anA * T^2 + 2 * aK * T + aC = 0
|
||||
const Standard_Real anA = (aX1 - aX2) * (aX1 - aX2) + (anY1 - anY2) * (anY1 - anY2);
|
||||
const Standard_Real aK = aX1 * (aX2 - aX1) + anY1 * (anY2 - anY1);
|
||||
const Standard_Real aC = aX1 * aX1 + anY1 * anY1 - theRadius * theRadius;
|
||||
|
||||
const Standard_Real aDiscr = aK * aK - anA * aC;
|
||||
if (aDiscr >= 0.0)
|
||||
{
|
||||
const Standard_Real aT1 = (-aK + Sqrt (aDiscr)) / anA;
|
||||
const Standard_Real aT2 = (-aK - Sqrt (aDiscr)) / anA;
|
||||
if ((aT1 >= 0 && aT1 <= 1) || (aT2 >= 0 && aT2 <= 1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : isSegmentsIntersect
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::isSegmentsIntersect (const gp_Pnt& thePnt1Seg1,
|
||||
const gp_Pnt& thePnt2Seg1,
|
||||
const gp_Pnt& thePnt1Seg2,
|
||||
const gp_Pnt& thePnt2Seg2) const
|
||||
{
|
||||
const gp_Mat aMatPln (thePnt2Seg1.X() - thePnt1Seg1.X(), thePnt2Seg1.Y() - thePnt1Seg1.Y(), thePnt2Seg1.Z() - thePnt1Seg1.Z(),
|
||||
thePnt1Seg2.X() - thePnt1Seg1.X(), thePnt1Seg2.Y() - thePnt1Seg1.Y(), thePnt1Seg2.Z() - thePnt1Seg1.Z(),
|
||||
thePnt2Seg2.X() - thePnt1Seg1.X(), thePnt2Seg2.Y() - thePnt1Seg1.Y(), thePnt2Seg2.Z() - thePnt1Seg1.Z());
|
||||
if (Abs (aMatPln.Determinant()) > Precision::Confusion())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Standard_Real aFst[4] = { thePnt1Seg1.X(), thePnt2Seg1.X(), thePnt1Seg2.X(), thePnt2Seg2.X() };
|
||||
Standard_Real aSnd[4] = { thePnt1Seg1.Y(), thePnt2Seg1.Y(), thePnt1Seg2.Y(), thePnt2Seg2.Y() };
|
||||
if (aFst[0] == aFst[2] && aFst[1] == aFst[3])
|
||||
{
|
||||
aFst[0] = thePnt1Seg1.Z();
|
||||
aFst[1] = thePnt2Seg1.Z();
|
||||
aFst[2] = thePnt1Seg2.Z();
|
||||
aFst[3] = thePnt2Seg2.Z();
|
||||
}
|
||||
if (aSnd[0] == aSnd[2]
|
||||
&& aSnd[1] == aSnd[3])
|
||||
{
|
||||
aSnd[0] = thePnt1Seg1.Z();
|
||||
aSnd[1] = thePnt2Seg1.Z();
|
||||
aSnd[2] = thePnt1Seg2.Z();
|
||||
aSnd[3] = thePnt2Seg2.Z();
|
||||
}
|
||||
const gp_Mat2d aMat (gp_XY (aFst[0] - aFst[1], aSnd[0] - aSnd[1]),
|
||||
gp_XY (aFst[3] - aFst[2], aSnd[3] - aSnd[2]));
|
||||
|
||||
const gp_Mat2d aMatU (gp_XY (aFst[0] - aFst[2], aSnd[0] - aSnd[2]),
|
||||
gp_XY (aFst[3] - aFst[2], aSnd[3] - aSnd[2]));
|
||||
|
||||
const gp_Mat2d aMatV (gp_XY (aFst[0] - aFst[1], aSnd[0] - aSnd[1]),
|
||||
gp_XY (aFst[0] - aFst[2], aSnd[0] - aSnd[2]));
|
||||
if (aMat.Determinant() == 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Standard_Real anU = aMatU.Determinant() / aMat.Determinant();
|
||||
const Standard_Real aV = aMatV.Determinant() / aMat.Determinant();
|
||||
if (anU >= 0.0 && anU <= 1.0
|
||||
&& aV >= 0.0 && aV <= 1.0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCylinder
|
||||
// purpose :
|
||||
@@ -795,12 +955,28 @@ Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCylinder (const Standard_
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point || mySelectionType == SelectMgr_SelectionType_Box,
|
||||
"Error! SelectMgr_RectangularFrustum::Overlaps() should be called after selection frustum initialization");
|
||||
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf, theInside);
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf, theIsHollow, theInside);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_RectangularFrustum::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Point || mySelectionType == SelectMgr_SelectionType_Box,
|
||||
"Error! SelectMgr_RectangularFrustum::Overlaps() should be called after selection frustum initialization");
|
||||
|
||||
return hasCircleOverlap (theRadius, theTrsf, theIsFilled, theInside);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -66,6 +66,18 @@ public:
|
||||
Standard_EXPORT void Init (const gp_Pnt2d& theMinPnt,
|
||||
const gp_Pnt2d& theMaxPnt);
|
||||
|
||||
//! Returns True if Frustum (theVertices) intersects the circle.
|
||||
Standard_EXPORT Standard_Boolean isIntersectCircle (const Standard_Real theRadius,
|
||||
const gp_Pnt& theCenter,
|
||||
const gp_Trsf& theTrsf,
|
||||
const TColgp_Array1OfPnt& theVertices) const;
|
||||
|
||||
//! Returns True if Seg1 (thePnt1Seg1, thePnt2Seg1) and Seg2 (thePnt1Seg2, thePnt2Seg2) intersect.
|
||||
Standard_EXPORT Standard_Boolean isSegmentsIntersect (const gp_Pnt& thePnt1Seg1,
|
||||
const gp_Pnt& thePnt2Seg1,
|
||||
const gp_Pnt& thePnt1Seg2,
|
||||
const gp_Pnt& thePnt2Seg2) const;
|
||||
|
||||
//! Builds volume according to internal parameters.
|
||||
//! NOTE: it should be called after Init() method
|
||||
Standard_EXPORT virtual void Build() Standard_OVERRIDE;
|
||||
@@ -150,6 +162,7 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
@@ -159,8 +172,28 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Measures distance between 3d projection of user-picked
|
||||
//! screen point and given point theCOG.
|
||||
//! It makes sense only for frustums built on a single point.
|
||||
|
@@ -426,13 +426,15 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::OverlapsCylinder (const Stand
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
if (myActiveSelectingVolume.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myActiveSelectingVolume->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf, myViewClipRange, thePickResult);
|
||||
return myActiveSelectingVolume->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf,
|
||||
theIsHollow, myViewClipRange, thePickResult);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -443,13 +445,47 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::OverlapsCylinder (const Stand
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
if (myActiveSelectingVolume.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myActiveSelectingVolume->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf, theInside);
|
||||
return myActiveSelectingVolume->OverlapsCylinder (theBottomRad, theTopRad, theHeight,
|
||||
theTrsf, theIsHollow, theInside);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
if (myActiveSelectingVolume.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myActiveSelectingVolume->OverlapsCircle (theRadius, theTrsf, theIsFilled, myViewClipRange, thePickResult);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_SelectingVolumeManager::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
if (myActiveSelectingVolume.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return myActiveSelectingVolume->OverlapsCircle (theRadius, theTrsf, theIsFilled, theInside);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -168,6 +168,7 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses theBottomRad
|
||||
@@ -176,8 +177,27 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Measures distance between 3d projection of user-picked
|
||||
//! screen point and given point theCOG
|
||||
Standard_EXPORT virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) const Standard_OVERRIDE;
|
||||
|
@@ -337,12 +337,13 @@ Standard_Boolean SelectMgr_TriangularFrustum::OverlapsCylinder (const Standard_R
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
(void)theClipRange;
|
||||
(void)thePickResult;
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf);
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf, theIsHollow);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -353,10 +354,39 @@ Standard_Boolean SelectMgr_TriangularFrustum::OverlapsCylinder (const Standard_R
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
(void) theInside;
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf);
|
||||
return hasCylinderOverlap (theBottomRad, theTopRad, theHeight, theTrsf, theIsHollow);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustum::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
(void)theClipRange;
|
||||
(void)thePickResult;
|
||||
return hasCircleOverlap (theRadius, theTrsf, theIsFilled);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustum::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
(void)theInside;
|
||||
return hasCircleOverlap (theRadius, theTrsf, theIsFilled);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -123,6 +123,7 @@ public: //! @name SAT Tests for different objects
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
@@ -132,8 +133,28 @@ public: //! @name SAT Tests for different objects
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by circle with radius theRadius,
|
||||
//! boolean theIsFilled and transformation to apply theTrsf.
|
||||
//! The position and orientation of the circle are specified
|
||||
//! via theTrsf transformation for gp::XOY() with center in gp::Origin().
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
public:
|
||||
|
||||
//! Nullifies the handle to corresponding builder instance to prevent memory leaks
|
||||
|
@@ -17,6 +17,10 @@
|
||||
|
||||
#include <BRepMesh_DataStructureOfDelaun.hxx>
|
||||
#include <BRepMesh_Delaun.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <GeomInt_IntSS.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <SelectMgr_FrustumBuilder.hxx>
|
||||
|
||||
@@ -506,6 +510,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
@@ -513,7 +518,8 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
"Error! SelectMgr_TriangularFrustumSet::Overlaps() should be called after selection frustum initialization");
|
||||
for (SelectMgr_TriangFrustums::Iterator anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.Value()->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf, theClipRange, thePickResult))
|
||||
if (anIter.Value()->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf,
|
||||
theIsHollow, theClipRange, thePickResult))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -529,6 +535,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
const gp_Dir aCylNorm (gp::DZ().Transformed (theTrsf));
|
||||
@@ -589,7 +596,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
{
|
||||
aVertices[anIdx] = anIter.Value()->myVertices[anIdx];
|
||||
}
|
||||
if (anIter.Value()->IsDotInside (aPoints[i], aVertices))
|
||||
if (anIter.Value()->isDotInside (aPoints[i], aVertices))
|
||||
{
|
||||
isInside = true;
|
||||
break;
|
||||
@@ -607,7 +614,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
}
|
||||
for (SelectMgr_TriangFrustums::Iterator anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.Value()->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf, theInside))
|
||||
if (anIter.Value()->OverlapsCylinder (theBottomRad, theTopRad, theHeight, theTrsf, theIsHollow, theInside))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -615,6 +622,109 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCylinder (const Standar
|
||||
return false;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const
|
||||
{
|
||||
Standard_ASSERT_RAISE (mySelectionType == SelectMgr_SelectionType_Polyline,
|
||||
"Error! SelectMgr_TriangularFrustumSet::Overlaps() should be called after selection frustum initialization");
|
||||
for (SelectMgr_TriangFrustums::Iterator anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (anIter.Value()->OverlapsCircle (theRadius, theTrsf, theIsFilled, theClipRange, thePickResult))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : OverlapsCircle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::OverlapsCircle (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside) const
|
||||
{
|
||||
const gp_Pnt aCenter (gp::Origin().Transformed (theTrsf));
|
||||
const gp_Vec aVecPlane1 (myFrustums.First()->myVertices[0], myFrustums.First()->myVertices[1]);
|
||||
const gp_Vec aVecPlane2 (myFrustums.First()->myVertices[0], myFrustums.First()->myVertices[2]);
|
||||
|
||||
const gp_Dir aDirNorm (aVecPlane1.Crossed (aVecPlane2));
|
||||
const gp_Pln aPln (myFrustums.First()->myVertices[0], aDirNorm);
|
||||
Standard_Real aCoefA, aCoefB, aCoefC, aCoefD;
|
||||
aPln.Coefficients (aCoefA, aCoefB, aCoefC, aCoefD);
|
||||
|
||||
const Standard_Real aT = -(aCenter.XYZ().Dot (aDirNorm.XYZ()) + aCoefD) / aDirNorm.Dot (aDirNorm);
|
||||
const gp_Pnt aCenterProject (aCoefA * aT + aCenter.X(),
|
||||
aCoefB * aT + aCenter.Y(),
|
||||
aCoefC * aT + aCenter.Z());
|
||||
|
||||
gp_Pnt aVerticesBuf[3];
|
||||
TColgp_Array1OfPnt aVertices (aVerticesBuf[0], 0, 2);
|
||||
|
||||
if (!theIsFilled)
|
||||
{
|
||||
for (SelectMgr_TriangFrustums::Iterator anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (!anIter.Value()->OverlapsCircle (theRadius, theTrsf, theIsFilled, theInside))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (myToAllowOverlap)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (isIntersectBoundary (theRadius, theTrsf, theIsFilled))
|
||||
{
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside &= Standard_False;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (SelectMgr_TriangFrustums::Iterator anIter (myFrustums); anIter.More(); anIter.Next())
|
||||
{
|
||||
if (!anIter.Value()->OverlapsCircle (theRadius, theTrsf, theIsFilled, theInside))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (myToAllowOverlap)
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (isIntersectBoundary (theRadius, theTrsf, theIsFilled))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
if (theInside != NULL)
|
||||
{
|
||||
*theInside &= Standard_False;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetPlanes
|
||||
// purpose :
|
||||
@@ -638,6 +748,127 @@ void SelectMgr_TriangularFrustumSet::SetAllowOverlapDetection (const Standard_Bo
|
||||
myToAllowOverlap = theIsToAllow;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : PointInTriangle
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::pointInTriangle (const gp_Pnt& thePnt,
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3)
|
||||
{
|
||||
gp_Vec a = theV1.XYZ() - thePnt.XYZ();
|
||||
gp_Vec b = theV2.XYZ() - thePnt.XYZ();
|
||||
gp_Vec c = theV3.XYZ() - thePnt.XYZ();
|
||||
|
||||
gp_Vec u = b.Crossed (c);
|
||||
gp_Vec v = c.Crossed (a);
|
||||
gp_Vec w = a.Crossed (b);
|
||||
|
||||
if (u.Dot (v) < 0.0 || u.Dot (w) < 0.0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : segmentSegmentIntersection
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::segmentSegmentIntersection (const gp_Pnt& theStartPnt1,
|
||||
const gp_Pnt& theEndPnt1,
|
||||
const gp_Pnt& theStartPnt2,
|
||||
const gp_Pnt& theEndPnt2)
|
||||
{
|
||||
gp_XYZ aVec1 = theEndPnt1.XYZ() - theStartPnt1.XYZ();
|
||||
gp_XYZ aVec2 = theEndPnt2.XYZ() - theStartPnt2.XYZ();
|
||||
gp_XYZ aVec21 = theStartPnt2.XYZ() - theStartPnt1.XYZ();
|
||||
gp_XYZ aVec12 = theStartPnt1.XYZ() - theStartPnt2.XYZ();
|
||||
if (Abs (aVec21.DotCross (aVec1, aVec2)) > Precision::Confusion() ||
|
||||
Abs (aVec12.DotCross (aVec2, aVec1)) > Precision::Confusion())
|
||||
{
|
||||
// lines are not coplanar
|
||||
return false;
|
||||
}
|
||||
|
||||
double aValue1 = aVec21.Crossed (aVec2).Dot (aVec1.Crossed (aVec2)) / aVec1.Crossed (aVec2).SquareModulus();
|
||||
double aValue2 = aVec12.Crossed (aVec1).Dot (aVec2.Crossed (aVec1)) / aVec2.Crossed (aVec1).SquareModulus();
|
||||
if (aValue1 < 0.0 || aValue1 > 1.0 || aValue2 < 0.0 || aValue2 > 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : isIntersectBoundary
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::isIntersectBoundary (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled) const
|
||||
{
|
||||
Standard_Integer aFacesNb = myBoundaryPoints.Size() / 2;
|
||||
|
||||
const gp_Pnt& aCircCenter = theTrsf.TranslationPart();
|
||||
gp_Ax2 anAxis;
|
||||
anAxis.Transform (theTrsf);
|
||||
Handle(Geom_Circle) aCirc = new Geom_Circle (anAxis, theRadius);
|
||||
|
||||
gp_Dir aCircNorm = gp_Dir(0, 0, 1).Transformed (theTrsf);
|
||||
Handle(Geom_Surface) aCircPlane = new Geom_Plane(aCircCenter, aCircNorm);
|
||||
|
||||
for (Standard_Integer anIdx = myBoundaryPoints.Lower(); anIdx < aFacesNb + myBoundaryPoints.Lower(); anIdx++)
|
||||
{
|
||||
gp_Pnt aFace[4] = { myBoundaryPoints.Value (anIdx),
|
||||
myBoundaryPoints.Value (anIdx + aFacesNb),
|
||||
myBoundaryPoints.Value (anIdx % aFacesNb + 1 + aFacesNb),
|
||||
myBoundaryPoints.Value (anIdx % aFacesNb + 1) };
|
||||
|
||||
gp_Dir aBndPlaneNorm = gp_Vec (aFace[0], aFace[1]).Crossed (gp_Vec(aFace[0], aFace[2]));
|
||||
Handle(Geom_Surface) aBndPlane = new Geom_Plane(aFace[0], aBndPlaneNorm);
|
||||
|
||||
GeomInt_IntSS anInterSS (aCircPlane, aBndPlane, Precision::Confusion());
|
||||
if (!anInterSS.IsDone() || anInterSS.NbLines() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const Handle(Geom_Line)& anInterLine = Handle(Geom_Line)::DownCast (anInterSS.Line(1));
|
||||
Standard_Real aDistance = anInterLine->Lin().Distance (aCircCenter);
|
||||
if (aDistance > theRadius)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gp_Lin aLine = anInterLine->Lin();
|
||||
gp_Lin aNormalLine = aLine.Normal (aCircCenter);
|
||||
gp_Pnt aCrossPoint = aCircCenter.Translated (aNormalLine.Direction().Reversed().XYZ() * aDistance);
|
||||
|
||||
Standard_Real anOffset = Sqrt (theRadius * theRadius - aDistance * aDistance);
|
||||
// Line-circle intersection points
|
||||
gp_Pnt aP1 = aCrossPoint.Translated (aLine.Direction().XYZ() * anOffset);
|
||||
gp_Pnt aP2 = aCrossPoint.Translated (aLine.Direction().Reversed().XYZ() * anOffset);
|
||||
|
||||
if (pointInTriangle (aP1, aFace[0], aFace[1], aFace[2])
|
||||
|| pointInTriangle (aP1, aFace[0], aFace[2], aFace[3])
|
||||
|| pointInTriangle (aP2, aFace[0], aFace[1], aFace[2])
|
||||
|| pointInTriangle (aP2, aFace[0], aFace[2], aFace[3]))
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (theIsFilled
|
||||
|| segmentSegmentIntersection (aP1, aP2, aFace[0], aFace[1])
|
||||
|| segmentSegmentIntersection (aP1, aP2, aFace[1], aFace[2])
|
||||
|| segmentSegmentIntersection (aP1, aP2, aFace[2], aFace[3])
|
||||
|| segmentSegmentIntersection (aP1, aP2, aFace[0], aFace[3]))
|
||||
{
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : isIntersectBoundary
|
||||
// purpose :
|
||||
@@ -669,7 +900,7 @@ Standard_Boolean SelectMgr_TriangularFrustumSet::isIntersectBoundary (const gp_P
|
||||
// purpose : Moller-Trumbore ray-triangle intersection test
|
||||
//=======================================================================
|
||||
Standard_Boolean SelectMgr_TriangularFrustumSet::segmentTriangleIntersection (const gp_Pnt& theOrig, const gp_Vec& theDir,
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3)
|
||||
{
|
||||
gp_Vec aPVec, aTVec, aQVec;
|
||||
Standard_Real aD, aInvD, anU, aV, aT;
|
||||
|
@@ -124,6 +124,7 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
@@ -133,8 +134,24 @@ public:
|
||||
const Standard_Real theTopRad,
|
||||
const Standard_Real theHeight,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsHollow,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses theBottomRad
|
||||
//! and theTopRad, height theHeight and transformation to apply theTrsf.
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
const SelectMgr_ViewClipRange& theClipRange,
|
||||
SelectBasics_PickResult& thePickResult) const Standard_OVERRIDE;
|
||||
|
||||
//! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses theBottomRad
|
||||
//! and theTopRad, height theHeight and transformation to apply theTrsf.
|
||||
Standard_EXPORT virtual Standard_Boolean OverlapsCircle (const Standard_Real theBottomRad,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled,
|
||||
Standard_Boolean* theInside = NULL) const Standard_OVERRIDE;
|
||||
|
||||
//! Stores plane equation coefficients (in the following form:
|
||||
//! Ax + By + Cz + D = 0) to the given vector
|
||||
Standard_EXPORT virtual void GetPlanes (NCollection_Vector<SelectMgr_Vec4>& thePlaneEquations) const Standard_OVERRIDE;
|
||||
@@ -151,15 +168,34 @@ private:
|
||||
//! Checks whether the segment intersects with the boundary of the current volume selection
|
||||
Standard_EXPORT Standard_Boolean isIntersectBoundary (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2) const;
|
||||
|
||||
//! Checks whether the circle intersects with the boundary of the current volume selection
|
||||
Standard_EXPORT Standard_Boolean isIntersectBoundary (const Standard_Real theRadius,
|
||||
const gp_Trsf& theTrsf,
|
||||
const Standard_Boolean theIsFilled) const;
|
||||
|
||||
//! Checks whether the triangle intersects with a segment
|
||||
Standard_EXPORT Standard_Boolean segmentTriangleIntersection (const gp_Pnt &theOrig, const gp_Vec& theDir,
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3) const;
|
||||
Standard_EXPORT static Standard_Boolean segmentTriangleIntersection (const gp_Pnt &theOrig, const gp_Vec& theDir,
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3);
|
||||
|
||||
Standard_EXPORT static Standard_Boolean segmentSegmentIntersection (const gp_Pnt& theStartPnt1,
|
||||
const gp_Pnt& theEndPnt1,
|
||||
const gp_Pnt& theStartPnt2,
|
||||
const gp_Pnt& theEndPnt2);
|
||||
|
||||
Standard_EXPORT static Standard_Boolean pointInTriangle (const gp_Pnt& thePnt,
|
||||
const gp_Pnt& theV1, const gp_Pnt& theV2, const gp_Pnt& theV3);
|
||||
|
||||
private:
|
||||
|
||||
SelectMgr_TriangFrustums myFrustums; //!< set of triangular frustums
|
||||
SelectionPolyline mySelPolyline; //!< parameters of selection polyline (it is used to build triangle frustum set)
|
||||
TColgp_Array1OfPnt myBoundaryPoints; //!< boundary points
|
||||
//! 1_____2
|
||||
//! /| |\ .
|
||||
//! 4/_|_____|_\3
|
||||
//! | 5|_____|6 |
|
||||
//! | / \ |
|
||||
//! 8|/_________\|7
|
||||
Standard_Boolean myToAllowOverlap; //!< flag to detect only fully included sensitives or not
|
||||
};
|
||||
|
||||
|
@@ -46,9 +46,3 @@ ShapeAnalysis_WireVertex.cxx
|
||||
ShapeAnalysis_WireVertex.hxx
|
||||
ShapeAnalysis_CanonicalRecognition.cxx
|
||||
ShapeAnalysis_CanonicalRecognition.hxx
|
||||
ShapeAnalysis_FuncSphereLSDist.cxx
|
||||
ShapeAnalysis_FuncSphereLSDist.hxx
|
||||
ShapeAnalysis_FuncCylinderLSDist.cxx
|
||||
ShapeAnalysis_FuncCylinderLSDist.hxx
|
||||
ShapeAnalysis_FuncConeLSDist.cxx
|
||||
ShapeAnalysis_FuncConeLSDist.hxx
|
||||
|
@@ -51,9 +51,9 @@
|
||||
#include <BRepLib_FindSurface.hxx>
|
||||
#include <TColgp_HArray1OfXYZ.hxx>
|
||||
#include <math_Vector.hxx>
|
||||
#include <ShapeAnalysis_FuncSphereLSDist.hxx>
|
||||
#include <ShapeAnalysis_FuncCylinderLSDist.hxx>
|
||||
#include <ShapeAnalysis_FuncConeLSDist.hxx>
|
||||
#include <GeomConvert_FuncSphereLSDist.hxx>
|
||||
#include <GeomConvert_FuncCylinderLSDist.hxx>
|
||||
#include <GeomConvert_FuncConeLSDist.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
#include <GCPnts_QuasiUniformAbscissa.hxx>
|
||||
@@ -834,9 +834,9 @@ Standard_Boolean ShapeAnalysis_CanonicalRecognition::GetSurfaceByLS(const TopoDS
|
||||
//
|
||||
Standard_Real aTol = Precision::Confusion();
|
||||
math_MultipleVarFunction* aPFunc;
|
||||
ShapeAnalysis_FuncSphereLSDist aFuncSph(aPoints);
|
||||
ShapeAnalysis_FuncCylinderLSDist aFuncCyl(aPoints, thePos.Direction());
|
||||
ShapeAnalysis_FuncConeLSDist aFuncCon(aPoints, thePos.Direction());
|
||||
GeomConvert_FuncSphereLSDist aFuncSph(aPoints);
|
||||
GeomConvert_FuncCylinderLSDist aFuncCyl(aPoints, thePos.Direction());
|
||||
GeomConvert_FuncConeLSDist aFuncCon(aPoints, thePos.Direction());
|
||||
if (theTarget == GeomAbs_Sphere)
|
||||
{
|
||||
aPFunc = (math_MultipleVarFunction*)&aFuncSph;
|
||||
|
@@ -982,84 +982,24 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ModifE1 == ModifE2 ) {
|
||||
if( !ModifE1 && !ModifE2 ) {
|
||||
gp_Pnt P0( (pi1.X()+pi2.X())/2, (pi1.Y()+pi2.Y())/2, (pi1.Z()+pi2.Z())/2 );
|
||||
tolV = Max( (pi1.Distance(pi2)/2)*1.00001, Precision::Confusion() );
|
||||
B.MakeVertex(V,P0,tolV);
|
||||
MaxTolVert = Max(MaxTolVert,tolV);
|
||||
if( !ModifE1 && !ModifE2 ) {
|
||||
Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
|
||||
V, tolV, boxes);
|
||||
if(isEdgeSplit2) {
|
||||
NbSplit++;
|
||||
num2--;
|
||||
}
|
||||
if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
|
||||
NbSplit++;
|
||||
num1--;
|
||||
break;
|
||||
}
|
||||
if(isEdgeSplit2)
|
||||
continue;
|
||||
Standard_Boolean isEdgeSplit2 = SplitEdge1(sewd, face, num2, param2,
|
||||
V, tolV, boxes);
|
||||
if(isEdgeSplit2) {
|
||||
NbSplit++;
|
||||
num2--;
|
||||
}
|
||||
else if (PVF1.Distance(PVF2) < MaxTolVert || PVF1.Distance(PVL2) < MaxTolVert ||
|
||||
PVL1.Distance(PVF2) < MaxTolVert || PVL1.Distance(PVL2) < MaxTolVert)
|
||||
{
|
||||
ShapeBuild_Edge sbe;
|
||||
ShapeAnalysis_Edge sae;
|
||||
Standard_Real dist1 = pi1.Distance(PVF1);
|
||||
Standard_Real dist2 = pi1.Distance(PVL1);
|
||||
TopoDS_Edge NewE1, NewAjE1, edgeAj1;
|
||||
Standard_Integer n;
|
||||
if(dist1 < dist2)
|
||||
{
|
||||
NewE1 = sbe.CopyReplaceVertices(edge1,V,VL1);
|
||||
n = num1 - 1;
|
||||
edgeAj1 = sewd->Edge(n);
|
||||
NewAjE1 = sbe.CopyReplaceVertices(edgeAj1,sae.FirstVertex(edgeAj1),V);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewE1 = sbe.CopyReplaceVertices(edge1,VF1,V);
|
||||
n = num1 + 1;
|
||||
edgeAj1 = sewd->Edge(n);
|
||||
NewAjE1 = sbe.CopyReplaceVertices(edgeAj1,V,sae.LastVertex(edgeAj1));
|
||||
}
|
||||
myContext->Replace(edge1,NewE1);
|
||||
myContext->Replace(edgeAj1,NewAjE1);
|
||||
sewd->Set(NewE1,num1);
|
||||
sewd->Set(NewAjE1,n);
|
||||
boxes.Bind(NewE1,B1);
|
||||
Bnd_Box2d BAj1 = boxes.Find(edgeAj1);
|
||||
boxes.Bind(NewAjE1,BAj1);
|
||||
edge1 = NewE1;
|
||||
|
||||
dist1 = pi2.Distance(PVF2);
|
||||
dist2 = pi2.Distance(PVL2);
|
||||
TopoDS_Edge NewE2, NewAjE2, edgeAj2;
|
||||
if(dist1 < dist2)
|
||||
{
|
||||
NewE2 = sbe.CopyReplaceVertices(edge2,V,VL2);
|
||||
n = num2 - 1;
|
||||
edgeAj2 = sewd->Edge(n);
|
||||
NewAjE2 = sbe.CopyReplaceVertices(edgeAj2,sae.FirstVertex(edgeAj2),V);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewE2 = sbe.CopyReplaceVertices(edge2,VF2,V);
|
||||
n = (num2 + 1 > sewd->NbEdges())?(num2 + 1 - sewd->NbEdges()):(num2 + 1);
|
||||
edgeAj2 = sewd->Edge(n);
|
||||
NewAjE2 = sbe.CopyReplaceVertices(edgeAj2,V,sae.LastVertex(edgeAj2));
|
||||
}
|
||||
myContext->Replace(edge2,NewE2);
|
||||
myContext->Replace(edgeAj2,NewAjE2);
|
||||
sewd->Set(NewE2,num2);
|
||||
sewd->Set(NewAjE2,n);
|
||||
boxes.Bind(NewE2,B2);
|
||||
Bnd_Box2d BAj2 = boxes.Find(edgeAj2);
|
||||
boxes.Bind(NewAjE2,BAj2);
|
||||
edge2 = NewE2;
|
||||
if(SplitEdge1(sewd, face, num1, param1, V, tolV, boxes)) {
|
||||
NbSplit++;
|
||||
num1--;
|
||||
break;
|
||||
}
|
||||
if(isEdgeSplit2)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( Tr1.PositionOnCurve() == IntRes2d_Middle &&
|
||||
@@ -1376,29 +1316,6 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
if(P01.Distance(PV12)<tolV1) {
|
||||
tolV1 += P01.Distance(PV12);
|
||||
B.UpdateVertex(NewV1,tolV1);
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
TopoDS_Edge eprev = sewd->Edge(num2+dnum1-1);
|
||||
if (sae.LastVertex(eprev).IsSame(V12))
|
||||
{
|
||||
TopoDS_Vertex VLprev = sae.LastVertex(eprev);
|
||||
TopoDS_Edge NewEprev =
|
||||
sbe.CopyReplaceVertices(eprev,sae.FirstVertex(eprev),NewV1);
|
||||
myContext->Replace(eprev,NewEprev);
|
||||
sewd->Set(NewEprev,num2+dnum1-1);
|
||||
Bnd_Box2d Bprev = boxes.Find(eprev);
|
||||
boxes.Bind(NewEprev,Bprev); // update boxes
|
||||
|
||||
if(VLprev.Orientation()==NewV1.Orientation()) {
|
||||
myContext->Replace(VLprev,NewV1);
|
||||
}
|
||||
else {
|
||||
myContext->Replace(VLprev,NewV1.Reversed());
|
||||
}
|
||||
}
|
||||
if(V12.Orientation()==NewV1.Orientation()) {
|
||||
myContext->Replace(V12,NewV1);
|
||||
V12 = NewV1;
|
||||
@@ -1408,36 +1325,16 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
V12 = TopoDS::Vertex(NewV1.Reversed());
|
||||
}
|
||||
nbReplaced++; //gka 06.09.04
|
||||
akey1 = 1;
|
||||
}
|
||||
if(P01.Distance(PV22)<tolV1) {
|
||||
tolV1 += P01.Distance(PV22);
|
||||
B.UpdateVertex(NewV1,tolV1);
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV1,V22);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
Standard_Integer n =
|
||||
(num2+dnum1+1 > sewd->NbEdges())?(num2+dnum1+1 - sewd->NbEdges()):(num2+dnum1+1);
|
||||
TopoDS_Edge enext = sewd->Edge(n);
|
||||
if (sae.FirstVertex(enext).IsSame(V22))
|
||||
{
|
||||
TopoDS_Vertex VFnext = sae.FirstVertex(enext);
|
||||
TopoDS_Edge NewEnext =
|
||||
sbe.CopyReplaceVertices(enext,NewV1,sae.LastVertex(enext));
|
||||
myContext->Replace(enext,NewEnext);
|
||||
sewd->Set(NewEnext,n);
|
||||
Bnd_Box2d Bnext = boxes.Find(enext);
|
||||
boxes.Bind(NewEnext,Bnext); // update boxes
|
||||
|
||||
if(VFnext.Orientation()==NewV1.Orientation()) {
|
||||
myContext->Replace(VFnext,NewV1);
|
||||
}
|
||||
else {
|
||||
myContext->Replace(VFnext,NewV1.Reversed());
|
||||
}
|
||||
}
|
||||
akey1 = 1;
|
||||
}
|
||||
if(P01.Distance(PV22)<tolV1) {
|
||||
tolV1 += P01.Distance(PV22);
|
||||
B.UpdateVertex(NewV1,tolV1);
|
||||
if(V22.Orientation()==NewV1.Orientation()) {
|
||||
myContext->Replace(V22,NewV1);
|
||||
V22 = NewV1;
|
||||
@@ -1447,34 +1344,16 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
V22 = TopoDS::Vertex(NewV1.Reversed());
|
||||
}
|
||||
nbReplaced++; //gka 06.09.04
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV1);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
akey1 = 2;
|
||||
}
|
||||
if(P02.Distance(PV12)<tolV2) {
|
||||
tolV2 += P02.Distance(PV12);
|
||||
B.UpdateVertex(NewV2,tolV2);
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
TopoDS_Edge eprev = sewd->Edge(num2+dnum1-1);
|
||||
if (sae.LastVertex(eprev).IsSame(V12))
|
||||
{
|
||||
TopoDS_Vertex VLprev = sae.LastVertex(eprev);
|
||||
TopoDS_Edge NewEprev =
|
||||
sbe.CopyReplaceVertices(eprev,sae.FirstVertex(eprev),NewV2);
|
||||
myContext->Replace(eprev,NewEprev);
|
||||
sewd->Set(NewEprev,num2+dnum1-1);
|
||||
Bnd_Box2d Bprev = boxes.Find(eprev);
|
||||
boxes.Bind(NewEprev,Bprev); // update boxes
|
||||
|
||||
if(VLprev.Orientation()==NewV2.Orientation()) {
|
||||
myContext->Replace(VLprev,NewV2);
|
||||
}
|
||||
else {
|
||||
myContext->Replace(VLprev,NewV2.Reversed());
|
||||
}
|
||||
}
|
||||
if(V12.Orientation()==NewV2.Orientation()) {
|
||||
myContext->Replace(V12,NewV2);
|
||||
V12 = NewV2;
|
||||
@@ -1484,36 +1363,16 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
V12 = TopoDS::Vertex(NewV2.Reversed());
|
||||
}
|
||||
nbReplaced++; //gka 06.09.04
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,NewV2,V22);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
akey2 = 1;
|
||||
}
|
||||
if(P02.Distance(PV22)<tolV2) {
|
||||
tolV2 += P02.Distance(PV22);
|
||||
B.UpdateVertex(NewV2,tolV2);
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
Standard_Integer n =
|
||||
(num2+dnum1+1 > sewd->NbEdges())?(num2+dnum1+1 - sewd->NbEdges()):(num2+dnum1+1);
|
||||
TopoDS_Edge enext = sewd->Edge(n);
|
||||
if (sae.FirstVertex(enext).IsSame(V22))
|
||||
{
|
||||
TopoDS_Vertex VFnext = sae.FirstVertex(enext);
|
||||
TopoDS_Edge NewEnext =
|
||||
sbe.CopyReplaceVertices(enext,NewV2,sae.LastVertex(enext));
|
||||
myContext->Replace(enext,NewEnext);
|
||||
sewd->Set(NewEnext,n);
|
||||
Bnd_Box2d Bnext = boxes.Find(enext);
|
||||
boxes.Bind(NewEnext,Bnext); // update boxes
|
||||
|
||||
if(VFnext.Orientation()==NewV2.Orientation()) {
|
||||
myContext->Replace(VFnext,NewV2);
|
||||
}
|
||||
else {
|
||||
myContext->Replace(VFnext,NewV2.Reversed());
|
||||
}
|
||||
}
|
||||
if(V22.Orientation()==NewV2.Orientation()) {
|
||||
myContext->Replace(V22,NewV2);
|
||||
V22 = NewV2;
|
||||
@@ -1523,6 +1382,11 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
V22 = TopoDS::Vertex(NewV2.Reversed());
|
||||
}
|
||||
nbReplaced++; //gka 06.09.04
|
||||
TopoDS_Edge NewE = sbe.CopyReplaceVertices(edge2,V12,NewV2);
|
||||
myContext->Replace(edge2,NewE);
|
||||
sewd->Set(NewE,num2+dnum1);
|
||||
boxes.Bind(NewE,B2); // update boxes
|
||||
edge2 = NewE;
|
||||
akey2 = 2;
|
||||
}
|
||||
Standard_Integer dnum2=0, numseg2=num2+dnum1;
|
||||
@@ -1567,11 +1431,6 @@ Standard_Boolean ShapeFix_IntersectionTool::FixSelfIntersectWire
|
||||
}
|
||||
}
|
||||
}
|
||||
if( akey1>0 || akey2>0 ) {
|
||||
if( UnionVertexes(sewd, edge1, edge2, num2+dnum1, boxes, B2) )
|
||||
nbReplaced ++;
|
||||
}
|
||||
|
||||
// remove segment
|
||||
sewd->Remove(numseg2);
|
||||
sewd->Remove(numseg1);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@
|
||||
#include <Standard_Std.hxx>
|
||||
#include <Standard_Stream.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
class Standard_Transient;
|
||||
|
||||
@@ -71,7 +72,7 @@ namespace opencascade {
|
||||
}
|
||||
|
||||
//! Move constructor
|
||||
handle (handle&& theHandle) noexcept : entity(theHandle.entity)
|
||||
handle (handle&& theHandle) Standard_Noexcept : entity(theHandle.entity)
|
||||
{
|
||||
theHandle.entity = 0;
|
||||
}
|
||||
@@ -112,7 +113,7 @@ namespace opencascade {
|
||||
}
|
||||
|
||||
//! Move operator
|
||||
handle& operator= (handle&& theHandle) noexcept
|
||||
handle& operator= (handle&& theHandle) Standard_Noexcept
|
||||
{
|
||||
std::swap (this->entity, theHandle.entity);
|
||||
return *this;
|
||||
|
@@ -315,5 +315,21 @@
|
||||
#define Standard_ATOMIC(theType) theType
|
||||
#endif
|
||||
|
||||
//! @def Standard_Noexcept
|
||||
//! Definition of Standard_Noexcept:
|
||||
//! if noexcept is accessible, Standard_Noexcept is "noexcept" and "throw()" otherwise.
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1900
|
||||
#define Standard_Noexcept noexcept
|
||||
#else
|
||||
#define Standard_Noexcept throw()
|
||||
#endif
|
||||
#else
|
||||
#if __cplusplus >= 201103L
|
||||
#define Standard_Noexcept noexcept
|
||||
#else
|
||||
#define Standard_Noexcept throw()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <Select3D_SensitiveFace.hxx>
|
||||
#include <Select3D_SensitiveGroup.hxx>
|
||||
#include <Select3D_SensitivePoint.hxx>
|
||||
#include <Select3D_SensitivePoly.hxx>
|
||||
#include <Select3D_SensitiveSegment.hxx>
|
||||
#include <Select3D_SensitiveSphere.hxx>
|
||||
#include <Select3D_SensitiveTriangulation.hxx>
|
||||
@@ -60,7 +61,6 @@
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
|
||||
#define BVH_PRIMITIVE_LIMIT 800000
|
||||
|
||||
@@ -249,6 +249,7 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
|
||||
case TopAbs_FACE:
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face (theShape);
|
||||
|
||||
Select3D_EntitySequence aSensitiveList;
|
||||
GetSensitiveForFace (aFace, theOwner,
|
||||
aSensitiveList,
|
||||
@@ -266,151 +267,15 @@ void StdSelect_BRepSelectionTool::ComputeSensitive (const TopoDS_Shape& theShape
|
||||
{
|
||||
TopTools_IndexedMapOfShape aSubfacesMap;
|
||||
TopExp::MapShapes (theShape, TopAbs_FACE, aSubfacesMap);
|
||||
if (aSubfacesMap.Extent() == 2) // detect cone
|
||||
|
||||
if (!GetSensitiveForCylinder (aSubfacesMap, theOwner, theSelection))
|
||||
{
|
||||
const TopoDS_Face* aFaces[2] =
|
||||
for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex)
|
||||
{
|
||||
&TopoDS::Face (aSubfacesMap.FindKey (1)),
|
||||
&TopoDS::Face (aSubfacesMap.FindKey (2))
|
||||
};
|
||||
|
||||
TopLoc_Location aLocSurf[2];
|
||||
const Handle(Geom_Surface)* aSurfaces[2] =
|
||||
{
|
||||
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
|
||||
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1])
|
||||
};
|
||||
|
||||
Standard_Integer aConIndex = 0;
|
||||
Handle(Geom_ConicalSurface) aGeomCone = Handle(Geom_ConicalSurface)::DownCast (*aSurfaces[0]);
|
||||
Handle(Geom_Plane) aGeomPln;
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
aGeomPln = Handle(Geom_Plane)::DownCast (*aSurfaces[1]);
|
||||
ComputeSensitive (aSubfacesMap.FindKey (aShIndex), theOwner,
|
||||
theSelection,
|
||||
theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
|
||||
}
|
||||
else
|
||||
{
|
||||
aConIndex = 1;
|
||||
aGeomCone = Handle(Geom_ConicalSurface)::DownCast (*aSurfaces[1]);
|
||||
aGeomPln = Handle(Geom_Plane)::DownCast (*aSurfaces[0]);
|
||||
}
|
||||
if (!aGeomCone.IsNull()
|
||||
&& !aGeomPln.IsNull()
|
||||
&& aGeomPln->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cone aCone = BRepAdaptor_Surface (*aFaces[aConIndex]).Cone();
|
||||
const Standard_Real aRad1 = aCone.RefRadius();
|
||||
const Standard_Real aHeight = (aRad1 != 0.0)
|
||||
? aRad1 / Abs (Tan (aCone.SemiAngle()))
|
||||
: aCone.Location().Distance (aGeomPln->Location().Transformed (aLocSurf[aConIndex == 0 ? 1 : 0]));
|
||||
const Standard_Real aRad2 = (aRad1 != 0.0) ? 0.0 : Tan (aCone.SemiAngle()) * aHeight;
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCone.Position(), gp_Ax3());
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aSubfacesMap.Extent() == 3) // detect cylinder or truncated cone
|
||||
{
|
||||
const TopoDS_Face* aFaces[3] =
|
||||
{
|
||||
&TopoDS::Face (aSubfacesMap.FindKey (1)),
|
||||
&TopoDS::Face (aSubfacesMap.FindKey (2)),
|
||||
&TopoDS::Face (aSubfacesMap.FindKey (3))
|
||||
};
|
||||
|
||||
TopLoc_Location aLocSurf[3];
|
||||
const Handle(Geom_Surface)* aSurfaces[3] =
|
||||
{
|
||||
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
|
||||
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1]),
|
||||
&BRep_Tool::Surface (*aFaces[2], aLocSurf[2])
|
||||
};
|
||||
|
||||
Standard_Integer aConIndex = -1, aNbPlanes = 0;
|
||||
Handle(Geom_ConicalSurface) aGeomCone;
|
||||
Handle(Geom_CylindricalSurface) aGeomCyl;
|
||||
Handle(Geom_Plane) aGeomPlanes[2];
|
||||
const TopLoc_Location* aGeomPlanesLoc[2];
|
||||
for (Standard_Integer aSurfIter = 0; aSurfIter < 3; ++aSurfIter)
|
||||
{
|
||||
const Handle(Geom_Surface)& aSurf = *aSurfaces[aSurfIter];
|
||||
if (aConIndex == -1)
|
||||
{
|
||||
aGeomCone = Handle (Geom_ConicalSurface)::DownCast (aSurf);
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
aConIndex = aSurfIter;
|
||||
continue;
|
||||
}
|
||||
aGeomCyl = Handle (Geom_CylindricalSurface)::DownCast (aSurf);
|
||||
if (!aGeomCyl.IsNull())
|
||||
{
|
||||
aConIndex = aSurfIter;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (aNbPlanes < 2)
|
||||
{
|
||||
aGeomPlanes[aNbPlanes] = Handle(Geom_Plane)::DownCast (aSurf);
|
||||
if (!aGeomPlanes[aNbPlanes].IsNull())
|
||||
{
|
||||
aGeomPlanesLoc[aNbPlanes] = &aLocSurf[aSurfIter];
|
||||
++aNbPlanes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
if (!aGeomPlanes[0].IsNull()
|
||||
&& !aGeomPlanes[1].IsNull()
|
||||
&& aGeomPlanes[0]->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular())
|
||||
&& aGeomPlanes[1]->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cone aCone = BRepAdaptor_Surface (*aFaces[aConIndex]).Cone();
|
||||
const Standard_Real aRad1 = aCone.RefRadius();
|
||||
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
|
||||
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCone.Position(), gp_Ax3());
|
||||
const Standard_Real aTriangleHeight = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 / Tan (aCone.SemiAngle())
|
||||
: aRad1 / Tan (Abs (aCone.SemiAngle())) - aHeight;
|
||||
const Standard_Real aRad2 = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 * (aTriangleHeight + aHeight) / aTriangleHeight
|
||||
: aRad1 * aTriangleHeight / (aTriangleHeight + aHeight);
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!aGeomCyl.IsNull())
|
||||
{
|
||||
if (!aGeomPlanes[0].IsNull()
|
||||
&& !aGeomPlanes[1].IsNull()
|
||||
&& aGeomPlanes[0]->Position().Direction().IsEqual (aGeomCyl->Position().Direction(), Precision::Angular())
|
||||
&& aGeomPlanes[1]->Position().Direction().IsEqual (aGeomCyl->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cylinder aCyl = BRepAdaptor_Surface (*aFaces[aConIndex]).Cylinder();
|
||||
const Standard_Real aRad = aCyl.Radius();
|
||||
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
|
||||
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCyl.Position(), gp_Ax3());
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Standard_Integer aShIndex = 1; aShIndex <= aSubfacesMap.Extent(); ++aShIndex)
|
||||
{
|
||||
ComputeSensitive (aSubfacesMap.FindKey (aShIndex), theOwner,
|
||||
theSelection,
|
||||
theDeflection, theDeviationAngle, theNbPOnEdge, theMaxParam, isAutoTriangulation);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -625,8 +490,7 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
|
||||
}
|
||||
else
|
||||
{
|
||||
theSensitive = new Select3D_SensitiveCircle (theOwner, aCircle,
|
||||
aParamFirst, aParamLast, Standard_False, 16);
|
||||
theSensitive = new Select3D_SensitivePoly (theOwner, aCircle, aParamFirst, aParamLast, Standard_False);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -697,6 +561,57 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : getCylinderHeight
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Real getCylinderHeight (const Handle(Poly_Triangulation)& theTriangulation,
|
||||
const TopLoc_Location& theLoc)
|
||||
{
|
||||
Bnd_Box aBox;
|
||||
gp_Trsf aScaleTrsf;
|
||||
aScaleTrsf.SetScaleFactor (theLoc.Transformation().ScaleFactor());
|
||||
theTriangulation->MinMax (aBox, aScaleTrsf);
|
||||
return aBox.CornerMax().Z() - aBox.CornerMin().Z();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : isCylinderOrCone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Boolean isCylinderOrCone (const TopoDS_Face& theHollowCylinder, const gp_Pnt& theLocation, gp_Dir& theDirection)
|
||||
{
|
||||
Standard_Integer aCirclesNb = 0;
|
||||
Standard_Boolean isCylinder = Standard_False;
|
||||
gp_Pnt aPos;
|
||||
|
||||
TopExp_Explorer anEdgeExp;
|
||||
for (anEdgeExp.Init (theHollowCylinder, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeExp.Current());
|
||||
BRepAdaptor_Curve anAdaptor (anEdge);
|
||||
|
||||
if (anAdaptor.GetType() == GeomAbs_Circle
|
||||
&& BRep_Tool::IsClosed (anEdge))
|
||||
{
|
||||
aCirclesNb++;
|
||||
isCylinder = Standard_True;
|
||||
if (aCirclesNb == 2)
|
||||
{
|
||||
// Reverse the direction of the cylinder, relevant if the cylinder was created as a prism
|
||||
if (aPos.IsEqual (theLocation, Precision::Confusion()))
|
||||
{
|
||||
theDirection.Reverse();
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
aPos = anAdaptor.Circle().Location().XYZ();
|
||||
}
|
||||
}
|
||||
|
||||
return isCylinder;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetSensitiveEntityForFace
|
||||
//purpose :
|
||||
@@ -741,6 +656,76 @@ Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
else if (Handle(Geom_ConicalSurface) aGeomCone = Handle(Geom_ConicalSurface)::DownCast (aSurf))
|
||||
{
|
||||
gp_Dir aDummyDir;
|
||||
if (isCylinderOrCone (theFace, gp_Pnt(), aDummyDir))
|
||||
{
|
||||
const gp_Cone aCone = BRepAdaptor_Surface (theFace).Cone();
|
||||
const Standard_Real aRad1 = aCone.RefRadius();
|
||||
const Standard_Real aHeight = getCylinderHeight (aTriangulation, aLoc);
|
||||
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCone.Position(), gp::XOY());
|
||||
|
||||
Standard_Real aRad2;
|
||||
if (aRad1 == 0.0)
|
||||
{
|
||||
aRad2 = Tan (aCone.SemiAngle()) * aHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Real aTriangleHeight = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 / Tan (aCone.SemiAngle())
|
||||
: aRad1 / Tan (Abs (aCone.SemiAngle())) - aHeight;
|
||||
aRad2 = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 * (aTriangleHeight + aHeight) / aTriangleHeight
|
||||
: aRad1 * aTriangleHeight / (aTriangleHeight + aHeight);
|
||||
}
|
||||
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf, true);
|
||||
theSensitiveList.Append (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
else if (Handle(Geom_CylindricalSurface) aGeomCyl = Handle(Geom_CylindricalSurface)::DownCast (aSurf))
|
||||
{
|
||||
const gp_Cylinder aCyl = BRepAdaptor_Surface (theFace).Cylinder();
|
||||
gp_Ax3 aPos = aCyl.Position();
|
||||
gp_Dir aDirection = aPos.Direction();
|
||||
|
||||
if (isCylinderOrCone (theFace, aPos.Location(), aDirection))
|
||||
{
|
||||
const Standard_Real aRad = aCyl.Radius();
|
||||
const Standard_Real aHeight = getCylinderHeight (aTriangulation, aLoc);
|
||||
|
||||
gp_Trsf aTrsf;
|
||||
aPos.SetDirection (aDirection);
|
||||
aTrsf.SetTransformation (aPos, gp::XOY());
|
||||
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf, true);
|
||||
theSensitiveList.Append (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
else if (Handle(Geom_Plane) aGeomPlane = Handle(Geom_Plane)::DownCast (aSurf))
|
||||
{
|
||||
TopTools_IndexedMapOfShape aSubfacesMap;
|
||||
TopExp::MapShapes (theFace, TopAbs_EDGE, aSubfacesMap);
|
||||
if (aSubfacesMap.Extent() == 1)
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge (aSubfacesMap.FindKey (1));
|
||||
BRepAdaptor_Curve anAdaptor (anEdge);
|
||||
if (anAdaptor.GetType() == GeomAbs_Circle
|
||||
&& BRep_Tool::IsClosed (anEdge))
|
||||
{
|
||||
Handle(Select3D_SensitiveCircle) aSensSCyl = new Select3D_SensitiveCircle (theOwner, anAdaptor.Circle(), theInteriorFlag);
|
||||
theSensitiveList.Append (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handle(Select3D_SensitiveTriangulation) STG = new Select3D_SensitiveTriangulation (theOwner, aTriangulation, aLoc, theInteriorFlag);
|
||||
theSensitiveList.Append (STG);
|
||||
return Standard_True;
|
||||
@@ -869,7 +854,7 @@ Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_
|
||||
}
|
||||
else
|
||||
{
|
||||
theSensitiveList.Append (new Select3D_SensitiveCircle (theOwner, cu3d.Circle(), theInteriorFlag, 16));
|
||||
theSensitiveList.Append (new Select3D_SensitiveCircle (theOwner, cu3d.Circle(), theInteriorFlag));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -939,3 +924,163 @@ Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForFace (const TopoDS_
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetSensitiveForCylinder
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean StdSelect_BRepSelectionTool::GetSensitiveForCylinder (const TopTools_IndexedMapOfShape& theSubfacesMap,
|
||||
const Handle(SelectMgr_EntityOwner)& theOwner,
|
||||
const Handle(SelectMgr_Selection)& theSelection)
|
||||
{
|
||||
if (theSubfacesMap.Extent() == 2) // detect cone
|
||||
{
|
||||
const TopoDS_Face* aFaces[2] =
|
||||
{
|
||||
&TopoDS::Face (theSubfacesMap.FindKey (1)),
|
||||
&TopoDS::Face (theSubfacesMap.FindKey (2))
|
||||
};
|
||||
|
||||
TopLoc_Location aLocSurf[2];
|
||||
const Handle(Geom_Surface)* aSurfaces[2] =
|
||||
{
|
||||
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
|
||||
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1])
|
||||
};
|
||||
|
||||
Standard_Integer aConIndex = 0;
|
||||
Handle(Geom_ConicalSurface) aGeomCone = Handle(Geom_ConicalSurface)::DownCast (*aSurfaces[0]);
|
||||
Handle(Geom_Plane) aGeomPln;
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
aGeomPln = Handle(Geom_Plane)::DownCast (*aSurfaces[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
aConIndex = 1;
|
||||
aGeomCone = Handle(Geom_ConicalSurface)::DownCast (*aSurfaces[1]);
|
||||
aGeomPln = Handle(Geom_Plane)::DownCast (*aSurfaces[0]);
|
||||
}
|
||||
if (!aGeomCone.IsNull()
|
||||
&& !aGeomPln.IsNull()
|
||||
&& aGeomPln->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cone aCone = BRepAdaptor_Surface (*aFaces[aConIndex]).Cone();
|
||||
const Standard_Real aRad1 = aCone.RefRadius();
|
||||
const Standard_Real aHeight = (aRad1 != 0.0)
|
||||
? aRad1 / Abs (Tan (aCone.SemiAngle()))
|
||||
: aCone.Location().Distance (aGeomPln->Location().Transformed (aLocSurf[aConIndex == 0 ? 1 : 0]));
|
||||
const Standard_Real aRad2 = (aRad1 != 0.0) ? 0.0 : Tan (aCone.SemiAngle()) * aHeight;
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCone.Position(), gp::XOY());
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
if (theSubfacesMap.Extent() == 3) // detect cylinder or truncated cone
|
||||
{
|
||||
const TopoDS_Face* aFaces[3] =
|
||||
{
|
||||
&TopoDS::Face (theSubfacesMap.FindKey (1)),
|
||||
&TopoDS::Face (theSubfacesMap.FindKey (2)),
|
||||
&TopoDS::Face (theSubfacesMap.FindKey (3))
|
||||
};
|
||||
|
||||
TopLoc_Location aLocSurf[3];
|
||||
const Handle(Geom_Surface)* aSurfaces[3] =
|
||||
{
|
||||
&BRep_Tool::Surface (*aFaces[0], aLocSurf[0]),
|
||||
&BRep_Tool::Surface (*aFaces[1], aLocSurf[1]),
|
||||
&BRep_Tool::Surface (*aFaces[2], aLocSurf[2])
|
||||
};
|
||||
|
||||
Standard_Integer aConIndex = -1, aNbPlanes = 0;
|
||||
Handle(Geom_ConicalSurface) aGeomCone;
|
||||
Handle(Geom_CylindricalSurface) aGeomCyl;
|
||||
Handle(Geom_Plane) aGeomPlanes[2];
|
||||
const TopLoc_Location* aGeomPlanesLoc[2];
|
||||
for (Standard_Integer aSurfIter = 0; aSurfIter < 3; ++aSurfIter)
|
||||
{
|
||||
const Handle(Geom_Surface)& aSurf = *aSurfaces[aSurfIter];
|
||||
if (aConIndex == -1)
|
||||
{
|
||||
aGeomCone = Handle (Geom_ConicalSurface)::DownCast (aSurf);
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
aConIndex = aSurfIter;
|
||||
continue;
|
||||
}
|
||||
aGeomCyl = Handle (Geom_CylindricalSurface)::DownCast (aSurf);
|
||||
if (!aGeomCyl.IsNull())
|
||||
{
|
||||
aConIndex = aSurfIter;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (aNbPlanes < 2)
|
||||
{
|
||||
aGeomPlanes[aNbPlanes] = Handle(Geom_Plane)::DownCast (aSurf);
|
||||
if (!aGeomPlanes[aNbPlanes].IsNull())
|
||||
{
|
||||
aGeomPlanesLoc[aNbPlanes] = &aLocSurf[aSurfIter];
|
||||
++aNbPlanes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!aGeomCone.IsNull())
|
||||
{
|
||||
if (!aGeomPlanes[0].IsNull()
|
||||
&& !aGeomPlanes[1].IsNull()
|
||||
&& aGeomPlanes[0]->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular())
|
||||
&& aGeomPlanes[1]->Position().Direction().IsEqual (aGeomCone->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cone aCone = BRepAdaptor_Surface (*aFaces[aConIndex]).Cone();
|
||||
const Standard_Real aRad1 = aCone.RefRadius();
|
||||
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
|
||||
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aCone.Position(), gp::XOY());
|
||||
const Standard_Real aTriangleHeight = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 / Tan (aCone.SemiAngle())
|
||||
: aRad1 / Tan (Abs (aCone.SemiAngle())) - aHeight;
|
||||
const Standard_Real aRad2 = (aCone.SemiAngle() > 0.0)
|
||||
? aRad1 * (aTriangleHeight + aHeight) / aTriangleHeight
|
||||
: aRad1 * aTriangleHeight / (aTriangleHeight + aHeight);
|
||||
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad1, aRad2, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
else if (!aGeomCyl.IsNull())
|
||||
{
|
||||
if (!aGeomPlanes[0].IsNull()
|
||||
&& !aGeomPlanes[1].IsNull()
|
||||
&& aGeomPlanes[0]->Position().Direction().IsParallel (aGeomCyl->Position().Direction(), Precision::Angular())
|
||||
&& aGeomPlanes[1]->Position().Direction().IsParallel (aGeomCyl->Position().Direction(), Precision::Angular()))
|
||||
{
|
||||
const gp_Cylinder aCyl = BRepAdaptor_Surface (*aFaces[aConIndex]).Cylinder();
|
||||
const Standard_Real aRad = aCyl.Radius();
|
||||
const Standard_Real aHeight = aGeomPlanes[0]->Location().Transformed (*aGeomPlanesLoc[0])
|
||||
.Distance (aGeomPlanes[1]->Location().Transformed (*aGeomPlanesLoc[1]));
|
||||
|
||||
gp_Trsf aTrsf;
|
||||
gp_Ax3 aPos = aCyl.Position();
|
||||
if (aGeomPlanes[0]->Position().IsCoplanar (aGeomPlanes[1]->Position(), Precision::Angular(), Precision::Angular()))
|
||||
{
|
||||
// cylinders created as a prism have an inverse vector of the cylindrical surface
|
||||
aPos.SetDirection (aPos.Direction().Reversed());
|
||||
}
|
||||
aTrsf.SetTransformation (aPos, gp::XOY());
|
||||
|
||||
Handle(Select3D_SensitiveCylinder) aSensSCyl = new Select3D_SensitiveCylinder (theOwner, aRad, aRad, aHeight, aTrsf);
|
||||
theSelection->Add (aSensSCyl);
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user