mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
2 Commits
CR0-MR_Pro
...
CR28569
Author | SHA1 | Date | |
---|---|---|---|
|
a16fd3862a | ||
|
f58535d13c |
@@ -561,27 +561,6 @@ else()
|
||||
OCCT_CHECK_AND_UNSET ("INSTALL_FREEIMAGE")
|
||||
endif()
|
||||
|
||||
# FFmpeg
|
||||
# search for CSF_FFmpeg variable in EXTERNLIB of each being used toolkit
|
||||
OCCT_IS_PRODUCT_REQUIRED (CSF_FFmpeg CAN_USE_FFMPEG)
|
||||
|
||||
if (CAN_USE_FFMPEG)
|
||||
set (USE_FFMPEG OFF CACHE BOOL "${USE_FFMPEG_DESCR}")
|
||||
|
||||
if (USE_FFMPEG)
|
||||
add_definitions (-DHAVE_FFMPEG)
|
||||
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/ffmpeg")
|
||||
else()
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_FFMPEG")
|
||||
OCCT_CHECK_AND_UNSET ("INSTALL_FFMPEG")
|
||||
endif()
|
||||
else()
|
||||
OCCT_CHECK_AND_UNSET ("USE_FFMPEG")
|
||||
|
||||
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_FFMPEG")
|
||||
OCCT_CHECK_AND_UNSET ("INSTALL_FFMPEG")
|
||||
endif()
|
||||
|
||||
# OpenGL ES 2.0
|
||||
if (WIN32 AND CAN_USE_GLES2)
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsStore")
|
||||
|
@@ -347,6 +347,8 @@ n StepToGeom
|
||||
n StepToTopoDS
|
||||
n StepVisual
|
||||
n StlAPI
|
||||
n StlMesh
|
||||
n StlTransfer
|
||||
n TopoDSToStep
|
||||
n Transfer
|
||||
n TransferBRep
|
||||
|
@@ -1,228 +0,0 @@
|
||||
# FFmpeg
|
||||
|
||||
if (NOT DEFINED INSTALL_FFMPEG)
|
||||
set (INSTALL_FFMPEG OFF CACHE BOOL "${INSTALL_FFMPEG_DESCR}")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_DIR)
|
||||
set (3RDPARTY_FFMPEG_DIR "" CACHE PATH "The directory containing FFmpeg")
|
||||
endif()
|
||||
|
||||
# include occt macros. compiler_bitness, os_wiht_bit, compiler
|
||||
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/occt_macros")
|
||||
|
||||
# specify FFMPEG folder in connection with 3RDPARTY_DIR
|
||||
if (3RDPARTY_DIR AND EXISTS "${3RDPARTY_DIR}")
|
||||
if (NOT 3RDPARTY_FFMPEG_DIR OR NOT EXISTS "${3RDPARTY_FFMPEG_DIR}")
|
||||
FIND_PRODUCT_DIR ("${3RDPARTY_DIR}" FFMPEG FFMPEG_DIR_NAME)
|
||||
if (FFMPEG_DIR_NAME)
|
||||
set (3RDPARTY_FFMPEG_DIR "${3RDPARTY_DIR}/${FFMPEG_DIR_NAME}" CACHE PATH "The directory containing FFmpeg" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
endif()
|
||||
|
||||
# define required FFMPEG variables
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_INCLUDE_DIR)
|
||||
set (3RDPARTY_FFMPEG_INCLUDE_DIR "" CACHE PATH "the path of headers directory")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_LIBRARY OR NOT 3RDPARTY_FFMPEG_LIBRARY_DIR OR NOT EXISTS "${3RDPARTY_FFMPEG_LIBRARY_DIR}")
|
||||
set (3RDPARTY_FFMPEG_LIBRARY "" CACHE FILEPATH "FFmpeg framework" FORCE)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_LIBRARY_DIR)
|
||||
set (3RDPARTY_FFMPEG_LIBRARY_DIR "" CACHE PATH "The directory containing FFmpeg framework")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_DLL OR NOT 3RDPARTY_FFMPEG_DLL_DIR OR NOT EXISTS "${3RDPARTY_FFMPEG_DLL_DIR}")
|
||||
set (3RDPARTY_FFMPEG_DLL "" CACHE FILEPATH "FFmpeg shared libraries" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
if (NOT DEFINED 3RDPARTY_FFMPEG_DLL_DIR)
|
||||
set (3RDPARTY_FFMPEG_DLL_DIR "" CACHE PATH "The directory containing FFmpeg shared libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# check 3RDPARTY_${PRODUCT_NAME}_ paths for consistency with specified 3RDPARTY_${PRODUCT_NAME}_DIR
|
||||
if (3RDPARTY_FFMPEG_DIR AND EXISTS "${3RDPARTY_FFMPEG_DIR}")
|
||||
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_INCLUDE_DIR PATH "the path to FFmpeg")
|
||||
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_LIBRARY FILEPATH "the path to FFmpeg framework")
|
||||
|
||||
if (3RDPARTY_FFMPEG_LIBRARY AND EXISTS "${3RDPARTY_FFMPEG_LIBRARY}")
|
||||
get_filename_component (3RDPARTY_FFMPEG_LIBRARY_DIR "${3RDPARTY_FFMPEG_LIBRARY}" PATH)
|
||||
set (3RDPARTY_FFMPEG_LIBRARY_DIR "${3RDPARTY_FFMPEG_LIBRARY_DIR}" CACHE PATH "The directory containing FFmpeg libraries" FORCE)
|
||||
else()
|
||||
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_LIBRARY_DIR PATH "The directory containing FFmpeg libraries")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_DLL FILEPATH "the path to FFmpeg shared libraries")
|
||||
|
||||
if (3RDPARTY_FFMPEG_DLL AND EXISTS "${3RDPARTY_FFMPEG_DLL}")
|
||||
get_filename_component (3RDPARTY_FFMPEG_DLL_DIR "${3RDPARTY_FFMPEG_DLL}" PATH)
|
||||
set (3RDPARTY_FFMPEG_DLL_DIR "${3RDPARTY_FFMPEG_DLL_DIR}" CACHE PATH "The directory containing FFmpeg shared libraries" FORCE)
|
||||
else()
|
||||
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_FFMPEG_DIR 3RDPARTY_FFMPEG_DLL_DIR PATH "The directory containing FFmpeg shared libraries")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# header
|
||||
if (NOT 3RDPARTY_FFMPEG_INCLUDE_DIR OR NOT EXISTS "${3RDPARTY_FFMPEG_INCLUDE_DIR}")
|
||||
set (HEADER_NAMES avutil.h libavutil/avutil.h)
|
||||
|
||||
# set 3RDPARTY_FFMPEG_INCLUDE_DIR as notfound, otherwise find_library can't assign a new value to 3RDPARTY_FFMPEG_INCLUDE_DIR
|
||||
set (3RDPARTY_FFMPEG_INCLUDE_DIR "3RDPARTY_FFMPEG_INCLUDE_DIR-NOTFOUND" CACHE FILEPATH "the path to header directory" FORCE)
|
||||
|
||||
if (3RDPARTY_FFMPEG_DIR AND EXISTS "${3RDPARTY_FFMPEG_DIR}")
|
||||
find_path (3RDPARTY_FFMPEG_INCLUDE_DIR NAMES ${HEADER_NAMES}
|
||||
PATHS ${3RDPARTY_FFMPEG_DIR}
|
||||
PATH_SUFFIXES include
|
||||
CMAKE_FIND_ROOT_PATH_BOTH
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_path (3RDPARTY_FFMPEG_INCLUDE_DIR NAMES ${HEADER_NAMES}
|
||||
PATH_SUFFIXES include
|
||||
CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (3RDPARTY_FFMPEG_INCLUDE_DIR AND EXISTS "${3RDPARTY_FFMPEG_INCLUDE_DIR}")
|
||||
list (APPEND 3RDPARTY_INCLUDE_DIRS "${3RDPARTY_FFMPEG_INCLUDE_DIR}")
|
||||
else()
|
||||
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_FFMPEG_INCLUDE_DIR)
|
||||
|
||||
set (3RDPARTY_FFMPEG_INCLUDE_DIR "" CACHE FILEPATH "the path to avutil.h" FORCE)
|
||||
endif()
|
||||
|
||||
# library
|
||||
if (NOT 3RDPARTY_FFMPEG_LIBRARY OR NOT EXISTS "${3RDPARTY_FFMPEG_LIBRARY}")
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .lib .so .dylib .a)
|
||||
|
||||
set (FFMPEG_PATH_SUFFIXES lib)
|
||||
if (ANDROID)
|
||||
set (FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} libs/${ANDROID_ABI})
|
||||
elseif(APPLE)
|
||||
set (FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} Frameworks)
|
||||
endif()
|
||||
|
||||
# set 3RDPARTY_FFMPEG_LIBRARY as notfound, otherwise find_library can't assign a new value to 3RDPARTY_FFMPEG_LIBRARY
|
||||
set (3RDPARTY_FFMPEG_LIBRARY "3RDPARTY_FFMPEG_LIBRARY-NOTFOUND" CACHE FILEPATH "The path to FFmpeg library" FORCE)
|
||||
|
||||
if (3RDPARTY_FFMPEG_DIR AND EXISTS "${3RDPARTY_FFMPEG_DIR}")
|
||||
find_library (3RDPARTY_FFMPEG_LIBRARY NAMES avutil
|
||||
PATHS "${3RDPARTY_FFMPEG_LIBRARY_DIR}" "${3RDPARTY_FFMPEG_DIR}"
|
||||
PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES}
|
||||
CMAKE_FIND_ROOT_PATH_BOTH
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
find_library (3RDPARTY_FFMPEG_LIBRARY NAMES avutil
|
||||
PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES}
|
||||
CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
endif()
|
||||
|
||||
if (3RDPARTY_FFMPEG_LIBRARY AND EXISTS "${3RDPARTY_FFMPEG_LIBRARY}")
|
||||
get_filename_component (3RDPARTY_FFMPEG_LIBRARY_DIR "${3RDPARTY_FFMPEG_LIBRARY}" PATH)
|
||||
set (3RDPARTY_FFMPEG_LIBRARY_DIR "${3RDPARTY_FFMPEG_LIBRARY_DIR}" CACHE PATH "The directory containing FFmpeg library" FORCE)
|
||||
else()
|
||||
set (3RDPARTY_FFMPEG_LIBRARY_DIR "" CACHE PATH "The directory containing FFmpeg library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (3RDPARTY_FFMPEG_LIBRARY_DIR AND EXISTS "${3RDPARTY_FFMPEG_LIBRARY_DIR}")
|
||||
list (APPEND 3RDPARTY_LIBRARY_DIRS "${3RDPARTY_FFMPEG_LIBRARY_DIR}")
|
||||
else()
|
||||
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_FFMPEG_LIBRARY_DIR)
|
||||
|
||||
set (3RDPARTY_FFMPEG_LIBRARY "" CACHE FILEPATH "The path to FFmpeg library" FORCE)
|
||||
endif()
|
||||
|
||||
# shared library
|
||||
if (WIN32)
|
||||
if (NOT 3RDPARTY_FFMPEG_DLL OR NOT EXISTS "${3RDPARTY_FFMPEG_DLL}")
|
||||
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .dll)
|
||||
set (3RDPARTY_FFMPEG_DLL "3RDPARTY_FFMPEG_DLL-NOTFOUND" CACHE FILEPATH "The path to FFmpeg shared library" FORCE)
|
||||
|
||||
# find FFmpeg shared library
|
||||
file (GLOB 3RDPARTY_FFMPEG_DLL "${3RDPARTY_FFMPEG_DIR}/bin/avutil[-][0-9]*")
|
||||
|
||||
if (3RDPARTY_FFMPEG_DLL AND EXISTS "${3RDPARTY_FFMPEG_DLL}")
|
||||
set (3RDPARTY_FFMPEG_DLL "${3RDPARTY_FFMPEG_DLL}" CACHE FILEPATH "FFmpeg shared library" FORCE)
|
||||
get_filename_component (3RDPARTY_FFMPEG_DLL_DIR "${3RDPARTY_FFMPEG_DLL}" PATH)
|
||||
set (3RDPARTY_FFMPEG_DLL_DIR "${3RDPARTY_FFMPEG_DLL_DIR}" CACHE PATH "The directory containing FFmpeg library" FORCE)
|
||||
else()
|
||||
set (3RDPARTY_FFMPEG_DLL_DIR "" CACHE PATH "The directory containing FFmpeg shared library" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (3RDPARTY_FFMPEG_DLL_DIR OR EXISTS "${3RDPARTY_FFMPEG_DLL_DIR}")
|
||||
list (APPEND 3RDPARTY_DLL_DIRS "${3RDPARTY_FFMPEG_DLL_DIR}")
|
||||
else()
|
||||
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_FFMPEG_DLL_DIR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# install instructions
|
||||
if (INSTALL_FFMPEG)
|
||||
OCCT_MAKE_OS_WITH_BITNESS()
|
||||
OCCT_MAKE_COMPILER_SHORT_NAME()
|
||||
|
||||
if (WIN32)
|
||||
if (DEFINED INSTALL_BIN_DIR)
|
||||
install (FILES "${3RDPARTY_FFMPEG_DLL}" DESTINATION "${INSTALL_BIN_DIR}")
|
||||
else()
|
||||
install (FILES "${3RDPARTY_FFMPEG_DLL}"
|
||||
CONFIGURATIONS Release
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/bin")
|
||||
install (FILES "${3RDPARTY_FFMPEG_DLL}"
|
||||
CONFIGURATIONS RelWithDebInfo
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/bini")
|
||||
install (FILES "${3RDPARTY_FFMPEG_DLL}"
|
||||
CONFIGURATIONS Debug
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/bind")
|
||||
endif()
|
||||
else()
|
||||
get_filename_component(3RDPARTY_FFMPEG_LIBRARY_ABS ${3RDPARTY_FFMPEG_LIBRARY} REALPATH)
|
||||
get_filename_component(3RDPARTY_FFMPEG_LIBRARY_NAME ${3RDPARTY_FFMPEG_LIBRARY} NAME)
|
||||
|
||||
if (DEFINED INSTALL_LIB_DIR)
|
||||
install (FILES "${3RDPARTY_FFMPEG_LIBRARY_ABS}"
|
||||
DESTINATION "${INSTALL_LIB_DIR}"
|
||||
RENAME ${3RDPARTY_FFMPEG_LIBRARY_NAME}.6)
|
||||
else()
|
||||
install (FILES "${3RDPARTY_FFMPEG_LIBRARY_ABS}"
|
||||
CONFIGURATIONS Release
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/lib"
|
||||
RENAME ${3RDPARTY_FFMPEG_LIBRARY_NAME}.6)
|
||||
install (FILES "${3RDPARTY_FFMPEG_LIBRARY_ABS}"
|
||||
CONFIGURATIONS RelWithDebInfo
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/libi"
|
||||
RENAME ${3RDPARTY_FFMPEG_LIBRARY_NAME}.6)
|
||||
install (FILES "${3RDPARTY_FFMPEG_LIBRARY_ABS}"
|
||||
CONFIGURATIONS Debug
|
||||
DESTINATION "${INSTALL_DIR}/${OS_WITH_BIT}/${COMPILER}/libd"
|
||||
RENAME ${3RDPARTY_FFMPEG_LIBRARY_NAME}.6)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set (USED_3RDPARTY_FFMPEG_DIR "")
|
||||
else()
|
||||
# the library directory for using by the executable
|
||||
if (WIN32)
|
||||
set (USED_3RDPARTY_FFMPEG_DIR ${3RDPARTY_FFMPEG_DLL_DIR})
|
||||
else()
|
||||
set (USED_3RDPARTY_FFMPEG_DIR ${3RDPARTY_FFMPEG_LIBRARY_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# unset all redundant variables
|
||||
OCCT_CHECK_AND_UNSET (FFMPEG_INCLUDE_DIRS)
|
||||
OCCT_CHECK_AND_UNSET (FFMPEG_LIBRARY_DIRS)
|
||||
OCCT_CHECK_AND_UNSET (FFMPEG_DIR)
|
||||
|
||||
mark_as_advanced (3RDPARTY_FFMPEG_LIBRARY 3RDPARTY_FFMPEG_DLL)
|
@@ -24,13 +24,6 @@ else()
|
||||
set (CSF_FREETYPE)
|
||||
endif()
|
||||
|
||||
# FFmpeg
|
||||
if (USE_FFMPEG)
|
||||
set (CSF_FFmpeg "avcodec avformat swscale avutil")
|
||||
else()
|
||||
set (CSF_FFmpeg)
|
||||
endif()
|
||||
|
||||
# FREEIMAGE
|
||||
if (USE_FREEIMAGE)
|
||||
set (CSF_FreeImagePlus "freeimage")
|
||||
|
@@ -316,7 +316,6 @@ if (BUILD_USE_PCH)
|
||||
|
||||
# workaround for old gcc
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_definitions("-D__STDC_CONSTANT_MACROS")
|
||||
add_definitions("-D__STDC_FORMAT_MACROS")
|
||||
endif()
|
||||
|
||||
|
@@ -82,7 +82,6 @@ endmacro()
|
||||
INSTALL_MESSAGE (INSTALL_SAMPLES "OCCT samples")
|
||||
INSTALL_MESSAGE (INSTALL_TEST_CASES "non-regression OCCT test scripts")
|
||||
INSTALL_MESSAGE (INSTALL_DOC_Overview "OCCT overview documentation (HTML format)")
|
||||
INSTALL_MESSAGE (INSTALL_FFMPEG "FFmpeg binaries")
|
||||
INSTALL_MESSAGE (INSTALL_FREEIMAGE "FreeImage binaries")
|
||||
INSTALL_MESSAGE (INSTALL_EGL "EGL binaries")
|
||||
INSTALL_MESSAGE (INSTALL_GLES2 "OpenGL ES 2.0 binaries")
|
||||
@@ -137,10 +136,6 @@ set (3RDPARTY_DIR_DESCR
|
||||
third-party product have been found - corresponding CMake variables will be specified
|
||||
(VTK: 3RDPARTY_VTK_DIR, 3RDPARTY_VTK_INCLUDE_DIR, 3RDPARTY_VTK_LIBRARY_DIR)")
|
||||
|
||||
set (USE_FFMPEG_DESCR
|
||||
"Indicates whether FFmpeg framework is used or not. FFmpeg stands for
|
||||
multimedia data handling, open-source software libraries used for video encoding and decoding.")
|
||||
|
||||
set (USE_FREEIMAGE_DESCR
|
||||
"Indicates whether Freeimage product should be used in OCCT visualization
|
||||
module for support of popular graphics image formats (PNG, BMP etc)")
|
||||
|
@@ -119,21 +119,6 @@ proc wokdep:SearchHeader {theHeader} {
|
||||
if { [file exists "$aPath"] } {
|
||||
return "$aPath"
|
||||
}
|
||||
|
||||
if { "$::tcl_platform(os)" == "Linux" } {
|
||||
if { "$::ARCH" == "64" } {
|
||||
set aPath "/usr/include/x86_64-linux-gnu/${theHeader}"
|
||||
if { [file exists "$aPath"] } {
|
||||
return "$aPath"
|
||||
}
|
||||
} else {
|
||||
set aPath "/usr/include/i386-linux-gnu/${theHeader}"
|
||||
if { [file exists "$aPath"] } {
|
||||
return "$aPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@@ -61,7 +61,6 @@ set (OpenCASCADE_WITH_FREEIMAGE @USE_FREEIMAGE@)
|
||||
set (OpenCASCADE_WITH_GL2PS @USE_GL2PS@)
|
||||
set (OpenCASCADE_WITH_TBB @USE_TBB@)
|
||||
set (OpenCASCADE_WITH_VTK @USE_VTK@)
|
||||
set (OpenCASCADE_WITH_FFMPEG @USE_FFMPEG@)
|
||||
set (OpenCASCADE_WITH_GLES2 @USE_GLES2@)
|
||||
@SET_OpenCASCADE_WITH_D3D@
|
||||
@SET_OpenCASCADE_WITH_GLX@
|
||||
|
@@ -14,7 +14,6 @@ if /I "%VCVER%" == "@COMPILER@" (
|
||||
set "GL2PS_DIR=@3RDPARTY_GL2PS_DLL_DIRS@"
|
||||
set "TBB_DIR=@3RDPARTY_TBB_DLL_DIR@"
|
||||
set "VTK_DIR=@3RDPARTY_VTK_DLL_DIR@"
|
||||
set "FFMPEG_DIR=@3RDPARTY_FFMPEG_DLL_DIR@"
|
||||
|
||||
if not "@3RDPARTY_QT_DIR@" == "" (
|
||||
set "QTDIR=@3RDPARTY_QT_DIR@"
|
||||
|
@@ -12,7 +12,6 @@ if [ "$1" == "@BIN_LETTER@" ]; then
|
||||
export GL2PS_DIR="@3RDPARTY_GL2PS_LIBRARY_DIRS@"
|
||||
export TBB_DIR="@3RDPARTY_TBB_LIBRARY_DIR@"
|
||||
export VTK_DIR="@3RDPARTY_VTK_LIBRARY_DIR@"
|
||||
export FFMPEG_DIR="@3RDPARTY_FFMPEG_LIBRARY_DIR@"
|
||||
|
||||
if [ "x@3RDPARTY_QT_DIR" != "x" ]; then
|
||||
export QTDIR="@3RDPARTY_QT_DIR@"
|
||||
|
@@ -16,7 +16,6 @@ if /I "%VCVER%" == "@COMPILER@" (
|
||||
set "GL2PS_DIR=@USED_3RDPARTY_GL2PS_DIRS@"
|
||||
set "TBB_DIR=@USED_3RDPARTY_TBB_DIR@"
|
||||
set "VTK_DIR=@USED_3RDPARTY_VTK_DIR@"
|
||||
set "FFMPEG_DIR=@USED_3RDPARTY_FFMPEG_DIR@"
|
||||
|
||||
if not "@USED_3RDPARTY_QT_DIR@" == "" (
|
||||
set "QTDIR=@USED_3RDPARTY_QT_DIR@"
|
||||
|
@@ -12,7 +12,6 @@ if [ "$1" == "@BIN_LETTER@" ]; then
|
||||
export GL2PS_DIR="@USED_3RDPARTY_GL2PS_DIRS@"
|
||||
export TBB_DIR="@USED_3RDPARTY_TBB_DIR@"
|
||||
export VTK_DIR="@USED_3RDPARTY_VTK_DIR@"
|
||||
export FFMPEG_DIR="@USED_3RDPARTY_FFMPEG_DIR@"
|
||||
|
||||
if [ "x@USED_3RDPARTY_QT_DIR@" != "x" ]; then
|
||||
export QTDIR="@USED_3RDPARTY_QT_DIR@"
|
||||
|
@@ -115,7 +115,6 @@ if not ["%GLES2_DIR%"] == [""] set "PATH=%GLES2_DIR%;%PATH%"
|
||||
if not ["%GL2PS_DIR%"] == [""] set "PATH=%GL2PS_DIR%;%PATH%"
|
||||
if not ["%TBB_DIR%"] == [""] set "PATH=%TBB_DIR%;%PATH%"
|
||||
if not ["%VTK_DIR%"] == [""] set "PATH=%VTK_DIR%;%PATH%"
|
||||
if not ["%FFMPEG_DIR%"] == [""] set "PATH=%FFMPEG_DIR%;%PATH%"
|
||||
if not ["%QTDIR%"] == [""] set "PATH=%QTDIR%/bin;%PATH%"
|
||||
|
||||
rem ----- Set path to 3rd party and OCCT libraries -----
|
||||
|
@@ -66,10 +66,6 @@ if [ "$VTK_DIR" != "" ]; then
|
||||
THRDPARTY_PATH="${VTK_DIR}:${THRDPARTY_PATH}"
|
||||
fi
|
||||
|
||||
if [ "$FFMPEG_DIR" != "" ]; then
|
||||
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
|
||||
fi
|
||||
|
||||
if [ "$QTDIR" != "" ]; then
|
||||
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
|
||||
fi
|
||||
|
@@ -110,7 +110,6 @@
|
||||
<ProgramDatabaseFile>.\..\..\..\win32\__VCVER__\bin\__XQTNAM__.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<ImportLibrary>..\..\..\win32\__VCVER__\lib\__XQTNAM__.lib</ImportLibrary>
|
||||
<AdditionalOptions>/LARGEADDRESSAWARE %(AdditionalOptions)</AdditionalOptions>
|
||||
__VCLNKREL__
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@@ -156,7 +155,6 @@
|
||||
<ProgramDatabaseFile>..\..\..\win32\__VCVER__\bind\__XQTNAM__.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<ImportLibrary>..\..\..\win32\__VCVER__\libd\__XQTNAM__.lib</ImportLibrary>
|
||||
<AdditionalOptions>/LARGEADDRESSAWARE %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@@ -1406,7 +1406,3 @@ In previous versions, *IsPeriodic()* always returned false if *IsClosed()* retur
|
||||
The history of the changing of the initial shape was corrected:
|
||||
* all shapes created by the algorithm are considered as modified shapes instead of generated ones;
|
||||
* method Generated was removed and its calls should be replaced by calls of method History()->Modified.
|
||||
|
||||
@subsection upgrade_720_Change_In_RWStl Changes in STL Reader / Writer
|
||||
|
||||
Class RWStl now uses class Poly_Triangulation for storing triangular mesh instead of StlMesh data classes; the latter have been removed.
|
||||
|
@@ -135,9 +135,6 @@ by fully automating techniques as precompiled header usage and single compilatio
|
||||
Cotire is included in OCCT repository and used optionally by OCCT CMake scripts to accelerate builds by use of precompiled headers.
|
||||
Cotire is licensed under the MIT license (https://github.com/sakra/cotire/blob/master/license).
|
||||
|
||||
**FFmpeg** is an Open Source framework supporting various image, video and audio codecs.
|
||||
FFmpeg is optionally used by OCCT for video recording, on LGPL conditions (https://www.ffmpeg.org/legal.html).
|
||||
|
||||
**MikTEX** is up-to-date implementation of TeX/LaTeX and related programs for Windows. It is used
|
||||
for generation of User and Developer Guides in PDF format. See https://miktex.org for information
|
||||
on this tool.
|
||||
@@ -213,7 +210,6 @@ for which OCCT is certified to work.
|
||||
| TCL (for testing tools) | Tcl/Tk 8.6.3+ http://www.tcl.tk/software/tcltk/download.html <br> or ActiveTcl 8.6 http://www.activestate.com/activetcl/downloads (for Windows)|
|
||||
| Freetype (for text rendering) | FreeType 2.4.11-2.5.5 http://sourceforge.net/projects/freetype/files/ |
|
||||
| FreeImage (optional, for support of common 2D graphic formats) | FreeImage 3.17.0+ http://sourceforge.net/projects/freeimage/files |
|
||||
| FFmpeg (optional, for video recording) | FFmpeg 3.1+ https://www.ffmpeg.org |
|
||||
| gl2ps (optional, for export contents of OCCT viewer to vector formats) | gl2ps-1.3.8+ http://geuz.org/gl2ps/ |
|
||||
| Intel TBB (optional, for multithreaded algorithms) | TBB 4.x or 5.x http://www.threadingbuildingblocks.org/ |
|
||||
| VTK (for VTK Integration Services | VTK 6.1+ http://www.vtk.org/VTK/resources/software.html |
|
||||
|
@@ -1508,8 +1508,8 @@ Such an object, for example, can be used for displaying the object and stored in
|
||||
|
||||
~~~~~
|
||||
// read the data and create a data source
|
||||
Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName);
|
||||
Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
|
||||
Handle (StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFileName);
|
||||
Handle (XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
|
||||
|
||||
// create mesh
|
||||
Handle (MeshVS_Mesh) aMesh = new MeshVS();
|
||||
|
4
genconf
4
genconf
@@ -6,10 +6,8 @@
|
||||
# initialize environment
|
||||
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
|
||||
if [ ! -e "${aScriptPath}/env.sh" ]; then
|
||||
cat ${aScriptPath}/adm/templates/env.sh | sed -e '/__CASROOT__/d' > ${aScriptPath}/env.sh
|
||||
cat ${aScriptPath}/adm/templates/env.sh | sed -e '/__CASROOT__/d' > ${aScriptPath}/env.sh
|
||||
fi
|
||||
|
||||
if [ -e "${aScriptPath}/custom.sh" ]; then source "${aScriptPath}/custom.sh"; fi
|
||||
|
||||
# run GUI tool
|
||||
tclsh "${aScriptPath}/adm/genconf.tcl"
|
||||
|
@@ -331,8 +331,10 @@ Standard_Boolean MainPage::SaveSTEP(const wchar_t* theFilePath, const TopoDS_Sha
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
switch (aWriter.Write (aFilePath.ToCString()))
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
switch (aWriter.Write(theFilePathA))
|
||||
{
|
||||
case IFSelect_RetError:
|
||||
Output_TextBlock->Text += L"Error: Incorrect Data\n";
|
||||
@@ -356,8 +358,11 @@ Standard_Boolean MainPage::SaveSTEP(const wchar_t* theFilePath, const TopoDS_Sha
|
||||
Standard_Boolean MainPage::SaveSTL(const wchar_t* theFilePath, const TopoDS_Shape& theShape)
|
||||
{
|
||||
StlAPI_Writer myStlWriter;
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
return myStlWriter.Write (theShape, aFilePath.ToCString());
|
||||
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
return myStlWriter.Write(theShape, theFilePathA) == StlAPI_StatusOK;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -367,8 +372,12 @@ Standard_Boolean MainPage::SaveSTL(const wchar_t* theFilePath, const TopoDS_Shap
|
||||
Standard_Boolean MainPage::SaveVRML(const wchar_t* theFilePath, const TopoDS_Shape& theShape)
|
||||
{
|
||||
VrmlAPI_Writer aWriter;
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
aWriter.Write (theShape, aFilePath.ToCString());
|
||||
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
aWriter.Write(theShape, theFilePathA);
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
@@ -381,8 +390,11 @@ Standard_Boolean MainPage::ReadBREP(const wchar_t* theFilePath, TopoDS_Shape& th
|
||||
theShape.Nullify();
|
||||
|
||||
BRep_Builder aBuilder;
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
if (!BRepTools::Read(theShape, aFilePath.ToCString(), aBuilder))
|
||||
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
if (!BRepTools::Read(theShape, theFilePathA, aBuilder))
|
||||
return Standard_False;
|
||||
|
||||
return !theShape.IsNull() && BRepAlgo::IsValid(theShape);
|
||||
@@ -398,8 +410,10 @@ Standard_Boolean MainPage::ReadIGES(const wchar_t* theFilePath, TopoDS_Shape& th
|
||||
|
||||
IGESControl_Reader Reader;
|
||||
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
if (Reader.ReadFile (aFilePath.ToCString()) != IFSelect_RetDone)
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
if (Reader.ReadFile(theFilePathA) != IFSelect_RetDone)
|
||||
return Standard_False;
|
||||
|
||||
Reader.TransferRoots();
|
||||
@@ -417,8 +431,11 @@ Standard_Boolean MainPage::ReadSTEP(const wchar_t* theFilePath, TopoDS_Shape& th
|
||||
theShape.Nullify();
|
||||
|
||||
STEPControl_Reader aReader;
|
||||
const TCollection_AsciiString aFilePath (theFilePath);
|
||||
switch (aReader.ReadFile (aFilePath.ToCString()))
|
||||
|
||||
char theFilePathA[MAX_PATH];
|
||||
WideCharToMultiByte(CP_UTF8, 0, theFilePath, -1, theFilePathA, sizeof(theFilePathA), NULL, NULL);
|
||||
|
||||
switch (aReader.ReadFile(theFilePathA))
|
||||
{
|
||||
case IFSelect_RetError:
|
||||
Output_TextBlock->Text += L"Error: Not a valid Step file\n";
|
||||
|
@@ -20,6 +20,15 @@
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
|
||||
#ifdef _WIN32
|
||||
#if _MSC_VER < 1800
|
||||
inline double log2 (const double arg)
|
||||
{
|
||||
return log(arg) / log(2.);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline
|
||||
Standard_Real Transform2d(const Standard_Real u,
|
||||
const Standard_Real umin,
|
||||
@@ -27,50 +36,102 @@ static inline
|
||||
|
||||
//=======================================================================
|
||||
//function : CSLib_Class2d
|
||||
//purpose :
|
||||
//purpose : Constructor
|
||||
//CR28569 : When the number of points is big enough (now 64 or more) then
|
||||
// the internal array of 1D Y-boxes myBoxes1d is initialized. It
|
||||
// cointains approx. sqrt(N) boxes with equal number of points in
|
||||
// them (mySizeBox is a degree of 2). In each box two double
|
||||
// numbers define min Y and max Y of the referred points.
|
||||
//=======================================================================
|
||||
CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& TP2d,
|
||||
const Standard_Real aTolu,
|
||||
const Standard_Real aTolv,
|
||||
const Standard_Real theTolu,
|
||||
const Standard_Real theTolv,
|
||||
const Standard_Real umin,
|
||||
const Standard_Real vmin,
|
||||
const Standard_Real umax,
|
||||
const Standard_Real vmax)
|
||||
: MyPnts2d (NULL),
|
||||
MyBoxes1d (NULL),
|
||||
mySizeBox (0),
|
||||
myNBoxes (0),
|
||||
N (0)
|
||||
{
|
||||
Umin=umin;
|
||||
Vmin=vmin;
|
||||
Umax=umax;
|
||||
Vmax=vmax;
|
||||
//
|
||||
if(umax<=umin || vmax<=vmin) {
|
||||
MyPnts2dX=NULL;
|
||||
MyPnts2dY=NULL;
|
||||
N=0;
|
||||
}
|
||||
//
|
||||
else {
|
||||
if(umax > umin && vmax > vmin)
|
||||
{
|
||||
Standard_Integer i, iLower;
|
||||
Standard_Real du,dv,*Pnts2dX,*Pnts2dY, aPrc;
|
||||
Standard_Real du,dv,*Pnts2dX,*Pnts2dY, aPrc;
|
||||
Umin=umin;
|
||||
Vmin=vmin;
|
||||
Umax=umax;
|
||||
Vmax=vmax;
|
||||
//
|
||||
aPrc=1.e-10;
|
||||
N = TP2d.Length();
|
||||
Tolu = aTolu;
|
||||
Tolv = aTolv;
|
||||
MyPnts2dX = new Standard_Real [N+1];
|
||||
MyPnts2dY = new Standard_Real [N+1];
|
||||
Tolu = theTolu;
|
||||
Tolv = theTolv;
|
||||
MyPnts2d = new Standard_Real [2*N+2];
|
||||
MyBoxes1d = NULL;
|
||||
Pnts2dX = MyPnts2d;
|
||||
Pnts2dY = Pnts2dX + 1;
|
||||
|
||||
du=umax-umin;
|
||||
dv=vmax-vmin;
|
||||
Pnts2dX = (Standard_Real *)MyPnts2dX;
|
||||
Pnts2dY = (Standard_Real *)MyPnts2dY;
|
||||
//
|
||||
|
||||
iLower=TP2d.Lower();
|
||||
for(i = 0; i<N; ++i) {
|
||||
const gp_Pnt2d& aP2D=TP2d(i+iLower);
|
||||
Pnts2dX[i] = Transform2d(aP2D.X(), umin, du);
|
||||
Pnts2dY[i] = Transform2d(aP2D.Y(), vmin, dv);
|
||||
|
||||
if (N > 63) {
|
||||
// large polygon, here 1D Y-boxes are created and filled with data.
|
||||
const Standard_Integer aDegBox = static_cast<Standard_Integer>
|
||||
(0.5 * log2(static_cast<Standard_Real>(N-1)));
|
||||
mySizeBox = 1 << aDegBox;
|
||||
myNBoxes = (N + mySizeBox - 1) / mySizeBox;
|
||||
MyBoxes1d = new Standard_Real[2 * myNBoxes];
|
||||
|
||||
Standard_Integer iBox(0), maskBox(mySizeBox-1);
|
||||
const gp_Pnt2d& aP0 = TP2d(iLower);
|
||||
Pnts2dX[0] = Transform2d(aP0.X(), umin, du);
|
||||
Pnts2dY[0] = Transform2d(aP0.Y(), vmin, dv);
|
||||
MyBoxes1d[0] = Pnts2dY[0];
|
||||
MyBoxes1d[1] = Pnts2dY[0];
|
||||
|
||||
for (i = 1; i<N; ++i) {
|
||||
const gp_Pnt2d& aP2D=TP2d(i+iLower);
|
||||
Pnts2dX[2*i] = Transform2d(aP2D.X(), umin, du);
|
||||
const Standard_Real anY = Transform2d(aP2D.Y(), vmin, dv);
|
||||
Pnts2dY[2*i] = anY;
|
||||
if ((i & maskBox) == 0) {
|
||||
if (anY < MyBoxes1d[iBox])
|
||||
MyBoxes1d[iBox] = anY;
|
||||
if (anY > MyBoxes1d[iBox+1])
|
||||
MyBoxes1d[iBox+1] = anY;
|
||||
iBox+=2;
|
||||
MyBoxes1d[iBox] = anY;
|
||||
MyBoxes1d[iBox+1] = anY;
|
||||
}
|
||||
else if (anY < MyBoxes1d[iBox])
|
||||
MyBoxes1d[iBox] = anY;
|
||||
else if (anY > MyBoxes1d[iBox+1])
|
||||
MyBoxes1d[iBox+1] = anY;
|
||||
}
|
||||
Pnts2dX[2*N]=Pnts2dX[0];
|
||||
Pnts2dY[2*N]=Pnts2dY[0];
|
||||
// now iBox must be equal to 2*myNBoxes-2
|
||||
if (Pnts2dY[0] < MyBoxes1d[iBox])
|
||||
MyBoxes1d[iBox] = Pnts2dY[0];
|
||||
if (Pnts2dY[0] > MyBoxes1d[iBox+1])
|
||||
MyBoxes1d[iBox+1] = Pnts2dY[0];
|
||||
}
|
||||
else {
|
||||
// small polygon, simply fill the array of points.
|
||||
for(i = 0; i<N; ++i) {
|
||||
const gp_Pnt2d& aP2D=TP2d(i+iLower);
|
||||
Pnts2dX[2*i] = Transform2d(aP2D.X(), umin, du);
|
||||
Pnts2dY[2*i] = Transform2d(aP2D.Y(), vmin, dv);
|
||||
}
|
||||
Pnts2dX[2*N]=Pnts2dX[0];
|
||||
Pnts2dY[2*N]=Pnts2dY[0];
|
||||
}
|
||||
Pnts2dX[N]=Pnts2dX[0];
|
||||
Pnts2dY[N]=Pnts2dY[0];
|
||||
//
|
||||
if(du>aPrc) {
|
||||
Tolu/=du;
|
||||
@@ -85,13 +146,13 @@ CSLib_Class2d::CSLib_Class2d(const TColgp_Array1OfPnt2d& TP2d,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void CSLib_Class2d::Destroy() {
|
||||
if(MyPnts2dX) {
|
||||
delete [] (Standard_Real *)MyPnts2dX;
|
||||
MyPnts2dX=NULL;
|
||||
if(MyPnts2d) {
|
||||
delete [] MyPnts2d;
|
||||
MyPnts2d=NULL;
|
||||
}
|
||||
if(MyPnts2dY) {
|
||||
delete [] (Standard_Real *)MyPnts2dY;
|
||||
MyPnts2dY=NULL;
|
||||
if(MyBoxes1d) {
|
||||
delete [] MyBoxes1d;
|
||||
MyBoxes1d=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,41 +247,73 @@ Standard_Integer CSLib_Class2d::SiDans_OnMode(const gp_Pnt2d& P,
|
||||
Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px,
|
||||
const Standard_Real Py) const
|
||||
{
|
||||
Standard_Integer nbc, i, ip1, SH, NH;
|
||||
Standard_Integer nbc, i, SH, NH;
|
||||
Standard_Real *Pnts2dX, *Pnts2dY;
|
||||
Standard_Real x, y, nx, ny;
|
||||
//
|
||||
nbc = 0;
|
||||
i = 0;
|
||||
ip1 = 1;
|
||||
Pnts2dX = (Standard_Real *)MyPnts2dX;
|
||||
Pnts2dY = (Standard_Real *)MyPnts2dY;
|
||||
x = (Pnts2dX[i]-Px);
|
||||
y = (Pnts2dY[i]-Py);
|
||||
SH = (y<0.)? -1 : 1;
|
||||
//
|
||||
for(i=0; i<N ; i++,ip1++) {
|
||||
nx = Pnts2dX[ip1] - Px;
|
||||
ny = Pnts2dY[ip1] - Py;
|
||||
Pnts2dX = MyPnts2d;
|
||||
Pnts2dY = Pnts2dX + 1;
|
||||
if (MyBoxes1d == NULL)
|
||||
{
|
||||
x = (Pnts2dX[0]-Px);
|
||||
y = (Pnts2dY[0]-Py);
|
||||
SH = (y<0.)? -1 : 1;
|
||||
//
|
||||
for(i=0; i<N ; i++) {
|
||||
nx = Pnts2dX[2*(i+1)] - Px;
|
||||
ny = Pnts2dY[2*(i+1)] - Py;
|
||||
|
||||
NH = (ny<0.)? -1 : 1;
|
||||
if(NH!=SH) {
|
||||
if(x>0. && nx>0.) {
|
||||
nbc++;
|
||||
NH = (ny<0.)? -1 : 1;
|
||||
if(NH!=SH) {
|
||||
if(x>0. && nx>0.) {
|
||||
nbc++;
|
||||
}
|
||||
else {
|
||||
if(x>0.0 || nx>0.) {
|
||||
if((x-y*(nx-x)/(ny-y))>0.) {
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SH = NH;
|
||||
}
|
||||
x = nx; y = ny;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find Y-boxes that include Py. Box with index iBox refers the range of
|
||||
// points starting from iBox*sizeBox.
|
||||
for (Standard_Integer iBox = 0; iBox < myNBoxes; iBox++) {
|
||||
if ((MyBoxes1d[2*iBox] - Tolv - Py) * (MyBoxes1d[2*iBox+1] + Tolv - Py) < 0.)
|
||||
{
|
||||
Standard_Integer lastBox = (iBox + 1) * mySizeBox;
|
||||
if (lastBox > N)
|
||||
lastBox = N;
|
||||
x = (Pnts2dX[2*iBox*mySizeBox]-Px);
|
||||
y = (Pnts2dY[2*iBox*mySizeBox]-Py);
|
||||
for (i = iBox*mySizeBox; i < lastBox; i++)
|
||||
{
|
||||
nx = Pnts2dX[2*(i+1)] - Px;
|
||||
ny = Pnts2dY[2*(i+1)] - Py;
|
||||
if (ny * y < 0.) {
|
||||
if (x > 0. && nx > 0.)
|
||||
nbc++;
|
||||
else if (x > 0.0 || nx > 0.) {
|
||||
if ((x - y*(nx-x)/(ny-y)) > 0.)
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
x = nx; y = ny;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(x>0.0 || nx>0.) {
|
||||
if((x-y*(nx-x)/(ny-y))>0.) {
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SH = NH;
|
||||
}
|
||||
x = nx; y = ny;
|
||||
}
|
||||
return(nbc&1);
|
||||
}
|
||||
|
||||
//modified by NIZNHY-PKV Fri Jan 15 09:03:48 2010f
|
||||
//=======================================================================
|
||||
//function : InternalSiDansOuOn
|
||||
@@ -229,71 +322,117 @@ Standard_Integer CSLib_Class2d::InternalSiDans(const Standard_Real Px,
|
||||
Standard_Integer CSLib_Class2d::InternalSiDansOuOn(const Standard_Real Px,
|
||||
const Standard_Real Py) const
|
||||
{
|
||||
Standard_Integer nbc, i, ip1, SH, NH, iRet;
|
||||
Standard_Integer nbc, i, ip1, SH, NH, iRet = 0;
|
||||
Standard_Real *Pnts2dX, *Pnts2dY;
|
||||
Standard_Real x, y, nx, ny, aX;
|
||||
Standard_Real aYmin;
|
||||
//
|
||||
nbc = 0;
|
||||
i = 0;
|
||||
ip1 = 1;
|
||||
Pnts2dX = (Standard_Real *)MyPnts2dX;
|
||||
Pnts2dY = (Standard_Real *)MyPnts2dY;
|
||||
x = (Pnts2dX[i]-Px);
|
||||
y = (Pnts2dY[i]-Py);
|
||||
aYmin=y;
|
||||
SH = (y<0.)? -1 : 1;
|
||||
for(i=0; i<N ; i++, ip1++) {
|
||||
|
||||
nx = Pnts2dX[ip1] - Px;
|
||||
ny = Pnts2dY[ip1] - Py;
|
||||
//-- le 14 oct 97
|
||||
if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) {
|
||||
iRet=-1;
|
||||
return iRet;
|
||||
}
|
||||
//find Y coordinate of polyline for current X gka
|
||||
//in order to detect possible status ON
|
||||
Standard_Real aDx = (Pnts2dX[ip1] - Pnts2dX[ip1-1]);
|
||||
if( (Pnts2dX[ip1-1] - Px) * nx < 0.)
|
||||
{
|
||||
|
||||
Standard_Real aCurPY = Pnts2dY[ip1] - (Pnts2dY[ip1] - Pnts2dY[ip1-1])/aDx *nx;
|
||||
Standard_Real aDeltaY = aCurPY - Py;
|
||||
if(aDeltaY >= -Tolv && aDeltaY <= Tolv)
|
||||
Pnts2dX = MyPnts2d;
|
||||
Pnts2dY = Pnts2dX + 1;
|
||||
if (MyBoxes1d == NULL)
|
||||
{
|
||||
x = (Pnts2dX[0]-Px);
|
||||
y = (Pnts2dY[0]-Py);
|
||||
SH = (y<0.)? -1 : 1;
|
||||
for(i=0; i<N ; i++, ip1++)
|
||||
{
|
||||
nx = Pnts2dX[2*ip1] - Px;
|
||||
ny = Pnts2dY[2*ip1] - Py;
|
||||
//-- le 14 oct 97
|
||||
if(nx<Tolu && nx>-Tolu && ny<Tolv && ny>-Tolv) {
|
||||
iRet=-1;
|
||||
return iRet;
|
||||
}
|
||||
//find Y coordinate of polyline for current X gka
|
||||
//in order to detect possible status ON
|
||||
Standard_Real aDx = (Pnts2dX[2*ip1] - Pnts2dX[2*(ip1-1)]);
|
||||
if( (Pnts2dX[2*(ip1-1)] - Px) * nx < 0.)
|
||||
{
|
||||
iRet=-1;
|
||||
return iRet;
|
||||
|
||||
Standard_Real aCurPY =
|
||||
Pnts2dY[2*ip1] - (Pnts2dY[2*ip1] - Pnts2dY[2*(ip1-1)])/aDx *nx;
|
||||
Standard_Real aDeltaY = aCurPY - Py;
|
||||
if(aDeltaY >= -Tolv && aDeltaY <= Tolv)
|
||||
{
|
||||
iRet=-1;
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
|
||||
NH = (ny<0.)? -1 : 1;
|
||||
if(NH!=SH) {
|
||||
if(x>0. && nx>0.) {
|
||||
nbc++;
|
||||
NH = (ny<0.)? -1 : 1;
|
||||
if(NH!=SH) {
|
||||
if(x>0. && nx>0.) {
|
||||
nbc++;
|
||||
}
|
||||
else {
|
||||
if(x>0. || nx>0.) {
|
||||
aX=x-y*(nx-x)/(ny-y);
|
||||
if(aX>0.){
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SH = NH;
|
||||
}
|
||||
else {
|
||||
if(x>0. || nx>0.) {
|
||||
aX=x-y*(nx-x)/(ny-y);
|
||||
if(aX>0.){
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
x = nx; y = ny;
|
||||
}// for(i=0; i<N ; i++,ip1++) {
|
||||
}
|
||||
else
|
||||
{
|
||||
const Standard_Real aTolu2(Tolu * Tolu);
|
||||
const Standard_Real aTolv2(Tolv * Tolv);
|
||||
|
||||
// Find Y-boxes that include Py. Box with index iBox refers the range of
|
||||
// points starting from iBox*sizeBox.
|
||||
for (Standard_Integer iBox = 0; iBox < myNBoxes; iBox++) {
|
||||
if ((MyBoxes1d[2*iBox] - Tolv - Py) * (MyBoxes1d[2*iBox+1] + Tolv - Py) < 0.)
|
||||
{
|
||||
Standard_Integer lastBox = (iBox + 1) * mySizeBox;
|
||||
if (lastBox > N)
|
||||
lastBox = N;
|
||||
x = (Pnts2dX[2*iBox*mySizeBox]-Px);
|
||||
y = (Pnts2dY[2*iBox*mySizeBox]-Py);
|
||||
for (i = iBox*mySizeBox; i < lastBox; i++)
|
||||
{
|
||||
nx = Pnts2dX[2*(i+1)] - Px;
|
||||
ny = Pnts2dY[2*(i+1)] - Py;
|
||||
if (nx * nx < aTolu2 && ny * ny < aTolv2) {
|
||||
iRet = -1;
|
||||
break;
|
||||
}
|
||||
//find Y coordinate of polyline for current X gka
|
||||
//in order to detect possible status ON
|
||||
if (x /*(Pnts2dX[2*(ip1-1)] - Px)*/ * nx < 0.)
|
||||
{
|
||||
const Standard_Real aDeltaY = ny - (ny - y)/(nx - x) * nx;
|
||||
if (aDeltaY*aDeltaY <= aTolv2) {
|
||||
iRet = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ny * y < 0.) {
|
||||
if (x > 0. && nx > 0.)
|
||||
nbc++;
|
||||
else if (x > 0. || nx > 0.) {
|
||||
if ((x - y*(nx-x)/(ny-y)) > 0.)
|
||||
nbc++;
|
||||
}
|
||||
}
|
||||
x = nx; y = ny;
|
||||
} // for(.. i ..)
|
||||
if (iRet < 0)
|
||||
break;
|
||||
}
|
||||
SH = NH;
|
||||
}
|
||||
else {// y has same sign as ny
|
||||
if (ny<aYmin) {
|
||||
aYmin=ny;
|
||||
}
|
||||
}
|
||||
x = nx; y = ny;
|
||||
}// for(i=0; i<N ; i++,ip1++) {
|
||||
|
||||
iRet=nbc&1;
|
||||
} // for(.. iBox ..)
|
||||
}
|
||||
if (iRet == 0)
|
||||
iRet = nbc&1;
|
||||
return iRet;
|
||||
}
|
||||
|
||||
//modified by NIZNHY-PKV Fri Jan 15 09:03:55 2010t
|
||||
//=======================================================================
|
||||
//function : Copy
|
||||
|
@@ -73,8 +73,10 @@ private:
|
||||
|
||||
|
||||
|
||||
Standard_Address MyPnts2dX;
|
||||
Standard_Address MyPnts2dY;
|
||||
Standard_Real * MyPnts2d;
|
||||
Standard_Real * MyBoxes1d;
|
||||
Standard_Integer mySizeBox;
|
||||
Standard_Integer myNBoxes;
|
||||
Standard_Real Tolu;
|
||||
Standard_Real Tolv;
|
||||
Standard_Integer N;
|
||||
|
@@ -350,11 +350,6 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
|
||||
#else
|
||||
di << "FreeImage disabled\n";
|
||||
#endif
|
||||
#ifdef HAVE_FFMPEG
|
||||
di << "FFmpeg enabled (HAVE_FFMPEG)\n";
|
||||
#else
|
||||
di << "FFmpeg disabled\n";
|
||||
#endif
|
||||
#ifdef HAVE_GLES2
|
||||
di << "OpenGL: ES2\n";
|
||||
#else
|
||||
|
@@ -576,12 +576,13 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
|
||||
//-- if(Nbp < MinNb) { cout<<"\n*"; } else { cout<<"\n."; }
|
||||
while(Nbp < MinNb) {
|
||||
//-- cout<<" \nGCPnts TangentialDeflection : Ajout de Points ("<<Nbp<<" "<<minNbPnts<<" )"<<endl;
|
||||
for (i = 2; i <= Nbp; i += 2) {
|
||||
for(i=2; i<=Nbp; i++) {
|
||||
MiddleU = (parameters.Value(i-1)+parameters.Value(i))*0.5;
|
||||
D0 (C, MiddleU, MiddlePoint);
|
||||
parameters.InsertBefore(i,MiddleU);
|
||||
points.InsertBefore(i,MiddlePoint);
|
||||
Nbp++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
//Additional check for intervals
|
||||
|
@@ -7,5 +7,3 @@ Image_Format.hxx
|
||||
Image_PixMap.cxx
|
||||
Image_PixMap.hxx
|
||||
Image_PixMapData.hxx
|
||||
Image_VideoRecorder.cxx
|
||||
Image_VideoRecorder.hxx
|
||||
|
@@ -1,509 +0,0 @@
|
||||
// Created on: 2016-04-01
|
||||
// Created by: Anastasia BORISOVA
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
// activate some C99 macros like UINT64_C in "stdint.h" which used by FFmpeg
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#endif
|
||||
|
||||
#include <Image_VideoRecorder.hxx>
|
||||
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
|
||||
#ifdef HAVE_FFMPEG
|
||||
|
||||
// Suppress deprecation warnings - it is difficult to provide compatibility with old and new API at once
|
||||
// since new APIs are introduced too often.
|
||||
// Should be disabled from time to time to clean up usage of old APIs.
|
||||
#if (defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
#else
|
||||
Standard_DISABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
// suppress some common warnings in FFmpeg headers
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4244)
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Image_VideoRecorder, Standard_Transient)
|
||||
|
||||
//=============================================================================
|
||||
//function : Constructor
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Image_VideoRecorder::Image_VideoRecorder()
|
||||
: myAVContext (NULL),
|
||||
myVideoStream (NULL),
|
||||
myVideoCodec (NULL),
|
||||
myFrame (NULL),
|
||||
myScaleCtx (NULL),
|
||||
myFrameCount (0)
|
||||
{
|
||||
myFrameRate.num = 1;
|
||||
myFrameRate.den = 30;
|
||||
|
||||
#ifdef HAVE_FFMPEG
|
||||
// initialize libavcodec, and register all codecs and formats, should be done once
|
||||
av_register_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ~Image_VideoRecorder
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Image_VideoRecorder::~Image_VideoRecorder()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : formatAvError
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
TCollection_AsciiString Image_VideoRecorder::formatAvError (const int theError) const
|
||||
{
|
||||
#ifdef HAVE_FFMPEG
|
||||
char anErrBuf[AV_ERROR_MAX_STRING_SIZE] = {};
|
||||
av_strerror (theError, anErrBuf, AV_ERROR_MAX_STRING_SIZE);
|
||||
return anErrBuf;
|
||||
#else
|
||||
return TCollection_AsciiString(theError);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Close
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
void Image_VideoRecorder::Close()
|
||||
{
|
||||
#ifdef HAVE_FFMPEG
|
||||
if (myScaleCtx != NULL)
|
||||
{
|
||||
sws_freeContext (myScaleCtx);
|
||||
myScaleCtx = NULL;
|
||||
}
|
||||
|
||||
if (myAVContext == NULL)
|
||||
{
|
||||
myFrameCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the trailer, if any. The trailer must be written before you close the CodecContexts open when you wrote the header;
|
||||
// otherwise av_write_trailer() may try to use memory that was freed on av_codec_close().
|
||||
if (myFrameCount != 0)
|
||||
{
|
||||
av_write_trailer (myAVContext);
|
||||
myFrameCount = 0;
|
||||
}
|
||||
|
||||
// close each codec
|
||||
if (myVideoStream != NULL)
|
||||
{
|
||||
avcodec_close (myVideoStream->codec);
|
||||
myVideoStream = NULL;
|
||||
}
|
||||
if (myFrame != NULL)
|
||||
{
|
||||
av_free (myFrame->data[0]);
|
||||
av_frame_free (&myFrame);
|
||||
myFrame = NULL;
|
||||
}
|
||||
|
||||
if (!(myAVContext->oformat->flags & AVFMT_NOFILE))
|
||||
{
|
||||
// close the output file
|
||||
avio_close (myAVContext->pb);
|
||||
}
|
||||
|
||||
// free the stream
|
||||
avformat_free_context (myAVContext);
|
||||
myAVContext = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Open
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Image_VideoRecorder::Open (const char* theFileName,
|
||||
const Image_VideoParams& theParams)
|
||||
{
|
||||
#ifdef HAVE_FFMPEG
|
||||
Close();
|
||||
if (theParams.Width <= 0
|
||||
|| theParams.Height <= 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// allocate the output media context
|
||||
avformat_alloc_output_context2 (&myAVContext, NULL, theParams.Format.IsEmpty() ? NULL : theParams.Format.ToCString(), theFileName);
|
||||
if (myAVContext == NULL)
|
||||
{
|
||||
::Message::DefaultMessenger()->Send ("ViewerTest_VideoRecorder, could not deduce output format from file extension", Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// add the audio stream using the default format codecs and initialize the codecs
|
||||
if (!addVideoStream (theParams, myAVContext->oformat->video_codec))
|
||||
{
|
||||
Close();
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// open video codec and allocate the necessary encode buffers
|
||||
if (!openVideoCodec (theParams))
|
||||
{
|
||||
Close();
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
av_dump_format (myAVContext, 0, theFileName, 1);
|
||||
#endif
|
||||
|
||||
// open the output file, if needed
|
||||
if ((myAVContext->oformat->flags & AVFMT_NOFILE) == 0)
|
||||
{
|
||||
const int aResAv = avio_open (&myAVContext->pb, theFileName, AVIO_FLAG_WRITE);
|
||||
if (aResAv < 0)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: could not open '") + theFileName + "', " + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
Close();
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// write the stream header, if any
|
||||
const int aResAv = avformat_write_header (myAVContext, NULL);
|
||||
if (aResAv < 0)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not open output file '") + theFileName + "', " + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
Close();
|
||||
return Standard_False;
|
||||
}
|
||||
#else
|
||||
(void )theFileName;
|
||||
(void )theParams;
|
||||
#endif
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : addVideoStream
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Image_VideoRecorder::addVideoStream (const Image_VideoParams& theParams,
|
||||
const Standard_Integer theDefCodecId)
|
||||
{
|
||||
myFrameRate.num = theParams.FpsNum;
|
||||
myFrameRate.den = theParams.FpsDen;
|
||||
|
||||
#ifdef HAVE_FFMPEG
|
||||
// find the encoder
|
||||
TCollection_AsciiString aCodecName;
|
||||
if (!theParams.VideoCodec.IsEmpty())
|
||||
{
|
||||
myVideoCodec = avcodec_find_encoder_by_name (theParams.VideoCodec.ToCString());
|
||||
aCodecName = theParams.VideoCodec;
|
||||
}
|
||||
else
|
||||
{
|
||||
myVideoCodec = avcodec_find_encoder ((AVCodecID )theDefCodecId);
|
||||
aCodecName = avcodec_get_name ((AVCodecID )theDefCodecId);
|
||||
}
|
||||
if (myVideoCodec == NULL)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not find encoder for ") + aCodecName;
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
const AVCodecID aCodecId = myVideoCodec->id;
|
||||
myVideoStream = avformat_new_stream (myAVContext, myVideoCodec);
|
||||
if (myVideoStream == NULL)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate stream!");
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
myVideoStream->id = myAVContext->nb_streams - 1;
|
||||
|
||||
AVCodecContext* aCodecCtx = myVideoStream->codec;
|
||||
aCodecCtx->codec_id = aCodecId;
|
||||
// resolution must be a multiple of two
|
||||
aCodecCtx->width = theParams.Width;
|
||||
aCodecCtx->height = theParams.Height;
|
||||
// Timebase is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
|
||||
// For fixed-fps content, timebase should be 1/framerate and timestamp increments should be identical to 1.
|
||||
aCodecCtx->time_base.den = myFrameRate.num;
|
||||
aCodecCtx->time_base.num = myFrameRate.den;
|
||||
aCodecCtx->gop_size = 12; // emit one intra frame every twelve frames at most
|
||||
|
||||
// some formats want stream headers to be separate
|
||||
if (myAVContext->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
{
|
||||
aCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
return Standard_True;
|
||||
#else
|
||||
(void )theParams;
|
||||
(void )theDefCodecId;
|
||||
return Standard_False;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : openVideoCodec
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Image_VideoRecorder::openVideoCodec (const Image_VideoParams& theParams)
|
||||
{
|
||||
#ifdef HAVE_FFMPEG
|
||||
AVDictionary* anOptions = NULL;
|
||||
AVCodecContext* aCodecCtx = myVideoStream->codec;
|
||||
|
||||
// setup default values
|
||||
aCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
//av_dict_set (&anOptions, "threads", "auto", 0);
|
||||
if (aCodecCtx->codec == avcodec_find_encoder_by_name ("mpeg2video"))
|
||||
{
|
||||
// just for testing, we also add B frames
|
||||
aCodecCtx->max_b_frames = 2;
|
||||
aCodecCtx->bit_rate = 6000000;
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("mpeg4"))
|
||||
{
|
||||
//
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("mjpeg"))
|
||||
{
|
||||
aCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;
|
||||
aCodecCtx->qmin = aCodecCtx->qmax = 5;
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("huffyuv"))
|
||||
{
|
||||
aCodecCtx->pix_fmt = AV_PIX_FMT_RGB24;
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("png"))
|
||||
{
|
||||
aCodecCtx->pix_fmt = AV_PIX_FMT_RGB24;
|
||||
aCodecCtx->compression_level = 9; // 0..9
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("h264")
|
||||
|| aCodecCtx->codec == avcodec_find_encoder_by_name ("libx264"))
|
||||
{
|
||||
// use CRF (Constant Rate Factor) as best single-pass compressing method
|
||||
av_dict_set (&anOptions, "crf", "20", 0); // quality 18-28, 23 is default (normal), 18 is almost lossless
|
||||
av_dict_set (&anOptions, "preset", "slow", 0); // good compression (see also "veryslow", "ultrafast")
|
||||
|
||||
// live-capturing
|
||||
//av_dict_set (&anOptions, "qp", "0", 0); // instead of crf
|
||||
//av_dict_set (&anOptions, "preset", "ultrafast", 0);
|
||||
|
||||
// compatibility with devices
|
||||
//av_dict_set (&anOptions, "profile", "baseline", 0);
|
||||
//av_dict_set (&anOptions, "level", "3.0", 0);
|
||||
}
|
||||
else if (aCodecCtx->codec == avcodec_find_encoder_by_name ("vp8")
|
||||
|| aCodecCtx->codec == avcodec_find_encoder_by_name ("vp9"))
|
||||
{
|
||||
av_dict_set (&anOptions, "crf", "20", 0); // quality 4<>63, 10 is normal
|
||||
}
|
||||
|
||||
// override defaults with specified options
|
||||
if (!theParams.PixelFormat.IsEmpty())
|
||||
{
|
||||
const AVPixelFormat aPixFormat = av_get_pix_fmt (theParams.PixelFormat.ToCString());
|
||||
if (aPixFormat == AV_PIX_FMT_NONE)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: unknown pixel format has been specified '") + theParams.PixelFormat + "'";
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
aCodecCtx->pix_fmt = aPixFormat;
|
||||
for (Resource_DataMapOfAsciiStringAsciiString::Iterator aParamIter (theParams.VideoCodecParams);
|
||||
aParamIter.More(); aParamIter.Next())
|
||||
{
|
||||
av_dict_set (&anOptions, aParamIter.Key().ToCString(), aParamIter.Value().ToCString(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// open codec
|
||||
int aResAv = avcodec_open2 (aCodecCtx, myVideoCodec, &anOptions);
|
||||
if (anOptions != NULL)
|
||||
{
|
||||
av_dict_free (&anOptions);
|
||||
}
|
||||
if (aResAv < 0)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not open video codec, ") + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// allocate and init a re-usable frame
|
||||
myFrame = av_frame_alloc();
|
||||
if (myFrame == NULL)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate video frame!");
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// allocate the encoded raw picture
|
||||
aResAv = av_image_alloc (myFrame->data, myFrame->linesize,
|
||||
aCodecCtx->width, aCodecCtx->height, aCodecCtx->pix_fmt, 1);
|
||||
if (aResAv < 0)
|
||||
{
|
||||
memset (myFrame->data, 0, sizeof(myFrame->data));
|
||||
memset (myFrame->linesize, 0, sizeof(myFrame->linesize));
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate picture ")
|
||||
+ aCodecCtx->width+ "x" + aCodecCtx->height + ", " + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
// copy data and linesize picture pointers to frame
|
||||
myFrame->format = aCodecCtx->pix_fmt;
|
||||
myFrame->width = aCodecCtx->width;
|
||||
myFrame->height = aCodecCtx->height;
|
||||
|
||||
const Standard_Size aStride = aCodecCtx->width + 16 - (aCodecCtx->width % 16);
|
||||
if (!myImgSrcRgba.InitZero (Image_PixMap::ImgRGBA, aCodecCtx->width, aCodecCtx->height, aStride))
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not allocate RGBA32 picture ")
|
||||
+ aCodecCtx->width+ "x" + aCodecCtx->height;
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
myScaleCtx = sws_getContext (aCodecCtx->width, aCodecCtx->height, AV_PIX_FMT_RGBA,
|
||||
aCodecCtx->width, aCodecCtx->height, aCodecCtx->pix_fmt,
|
||||
SWS_BICUBIC, NULL, NULL, NULL);
|
||||
if (myScaleCtx == NULL)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not initialize the conversion context!");
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
return Standard_True;
|
||||
#else
|
||||
(void )theParams;
|
||||
return Standard_False;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : writeVideoFrame
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean Image_VideoRecorder::writeVideoFrame (const Standard_Boolean theToFlush)
|
||||
{
|
||||
#ifdef HAVE_FFMPEG
|
||||
int aResAv = 0;
|
||||
AVCodecContext* aCodecCtx = myVideoStream->codec;
|
||||
if (!theToFlush)
|
||||
{
|
||||
uint8_t* aSrcData[4] = { (uint8_t*)myImgSrcRgba.ChangeData(), NULL, NULL, NULL };
|
||||
int aSrcLinesize[4] = { (int )myImgSrcRgba.SizeRowBytes(), 0, 0, 0 };
|
||||
sws_scale (myScaleCtx,
|
||||
aSrcData, aSrcLinesize,
|
||||
0, aCodecCtx->height,
|
||||
myFrame->data, myFrame->linesize);
|
||||
}
|
||||
|
||||
AVPacket aPacket;
|
||||
memset (&aPacket, 0, sizeof(aPacket));
|
||||
av_init_packet (&aPacket);
|
||||
if ((myAVContext->oformat->flags & AVFMT_RAWPICTURE) != 0
|
||||
&& !theToFlush)
|
||||
{
|
||||
// raw video case - directly store the picture in the packet
|
||||
aPacket.flags |= AV_PKT_FLAG_KEY;
|
||||
aPacket.stream_index = myVideoStream->index;
|
||||
aPacket.data = myFrame->data[0];
|
||||
aPacket.size = sizeof(AVPicture);
|
||||
|
||||
aResAv = av_interleaved_write_frame (myAVContext, &aPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode the image
|
||||
myFrame->pts = myFrameCount;
|
||||
int isGotPacket = 0;
|
||||
aResAv = avcodec_encode_video2 (aCodecCtx, &aPacket, theToFlush ? NULL : myFrame, &isGotPacket);
|
||||
if (aResAv < 0)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not encode video frame, ") + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// if size is zero, it means the image was buffered
|
||||
if (isGotPacket)
|
||||
{
|
||||
const AVRational& aTimeBase = aCodecCtx->time_base;
|
||||
|
||||
// rescale output packet timestamp values from codec to stream timebase
|
||||
aPacket.pts = av_rescale_q_rnd (aPacket.pts, aTimeBase, myVideoStream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
aPacket.dts = av_rescale_q_rnd (aPacket.dts, aTimeBase, myVideoStream->time_base, AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
aPacket.duration = av_rescale_q (aPacket.duration, aTimeBase, myVideoStream->time_base);
|
||||
aPacket.stream_index = myVideoStream->index;
|
||||
|
||||
// write the compressed frame to the media file
|
||||
aResAv = av_interleaved_write_frame (myAVContext, &aPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
aResAv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (aResAv < 0)
|
||||
{
|
||||
const TCollection_AsciiString aMsg = TCollection_AsciiString ("Error: can not write video frame, ") + formatAvError (aResAv);
|
||||
::Message::DefaultMessenger()->Send (aMsg, Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
++myFrameCount;
|
||||
return Standard_True;
|
||||
#else
|
||||
(void)theToFlush;
|
||||
return Standard_False;
|
||||
#endif
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
// Created on: 2016-04-01
|
||||
// Created by: Anastasia BORISOVA
|
||||
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef Image_VideoRecorder_HeaderFile_
|
||||
#define Image_VideoRecorder_HeaderFile_
|
||||
|
||||
#include <Image_PixMap.hxx>
|
||||
#include <Resource_DataMapOfAsciiStringAsciiString.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
// forward declarations
|
||||
struct AVFormatContext;
|
||||
struct AVStream;
|
||||
struct AVCodec;
|
||||
struct AVFrame;
|
||||
struct SwsContext;
|
||||
|
||||
//! Auxiliary structure defining video parameters.
|
||||
//! Please refer to FFmpeg documentation for defining text values.
|
||||
struct Image_VideoParams
|
||||
{
|
||||
TCollection_AsciiString Format; //!< [optional] video format (container), if empty - will be determined from the file name
|
||||
TCollection_AsciiString VideoCodec; //!< [optional] codec identifier, if empty - default codec from file format will be used
|
||||
TCollection_AsciiString PixelFormat; //!< [optional] pixel format, if empty - default codec pixel format will be used
|
||||
Standard_Integer Width; //!< [mandatory] video frame width
|
||||
Standard_Integer Height; //!< [mandatory] video frame height
|
||||
Standard_Integer FpsNum; //!< [mandatory] framerate numerator
|
||||
Standard_Integer FpsDen; //!< [mandatory] framerate denumerator
|
||||
Resource_DataMapOfAsciiStringAsciiString
|
||||
VideoCodecParams; //!< map of advanced video codec parameters
|
||||
|
||||
//! Empty constructor.
|
||||
Image_VideoParams() : Width (0), Height (0), FpsNum (0), FpsDen (1) {}
|
||||
|
||||
//! Setup playback FPS.
|
||||
void SetFramerate (const Standard_Integer theNumerator,
|
||||
const Standard_Integer theDenominator)
|
||||
{
|
||||
FpsNum = theNumerator;
|
||||
FpsDen = theDenominator;
|
||||
}
|
||||
|
||||
//! Setup playback FPS.
|
||||
//! For fixed-fps content, timebase should be 1/framerate and timestamp increments should be identical to 1.
|
||||
void SetFramerate (const Standard_Integer theValue)
|
||||
{
|
||||
FpsNum = theValue;
|
||||
FpsDen = 1;
|
||||
}
|
||||
};
|
||||
|
||||
//! Video recording tool based on FFmpeg framework.
|
||||
class Image_VideoRecorder : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Image_VideoRecorder, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Empty constructor.
|
||||
Standard_EXPORT Image_VideoRecorder();
|
||||
|
||||
//! Destructor.
|
||||
Standard_EXPORT virtual ~Image_VideoRecorder();
|
||||
|
||||
//! Close the stream - stop recorder.
|
||||
Standard_EXPORT void Close();
|
||||
|
||||
//! Open output stream - initialize recorder.
|
||||
//! @param theFileName [in] video filename
|
||||
//! @param theParams [in] video parameters
|
||||
Standard_EXPORT Standard_Boolean Open (const char* theFileName,
|
||||
const Image_VideoParams& theParams);
|
||||
|
||||
//! Access RGBA frame, should NOT be re-initialized outside.
|
||||
//! Note that image is expected to have upper-left origin.
|
||||
Image_PixMap& ChangeFrame() { return myImgSrcRgba; }
|
||||
|
||||
//! Return current frame index.
|
||||
int64_t FrameCount() const { return myFrameCount; }
|
||||
|
||||
//! Push new frame, should be called after Open().
|
||||
Standard_Boolean PushFrame()
|
||||
{
|
||||
return writeVideoFrame (Standard_False);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Wrapper for av_strerror().
|
||||
Standard_EXPORT TCollection_AsciiString formatAvError (const int theError) const;
|
||||
|
||||
//! Append video stream.
|
||||
//! theParams [in] video parameters
|
||||
//! theDefCodecId [in] identifier of codec managed by FFmpeg library (AVCodecID enum)
|
||||
Standard_EXPORT Standard_Boolean addVideoStream (const Image_VideoParams& theParams,
|
||||
const Standard_Integer theDefCodecId);
|
||||
|
||||
//! Open video codec.
|
||||
Standard_EXPORT Standard_Boolean openVideoCodec (const Image_VideoParams& theParams);
|
||||
|
||||
//! Write new video frame.
|
||||
Standard_EXPORT Standard_Boolean writeVideoFrame (const Standard_Boolean theToFlush);
|
||||
|
||||
protected:
|
||||
|
||||
//! AVRational alias.
|
||||
struct VideoRational
|
||||
{
|
||||
int num; //!< numerator
|
||||
int den; //!< denominator
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
AVFormatContext* myAVContext; //!< video context
|
||||
AVStream* myVideoStream; //!< video stream
|
||||
AVCodec* myVideoCodec; //!< video codec
|
||||
AVFrame* myFrame; //!< frame to record
|
||||
SwsContext* myScaleCtx; //!< scale context for conversion from RGBA to YUV
|
||||
|
||||
Image_PixMap myImgSrcRgba; //!< input RGBA image
|
||||
VideoRational myFrameRate; //!< video framerate
|
||||
int64_t myFrameCount; //!< current frame index
|
||||
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Image_VideoRecorder, Standard_Transient)
|
||||
|
||||
#endif // Image_VideoRecorder_HeaderFile_
|
@@ -128,9 +128,33 @@ static Standard_Integer OCC527(Draw_Interpretor& di, Standard_Integer argc, cons
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlTransfer.hxx>
|
||||
//=======================================================================
|
||||
//function : OCC1048
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer OCC1048 (Draw_Interpretor& di, Standard_Integer argc, const char ** argv)
|
||||
{
|
||||
// Verify amount of arguments of the command
|
||||
if (argc < 2) { di << "Usage : " << argv[0] <<" shape"; return 1;}
|
||||
|
||||
TopoDS_Shape aShape = DBRep::Get(argv[1]);
|
||||
|
||||
Standard_Real theDeflection = 0.006;
|
||||
Handle(StlMesh_Mesh) theStlMesh = new StlMesh_Mesh;
|
||||
BRepMesh_IncrementalMesh aMesh(aShape, theDeflection);
|
||||
StlTransfer::RetrieveMesh(aShape, theStlMesh);
|
||||
Standard_Integer NBTRIANGLES = theStlMesh->NbTriangles();
|
||||
di<<"Info: Number of triangles = "<<NBTRIANGLES<<"\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QABugs::Commands_2(Draw_Interpretor& theCommands) {
|
||||
const char *group = "QABugs";
|
||||
|
||||
theCommands.Add("OCC527", "OCC527 shape", __FILE__, OCC527, group);
|
||||
theCommands.Add("OCC1048", "OCC1048 shape", __FILE__, OCC1048, group);
|
||||
return;
|
||||
}
|
||||
|
@@ -1,4 +1,2 @@
|
||||
RWStl.cxx
|
||||
RWStl.hxx
|
||||
RWStl_Reader.cxx
|
||||
RWStl_Reader.hxx
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// Created on: 2017-06-13
|
||||
// Created by: Alexander MALYSHEV
|
||||
// Copyright (c) 2017 OPEN CASCADE SAS
|
||||
// Created on: 1994-10-13
|
||||
// Created by: Marc LEGAY
|
||||
// Copyright (c) 1994-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
@@ -13,289 +14,272 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <RWStl.hxx>
|
||||
|
||||
#include <BRepBuilderAPI_CellFilter.hxx>
|
||||
#include <BRepBuilderAPI_VertexInspector.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <Message_ProgressIndicator.hxx>
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <OSD.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_Host.hxx>
|
||||
#include <OSD_OpenFile.hxx>
|
||||
#include <RWStl_Reader.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <OSD_Protection.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <RWStl.hxx>
|
||||
#include <Standard_NoMoreObject.hxx>
|
||||
#include <Standard_TypeMismatch.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshExplorer.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
namespace
|
||||
#include <stdio.h>
|
||||
// A static method adding nodes to a mesh and keeping coincident (sharing) nodes.
|
||||
static Standard_Integer AddVertex(Handle(StlMesh_Mesh)& mesh,
|
||||
BRepBuilderAPI_CellFilter& filter,
|
||||
BRepBuilderAPI_VertexInspector& inspector,
|
||||
const gp_XYZ& p)
|
||||
{
|
||||
|
||||
static const Standard_Integer THE_STL_SIZEOF_FACET = 50;
|
||||
static const Standard_Integer IND_THRESHOLD = 1000; // increment the indicator every 1k triangles
|
||||
|
||||
//! Writing a Little Endian 32 bits integer
|
||||
inline static void convertInteger (const Standard_Integer theValue,
|
||||
Standard_Character* theResult)
|
||||
Standard_Integer index;
|
||||
inspector.SetCurrent(p);
|
||||
gp_XYZ minp = inspector.Shift(p, -Precision::Confusion());
|
||||
gp_XYZ maxp = inspector.Shift(p, +Precision::Confusion());
|
||||
filter.Inspect(minp, maxp, inspector);
|
||||
const TColStd_ListOfInteger& indices = inspector.ResInd();
|
||||
if (indices.IsEmpty() == Standard_False)
|
||||
{
|
||||
union
|
||||
{
|
||||
Standard_Integer i;
|
||||
Standard_Character c[4];
|
||||
} anUnion;
|
||||
anUnion.i = theValue;
|
||||
|
||||
theResult[0] = anUnion.c[0];
|
||||
theResult[1] = anUnion.c[1];
|
||||
theResult[2] = anUnion.c[2];
|
||||
theResult[3] = anUnion.c[3];
|
||||
index = indices.First(); // it should be only one
|
||||
inspector.ClearResList();
|
||||
}
|
||||
|
||||
//! Writing a Little Endian 32 bits float
|
||||
inline static void convertDouble (const Standard_Real theValue,
|
||||
Standard_Character* theResult)
|
||||
else
|
||||
{
|
||||
union
|
||||
{
|
||||
Standard_ShortReal i;
|
||||
Standard_Character c[4];
|
||||
} anUnion;
|
||||
anUnion.i = (Standard_ShortReal)theValue;
|
||||
|
||||
theResult[0] = anUnion.c[0];
|
||||
theResult[1] = anUnion.c[1];
|
||||
theResult[2] = anUnion.c[2];
|
||||
theResult[3] = anUnion.c[3];
|
||||
index = mesh->AddVertex(p.X(), p.Y(), p.Z());
|
||||
filter.Add(index, p);
|
||||
inspector.Add(p);
|
||||
}
|
||||
|
||||
class Reader : public RWStl_Reader
|
||||
{
|
||||
public:
|
||||
//! Add new node
|
||||
virtual Standard_Integer AddNode (const gp_XYZ& thePnt) Standard_OVERRIDE
|
||||
{
|
||||
myNodes.Append (thePnt);
|
||||
return myNodes.Size();
|
||||
}
|
||||
|
||||
//! Add new triangle
|
||||
virtual void AddTriangle (Standard_Integer theNode1, Standard_Integer theNode2, Standard_Integer theNode3) Standard_OVERRIDE
|
||||
{
|
||||
myTriangles.Append (Poly_Triangle (theNode1, theNode2, theNode3));
|
||||
}
|
||||
|
||||
//! Creates Poly_Triangulation from collected data
|
||||
Handle(Poly_Triangulation) GetTriangulation()
|
||||
{
|
||||
Handle(Poly_Triangulation) aPoly = new Poly_Triangulation (myNodes.Length(), myTriangles.Length(), Standard_False);
|
||||
for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
|
||||
{
|
||||
aPoly->ChangeNode (aNodeIter + 1) = myNodes (aNodeIter);
|
||||
}
|
||||
|
||||
for (Standard_Integer aTriIter = 0; aTriIter < myTriangles.Size(); ++aTriIter)
|
||||
{
|
||||
aPoly->ChangeTriangle (aTriIter + 1) = myTriangles (aTriIter);
|
||||
}
|
||||
|
||||
return aPoly;
|
||||
}
|
||||
|
||||
private:
|
||||
NCollection_Vector<gp_XYZ> myNodes;
|
||||
NCollection_Vector<Poly_Triangle> myTriangles;
|
||||
};
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Read
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Handle(Poly_Triangulation) RWStl::ReadFile (const Standard_CString theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
// constants
|
||||
static const size_t HEADER_SIZE = 84;
|
||||
static const size_t SIZEOF_STL_FACET = 50;
|
||||
static const size_t ASCII_LINES_PER_FACET = 7;
|
||||
|
||||
static const int IND_THRESHOLD = 1000; // increment the indicator every 1k triangles
|
||||
|
||||
//=======================================================================
|
||||
//function : WriteInteger
|
||||
//purpose : writing a Little Endian 32 bits integer
|
||||
//=======================================================================
|
||||
|
||||
inline static void WriteInteger(OSD_File& ofile,const Standard_Integer value)
|
||||
{
|
||||
Reader aReader;
|
||||
if (!aReader.Read (theFile, theProgress))
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
return aReader.GetTriangulation();
|
||||
union {
|
||||
Standard_Integer i;// don't be afraid, this is just an unsigned int
|
||||
char c[4];
|
||||
} bidargum;
|
||||
|
||||
bidargum.i = value;
|
||||
|
||||
Standard_Integer entier;
|
||||
|
||||
entier = bidargum.c[0] & 0xFF;
|
||||
entier |= (bidargum.c[1] & 0xFF) << 0x08;
|
||||
entier |= (bidargum.c[2] & 0xFF) << 0x10;
|
||||
entier |= (bidargum.c[3] & 0xFF) << 0x18;
|
||||
|
||||
ofile.Write((char *)&entier,sizeof(bidargum.c));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ReadFile
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Handle(Poly_Triangulation) RWStl::ReadFile (const OSD_Path& theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
OSD_File aFile(theFile);
|
||||
if (!aFile.Exists())
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : WriteDouble2Float
|
||||
//purpose : writing a Little Endian 32 bits float
|
||||
//=======================================================================
|
||||
|
||||
TCollection_AsciiString aPath;
|
||||
theFile.SystemName (aPath);
|
||||
return ReadFile (aPath.ToCString(), theProgress);
|
||||
inline static void WriteDouble2Float(OSD_File& ofile,Standard_Real value)
|
||||
{
|
||||
union {
|
||||
Standard_ShortReal f;
|
||||
char c[4];
|
||||
} bidargum;
|
||||
|
||||
bidargum.f = (Standard_ShortReal)value;
|
||||
|
||||
Standard_Integer entier;
|
||||
|
||||
entier = bidargum.c[0] & 0xFF;
|
||||
entier |= (bidargum.c[1] & 0xFF) << 0x08;
|
||||
entier |= (bidargum.c[2] & 0xFF) << 0x10;
|
||||
entier |= (bidargum.c[3] & 0xFF) << 0x18;
|
||||
|
||||
ofile.Write((char *)&entier,sizeof(bidargum.c));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ReadBinary
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Handle(Poly_Triangulation) RWStl::ReadBinary (const OSD_Path& theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
|
||||
//=======================================================================
|
||||
//function : readFloat2Double
|
||||
//purpose : reading a Little Endian 32 bits float
|
||||
//=======================================================================
|
||||
|
||||
inline static Standard_Real ReadFloat2Double(OSD_File &aFile)
|
||||
{
|
||||
OSD_File aFile(theFile);
|
||||
if (!aFile.Exists())
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
}bidargum;
|
||||
|
||||
TCollection_AsciiString aPath;
|
||||
theFile.SystemName (aPath);
|
||||
char c[4];
|
||||
Standard_Address adr;
|
||||
adr = (Standard_Address)c;
|
||||
Standard_Integer lread;
|
||||
aFile.Read(adr,4,lread);
|
||||
bidargum.i = c[0] & 0xFF;
|
||||
bidargum.i |= (c[1] & 0xFF) << 0x08;
|
||||
bidargum.i |= (c[2] & 0xFF) << 0x10;
|
||||
bidargum.i |= (c[3] & 0xFF) << 0x18;
|
||||
|
||||
std::filebuf aBuf;
|
||||
OSD_OpenStream (aBuf, aPath, std::ios::in | std::ios::binary);
|
||||
if (!aBuf.is_open())
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
Standard_IStream aStream (&aBuf);
|
||||
|
||||
Reader aReader;
|
||||
if (!aReader.ReadBinary (aStream, theProgress))
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
|
||||
return aReader.GetTriangulation();
|
||||
return (Standard_Real)(bidargum.f);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : ReadAscii
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Handle(Poly_Triangulation) RWStl::ReadAscii (const OSD_Path& theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
OSD_File aFile (theFile);
|
||||
if (!aFile.Exists())
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
|
||||
TCollection_AsciiString aPath;
|
||||
theFile.SystemName (aPath);
|
||||
|
||||
std::filebuf aBuf;
|
||||
OSD_OpenStream (aBuf, aPath, std::ios::in | std::ios::binary);
|
||||
if (!aBuf.is_open())
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
Standard_IStream aStream (&aBuf);
|
||||
//=======================================================================
|
||||
//function : WriteBinary
|
||||
//purpose : write a binary STL file in Little Endian format
|
||||
//=======================================================================
|
||||
|
||||
// get length of file to feed progress indicator
|
||||
aStream.seekg (0, aStream.end);
|
||||
std::streampos theEnd = aStream.tellg();
|
||||
aStream.seekg (0, aStream.beg);
|
||||
|
||||
Reader aReader;
|
||||
if (!aReader.ReadAscii (aStream, theEnd, theProgress))
|
||||
{
|
||||
return Handle(Poly_Triangulation)();
|
||||
}
|
||||
|
||||
return aReader.GetTriangulation();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean RWStl::WriteBinary (const Handle(Poly_Triangulation)& aMesh,
|
||||
Standard_Boolean RWStl::WriteBinary (const Handle(StlMesh_Mesh)& theMesh,
|
||||
const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd)
|
||||
{
|
||||
TCollection_AsciiString aPath;
|
||||
thePath.SystemName (aPath);
|
||||
OSD_File aFile (thePath);
|
||||
aFile.Build (OSD_WriteOnly, OSD_Protection());
|
||||
|
||||
FILE* aFile = OSD_OpenFile (aPath, "wb");
|
||||
if (aFile == NULL)
|
||||
Standard_Real x1, y1, z1;
|
||||
Standard_Real x2, y2, z2;
|
||||
Standard_Real x3, y3, z3;
|
||||
|
||||
// writing 80 bytes of the trash?
|
||||
char sval[80];
|
||||
aFile.Write ((Standard_Address)sval,80);
|
||||
WriteInteger (aFile, theMesh->NbTriangles());
|
||||
|
||||
int dum=0;
|
||||
StlMesh_MeshExplorer aMexp (theMesh);
|
||||
|
||||
// create progress sentry for domains
|
||||
Standard_Integer aNbDomains = theMesh->NbDomains();
|
||||
Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1);
|
||||
for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next())
|
||||
{
|
||||
return Standard_False;
|
||||
// create progress sentry for triangles in domain
|
||||
Message_ProgressSentry aTPS (theProgInd, "Triangles", 0,
|
||||
theMesh->NbTriangles (nbd), IND_THRESHOLD);
|
||||
Standard_Integer aTriangleInd = 0;
|
||||
for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle())
|
||||
{
|
||||
aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3);
|
||||
//pgo aMexp.TriangleOrientation (x,y,z);
|
||||
gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1));
|
||||
gp_XYZ Vect13 ((x3-x1), (y3-y1), (z3-z1));
|
||||
gp_XYZ Vnorm = Vect12 ^ Vect13;
|
||||
Standard_Real Vmodul = Vnorm.Modulus ();
|
||||
if (Vmodul > gp::Resolution())
|
||||
{
|
||||
Vnorm.Divide(Vmodul);
|
||||
}
|
||||
else
|
||||
{
|
||||
// si Vnorm est quasi-nul, on le charge a 0 explicitement
|
||||
Vnorm.SetCoord (0., 0., 0.);
|
||||
}
|
||||
|
||||
WriteDouble2Float (aFile, Vnorm.X());
|
||||
WriteDouble2Float (aFile, Vnorm.Y());
|
||||
WriteDouble2Float (aFile, Vnorm.Z());
|
||||
|
||||
WriteDouble2Float (aFile, x1);
|
||||
WriteDouble2Float (aFile, y1);
|
||||
WriteDouble2Float (aFile, z1);
|
||||
|
||||
WriteDouble2Float (aFile, x2);
|
||||
WriteDouble2Float (aFile, y2);
|
||||
WriteDouble2Float (aFile, z2);
|
||||
|
||||
WriteDouble2Float (aFile, x3);
|
||||
WriteDouble2Float (aFile, y3);
|
||||
WriteDouble2Float (aFile, z3);
|
||||
|
||||
aFile.Write (&dum, 2);
|
||||
|
||||
// update progress only per 1k triangles
|
||||
if (++aTriangleInd % IND_THRESHOLD == 0)
|
||||
{
|
||||
if (!aTPS.More())
|
||||
break;
|
||||
aTPS.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean isOK = writeBinary (aMesh, aFile, theProgInd);
|
||||
|
||||
fclose (aFile);
|
||||
return isOK;
|
||||
aFile.Close();
|
||||
Standard_Boolean isInterrupted = !aDPS.More();
|
||||
return !isInterrupted;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : WriteAscii
|
||||
//purpose : write an ASCII STL file
|
||||
//=======================================================================
|
||||
|
||||
//=============================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean RWStl::WriteAscii (const Handle(Poly_Triangulation)& theMesh,
|
||||
Standard_Boolean RWStl::WriteAscii (const Handle(StlMesh_Mesh)& theMesh,
|
||||
const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd)
|
||||
{
|
||||
TCollection_AsciiString aPath;
|
||||
thePath.SystemName (aPath);
|
||||
OSD_File theFile (thePath);
|
||||
theFile.Build(OSD_WriteOnly,OSD_Protection());
|
||||
TCollection_AsciiString buf ("solid\n");
|
||||
theFile.Write (buf,buf.Length());buf.Clear();
|
||||
|
||||
FILE* aFile = OSD_OpenFile (aPath, "w");
|
||||
if (aFile == NULL)
|
||||
Standard_Real x1, y1, z1;
|
||||
Standard_Real x2, y2, z2;
|
||||
Standard_Real x3, y3, z3;
|
||||
char sval[512];
|
||||
|
||||
// create progress sentry for domains
|
||||
Standard_Integer aNbDomains = theMesh->NbDomains();
|
||||
Message_ProgressSentry aDPS (theProgInd, "Mesh domains", 0, aNbDomains, 1);
|
||||
StlMesh_MeshExplorer aMexp (theMesh);
|
||||
for (Standard_Integer nbd = 1; nbd <= aNbDomains && aDPS.More(); nbd++, aDPS.Next())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean isOK = writeASCII (theMesh, aFile, theProgInd);
|
||||
fclose (aFile);
|
||||
return isOK;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : writeASCII
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean RWStl::writeASCII (const Handle(Poly_Triangulation)& theMesh,
|
||||
FILE* theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd)
|
||||
{
|
||||
// note that space after 'solid' is necessary for many systems
|
||||
if (fwrite ("solid \n", 1, 7, theFile) != 7)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
char aBuffer[512];
|
||||
memset (aBuffer, 0, sizeof(aBuffer));
|
||||
|
||||
Message_ProgressSentry aPS (theProgInd, "Triangles", 0,
|
||||
theMesh->NbTriangles(), IND_THRESHOLD);
|
||||
|
||||
const TColgp_Array1OfPnt& aNodes = theMesh->Nodes();
|
||||
const Poly_Array1OfTriangle& aTriangles = theMesh->Triangles();
|
||||
const Standard_Integer NBTriangles = theMesh->NbTriangles();
|
||||
Standard_Integer anElem[3] = {0, 0, 0};
|
||||
for (Standard_Integer aTriIter = 1; aTriIter <= NBTriangles; ++aTriIter)
|
||||
{
|
||||
const Poly_Triangle& aTriangle = aTriangles (aTriIter);
|
||||
aTriangle.Get (anElem[0], anElem[1], anElem[2]);
|
||||
|
||||
const gp_Pnt aP1 = aNodes (anElem[0]);
|
||||
const gp_Pnt aP2 = aNodes (anElem[1]);
|
||||
const gp_Pnt aP3 = aNodes (anElem[2]);
|
||||
|
||||
const gp_Vec aVec1 (aP1, aP2);
|
||||
const gp_Vec aVec2 (aP1, aP3);
|
||||
gp_Vec aVNorm = aVec1.Crossed (aVec2);
|
||||
if (aVNorm.SquareMagnitude() > gp::Resolution())
|
||||
// create progress sentry for triangles in domain
|
||||
Message_ProgressSentry aTPS (theProgInd, "Triangles", 0,
|
||||
theMesh->NbTriangles (nbd), IND_THRESHOLD);
|
||||
Standard_Integer aTriangleInd = 0;
|
||||
for (aMexp.InitTriangle (nbd); aMexp.MoreTriangle(); aMexp.NextTriangle())
|
||||
{
|
||||
aVNorm.Normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
aVNorm.SetCoord (0.0, 0.0, 0.0);
|
||||
}
|
||||
aMexp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3);
|
||||
|
||||
Sprintf (aBuffer,
|
||||
// Standard_Real x, y, z;
|
||||
// aMexp.TriangleOrientation (x,y,z);
|
||||
|
||||
gp_XYZ Vect12 ((x2-x1), (y2-y1), (z2-z1));
|
||||
gp_XYZ Vect23 ((x3-x2), (y3-y2), (z3-z2));
|
||||
gp_XYZ Vnorm = Vect12 ^ Vect23;
|
||||
Standard_Real Vmodul = Vnorm.Modulus ();
|
||||
if (Vmodul > gp::Resolution())
|
||||
{
|
||||
Vnorm.Divide (Vmodul);
|
||||
}
|
||||
else
|
||||
{
|
||||
// si Vnorm est quasi-nul, on le charge a 0 explicitement
|
||||
Vnorm.SetCoord (0., 0., 0.);
|
||||
}
|
||||
Sprintf (sval,
|
||||
" facet normal % 12e % 12e % 12e\n"
|
||||
" outer loop\n"
|
||||
" vertex % 12e % 12e % 12e\n"
|
||||
@@ -303,132 +287,270 @@ Standard_Boolean RWStl::writeASCII (const Handle(Poly_Triangulation)& theMesh,
|
||||
" vertex % 12e % 12e % 12e\n"
|
||||
" endloop\n"
|
||||
" endfacet\n",
|
||||
aVNorm.X(), aVNorm.Y(), aVNorm.Z(),
|
||||
aP1.X(), aP1.Y(), aP1.Z(),
|
||||
aP2.X(), aP2.Y(), aP2.Z(),
|
||||
aP3.X(), aP3.Y(), aP3.Z());
|
||||
Vnorm.X(), Vnorm.Y(), Vnorm.Z(),
|
||||
x1, y1, z1,
|
||||
x2, y2, z2,
|
||||
x3, y3, z3);
|
||||
buf += sval;
|
||||
theFile.Write (buf, buf.Length()); buf.Clear();
|
||||
|
||||
if (fprintf (theFile, "%s", aBuffer) < 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// update progress only per 1k triangles
|
||||
if ((aTriIter % IND_THRESHOLD) == 0)
|
||||
{
|
||||
aPS.Next();
|
||||
// update progress only per 1k triangles
|
||||
if (++aTriangleInd % IND_THRESHOLD == 0)
|
||||
{
|
||||
if (!aTPS.More())
|
||||
break;
|
||||
aTPS.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fwrite ("endsolid\n", 1, 9, theFile) != 9)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
buf += "endsolid\n";
|
||||
theFile.Write (buf, buf.Length()); buf.Clear();
|
||||
theFile.Close();
|
||||
Standard_Boolean isInterrupted = !aDPS.More();
|
||||
return !isInterrupted;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : ReadFile
|
||||
//Design :
|
||||
//Warning :
|
||||
//=======================================================================
|
||||
|
||||
//=============================================================================
|
||||
//function : writeBinary
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean RWStl::writeBinary (const Handle(Poly_Triangulation)& theMesh,
|
||||
FILE* theFile,
|
||||
Handle(StlMesh_Mesh) RWStl::ReadFile (const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd)
|
||||
{
|
||||
char aHeader[80] = "STL Exported by OpenCASCADE [www.opencascade.com]";
|
||||
if (fwrite (aHeader, 1, 80, theFile) != 80)
|
||||
OSD_File file (thePath);
|
||||
file.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
|
||||
Standard_Boolean IsAscii;
|
||||
unsigned char str[128];
|
||||
Standard_Integer lread,i;
|
||||
Standard_Address ach;
|
||||
ach = (Standard_Address)str;
|
||||
|
||||
// we skip the header which is in Ascii for both modes
|
||||
file.Read(ach,HEADER_SIZE,lread);
|
||||
|
||||
// we read 128 characters to detect if we have a non-ascii char
|
||||
file.Read(ach,sizeof(str),lread);
|
||||
|
||||
IsAscii = Standard_True;
|
||||
for (i = 0; i< lread && IsAscii; ++i) {
|
||||
if (str[i] > '~') {
|
||||
IsAscii = Standard_False;
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << (IsAscii ? "ascii\n" : "binary\n");
|
||||
#endif
|
||||
file.Close();
|
||||
|
||||
return IsAscii ? RWStl::ReadAscii (thePath, theProgInd)
|
||||
: RWStl::ReadBinary (thePath, theProgInd);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReadBinary
|
||||
//Design :
|
||||
//Warning :
|
||||
//=======================================================================
|
||||
|
||||
Handle(StlMesh_Mesh) RWStl::ReadBinary (const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& /*theProgInd*/)
|
||||
{
|
||||
Standard_Integer ifacet;
|
||||
Standard_Real fx,fy,fz,fx1,fy1,fz1,fx2,fy2,fz2,fx3,fy3,fz3;
|
||||
Standard_Integer i1,i2,i3,lread;
|
||||
char buftest[5];
|
||||
Standard_Address adr;
|
||||
adr = (Standard_Address)buftest;
|
||||
|
||||
// Open the file
|
||||
OSD_File theFile (thePath);
|
||||
theFile.Open(OSD_ReadOnly,OSD_Protection(OSD_RWD,OSD_RWD,OSD_RWD,OSD_RWD));
|
||||
|
||||
// the size of the file (minus the header size)
|
||||
// must be a multiple of SIZEOF_STL_FACET
|
||||
|
||||
// compute file size
|
||||
Standard_Size filesize = theFile.Size();
|
||||
|
||||
// don't trust the number of triangles which is coded in the file sometimes it is wrong
|
||||
Standard_Integer NBFACET = (Standard_Integer)((filesize - HEADER_SIZE) / SIZEOF_STL_FACET);
|
||||
if (NBFACET < 1)
|
||||
{
|
||||
return Standard_False;
|
||||
throw Standard_NoMoreObject("RWStl::ReadBinary (wrong file size)");
|
||||
}
|
||||
|
||||
Message_ProgressSentry aPS (theProgInd, "Triangles", 0,
|
||||
theMesh->NbTriangles(), IND_THRESHOLD);
|
||||
|
||||
const Standard_Size aNbChunkTriangles = 4096;
|
||||
const Standard_Size aChunkSize = aNbChunkTriangles * THE_STL_SIZEOF_FACET;
|
||||
NCollection_Array1<Standard_Character> aData (1, aChunkSize);
|
||||
Standard_Character* aDataChunk = &aData.ChangeFirst();
|
||||
|
||||
const TColgp_Array1OfPnt& aNodes = theMesh->Nodes();
|
||||
const Poly_Array1OfTriangle& aTriangles = theMesh->Triangles();
|
||||
const Standard_Integer aNBTriangles = theMesh->NbTriangles();
|
||||
|
||||
Standard_Character aConv[4];
|
||||
convertInteger (aNBTriangles, aConv);
|
||||
if (fwrite (aConv, 1, 4, theFile) != 4)
|
||||
theFile.Seek (80, OSD_FromBeginning);
|
||||
theFile.Read (adr, 4, lread);
|
||||
Standard_Integer aNbTrisInHeader = (((char* )buftest)[3] << 24) | (((Standard_Byte* )buftest)[2] << 16)
|
||||
| (((Standard_Byte* )buftest)[1] << 8 ) | (((Standard_Byte* )buftest)[0] << 0 );
|
||||
if (NBFACET < aNbTrisInHeader)
|
||||
{
|
||||
return Standard_False;
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file defines more triangles (") + aNbTrisInHeader
|
||||
+ ") that can be read (" + NBFACET + ") - probably corrupted file",
|
||||
Message_Warning);
|
||||
}
|
||||
else if (NBFACET > aNbTrisInHeader)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file defines less triangles (") + aNbTrisInHeader
|
||||
+ ") that can be read (" + NBFACET + ") - probably corrupted file",
|
||||
Message_Warning);
|
||||
}
|
||||
else if ((filesize - HEADER_SIZE) % SIZEOF_STL_FACET != 0)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("RWStl - Binary STL file has unidentified tail"),
|
||||
Message_Warning);
|
||||
}
|
||||
|
||||
Standard_Size aByteCount = 0;
|
||||
for (Standard_Integer aTriIter = 1; aTriIter <= aNBTriangles; ++aTriIter)
|
||||
// skip the header
|
||||
theFile.Seek(HEADER_SIZE,OSD_FromBeginning);
|
||||
|
||||
// create the StlMesh_Mesh object
|
||||
Handle(StlMesh_Mesh) ReadMesh = new StlMesh_Mesh ();
|
||||
ReadMesh->AddDomain ();
|
||||
|
||||
// Filter unique vertices to share the nodes of the mesh.
|
||||
BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion());
|
||||
BRepBuilderAPI_VertexInspector inspector(Precision::Confusion());
|
||||
|
||||
for (ifacet=1; ifacet<=NBFACET; ++ifacet) {
|
||||
// read normal coordinates
|
||||
fx = ReadFloat2Double(theFile);
|
||||
fy = ReadFloat2Double(theFile);
|
||||
fz = ReadFloat2Double(theFile);
|
||||
|
||||
// read vertex 1
|
||||
fx1 = ReadFloat2Double(theFile);
|
||||
fy1 = ReadFloat2Double(theFile);
|
||||
fz1 = ReadFloat2Double(theFile);
|
||||
|
||||
// read vertex 2
|
||||
fx2 = ReadFloat2Double(theFile);
|
||||
fy2 = ReadFloat2Double(theFile);
|
||||
fz2 = ReadFloat2Double(theFile);
|
||||
|
||||
// read vertex 3
|
||||
fx3 = ReadFloat2Double(theFile);
|
||||
fy3 = ReadFloat2Double(theFile);
|
||||
fz3 = ReadFloat2Double(theFile);
|
||||
|
||||
// Add vertices.
|
||||
i1 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx1, fy1, fz1));
|
||||
i2 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx2, fy2, fz2));
|
||||
i3 = AddVertex(ReadMesh, uniqueVertices, inspector, gp_XYZ(fx3, fy3, fz3));
|
||||
|
||||
// Add triangle.
|
||||
ReadMesh->AddTriangle (i1,i2,i3,fx,fy,fz);
|
||||
|
||||
// skip extra bytes
|
||||
theFile.Read(adr,2,lread);
|
||||
}
|
||||
|
||||
theFile.Close ();
|
||||
return ReadMesh;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReadAscii
|
||||
//Design :
|
||||
//Warning :
|
||||
//=======================================================================
|
||||
|
||||
Handle(StlMesh_Mesh) RWStl::ReadAscii (const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd)
|
||||
{
|
||||
TCollection_AsciiString filename;
|
||||
long ipos;
|
||||
Standard_Integer nbLines = 0;
|
||||
Standard_Integer nbTris = 0;
|
||||
Standard_Integer iTri;
|
||||
Standard_Integer i1,i2,i3;
|
||||
Handle(StlMesh_Mesh) ReadMesh;
|
||||
|
||||
thePath.SystemName (filename);
|
||||
|
||||
// Open the file
|
||||
FILE* file = OSD_OpenFile(filename.ToCString(),"r");
|
||||
|
||||
fseek(file,0L,SEEK_END);
|
||||
|
||||
long filesize = ftell(file);
|
||||
|
||||
rewind(file);
|
||||
|
||||
// count the number of lines
|
||||
for (ipos = 0; ipos < filesize; ++ipos) {
|
||||
if (getc(file) == '\n')
|
||||
nbLines++;
|
||||
}
|
||||
|
||||
// compute number of triangles
|
||||
nbTris = (nbLines / ASCII_LINES_PER_FACET);
|
||||
|
||||
// go back to the beginning of the file
|
||||
rewind(file);
|
||||
|
||||
// skip header
|
||||
while (getc(file) != '\n');
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "start mesh\n";
|
||||
#endif
|
||||
ReadMesh = new StlMesh_Mesh();
|
||||
ReadMesh->AddDomain();
|
||||
|
||||
// Filter unique vertices to share the nodes of the mesh.
|
||||
BRepBuilderAPI_CellFilter uniqueVertices(Precision::Confusion());
|
||||
BRepBuilderAPI_VertexInspector inspector(Precision::Confusion());
|
||||
|
||||
// main reading
|
||||
Message_ProgressSentry aPS (theProgInd, "Triangles", 0, (nbTris - 1) * 1.0 / IND_THRESHOLD, 1);
|
||||
for (iTri = 0; iTri < nbTris && aPS.More();)
|
||||
{
|
||||
Standard_Integer id[3];
|
||||
const Poly_Triangle& aTriangle = aTriangles (aTriIter);
|
||||
aTriangle.Get (id[0], id[1], id[2]);
|
||||
char x[256]="", y[256]="", z[256]="";
|
||||
|
||||
const gp_Pnt aP1 = aNodes (id[0]);
|
||||
const gp_Pnt aP2 = aNodes (id[1]);
|
||||
const gp_Pnt aP3 = aNodes (id[2]);
|
||||
// reading the facet normal
|
||||
if (3 != fscanf(file,"%*s %*s %80s %80s %80s\n", x, y, z))
|
||||
break; // error should be properly reported
|
||||
gp_XYZ aN (Atof(x), Atof(y), Atof(z));
|
||||
|
||||
gp_Vec aVec1 (aP1, aP2);
|
||||
gp_Vec aVec2 (aP1, aP3);
|
||||
gp_Vec aVNorm = aVec1.Crossed(aVec2);
|
||||
if (aVNorm.SquareMagnitude() > gp::Resolution())
|
||||
{
|
||||
aVNorm.Normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
aVNorm.SetCoord (0.0, 0.0, 0.0);
|
||||
}
|
||||
// skip the keywords "outer loop"
|
||||
if (fscanf(file,"%*s %*s") < 0)
|
||||
break;
|
||||
|
||||
convertDouble (aVNorm.X(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aVNorm.Y(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aVNorm.Z(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
// reading vertex
|
||||
if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z))
|
||||
break; // error should be properly reported
|
||||
gp_XYZ aV1 (Atof(x), Atof(y), Atof(z));
|
||||
if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z))
|
||||
break; // error should be properly reported
|
||||
gp_XYZ aV2 (Atof(x), Atof(y), Atof(z));
|
||||
if (3 != fscanf(file,"%*s %80s %80s %80s\n", x, y, z))
|
||||
break; // error should be properly reported
|
||||
gp_XYZ aV3 (Atof(x), Atof(y), Atof(z));
|
||||
|
||||
convertDouble (aP1.X(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP1.Y(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP1.Z(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
// here the facet must be built and put in the mesh datastructure
|
||||
|
||||
convertDouble (aP2.X(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP2.Y(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP2.Z(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
i1 = AddVertex(ReadMesh, uniqueVertices, inspector, aV1);
|
||||
i2 = AddVertex(ReadMesh, uniqueVertices, inspector, aV2);
|
||||
i3 = AddVertex(ReadMesh, uniqueVertices, inspector, aV3);
|
||||
ReadMesh->AddTriangle (i1, i2, i3, aN.X(), aN.Y(), aN.Z());
|
||||
|
||||
convertDouble (aP3.X(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP3.Y(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
convertDouble (aP3.Z(), &aDataChunk[aByteCount]); aByteCount += 4;
|
||||
// skip the keywords "endloop"
|
||||
if (fscanf(file,"%*s") < 0)
|
||||
break;
|
||||
|
||||
aDataChunk[aByteCount] = 0; aByteCount += 1;
|
||||
aDataChunk[aByteCount] = 0; aByteCount += 1;
|
||||
|
||||
// Chunk is filled. Dump it to the file.
|
||||
if (aByteCount == aChunkSize)
|
||||
{
|
||||
if (fwrite (aDataChunk, 1, aChunkSize, theFile) != aChunkSize)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
aByteCount = 0;
|
||||
}
|
||||
// skip the keywords "endfacet"
|
||||
if (fscanf(file,"%*s") < 0)
|
||||
break;
|
||||
|
||||
// update progress only per 1k triangles
|
||||
if ((aTriIter % IND_THRESHOLD) == 0)
|
||||
{
|
||||
if (++iTri % IND_THRESHOLD == 0)
|
||||
aPS.Next();
|
||||
}
|
||||
}
|
||||
|
||||
// Write last part if necessary.
|
||||
if (aByteCount != aChunkSize)
|
||||
{
|
||||
if (fwrite (aDataChunk, 1, aByteCount, theFile) != aByteCount)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "end mesh\n";
|
||||
#endif
|
||||
fclose(file);
|
||||
return ReadMesh;
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// Created on: 2017-06-13
|
||||
// Created by: Alexander MALYSHEV
|
||||
// Copyright (c) 2017 OPEN CASCADE SAS
|
||||
// Created on: 1994-10-13
|
||||
// Created by: Marc LEGAY
|
||||
// Copyright (c) 1994-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
@@ -16,61 +17,85 @@
|
||||
#ifndef _RWStl_HeaderFile
|
||||
#define _RWStl_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Message_ProgressIndicator.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
//! This class provides methods to read and write triangulation from / to the STL files.
|
||||
class RWStl
|
||||
class StlMesh_Mesh;
|
||||
class OSD_Path;
|
||||
|
||||
//! This package contains the methods to be used in
|
||||
//! the Stereo Lithograpy Application. The main
|
||||
//! features of this application are ,starting from a
|
||||
//! Shape :
|
||||
//! - mesh this shape with a maximun tolerance,
|
||||
//! - display the meshing,
|
||||
//! - write the meshing in a file (binary or ascii),
|
||||
//! - read of file (binary or ascii) and display it,
|
||||
//! - translate a binary file to an ascii file,
|
||||
//! - translate an ascii file to an binary file.
|
||||
class RWStl
|
||||
{
|
||||
public:
|
||||
|
||||
//! Write triangulation to binary STL file.
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! write the meshing in a file following the
|
||||
//! binary format of an STL file.
|
||||
//! Returns false if the cannot be opened;
|
||||
Standard_EXPORT static Standard_Boolean WriteBinary (const Handle(Poly_Triangulation)& theMesh,
|
||||
const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)());
|
||||
Standard_EXPORT static Standard_Boolean WriteBinary (const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL);
|
||||
|
||||
//! write the meshing in a file following the
|
||||
//! Ascii format of an STL file.
|
||||
//! Returns false if the cannot be opened;
|
||||
Standard_EXPORT static Standard_Boolean WriteAscii (const Handle(Poly_Triangulation)& theMesh,
|
||||
const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)());
|
||||
Standard_EXPORT static Standard_Boolean WriteAscii (const Handle(StlMesh_Mesh)& aMesh, const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL);
|
||||
|
||||
//! Read specified STL file and returns its content as triangulation.
|
||||
//! In case of error, returns Null handle.
|
||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const OSD_Path& theFile,
|
||||
const Handle(Message_ProgressIndicator)& aProgInd = Handle(Message_ProgressIndicator)());
|
||||
|
||||
//! Read specified STL file and returns its content as triangulation.
|
||||
//! In case of error, returns Null handle.
|
||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadFile (const Standard_CString theFile,
|
||||
const Handle(Message_ProgressIndicator)& aProgInd = Handle(Message_ProgressIndicator)());
|
||||
|
||||
//! 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,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)());
|
||||
//! This method will chwck if the file is a binary
|
||||
//! file or an AsciiFile testing the 5 first
|
||||
//! characters of the file wich are :"solid" in an
|
||||
//! ascii file. If we do not find that word we assume
|
||||
//! that it is a binary file.
|
||||
Standard_EXPORT static Handle(StlMesh_Mesh) ReadFile (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL);
|
||||
|
||||
//! Read triangulation from an Ascii STL file
|
||||
//! In case of error, returns Null handle.
|
||||
Standard_EXPORT static Handle(Poly_Triangulation) ReadAscii (const OSD_Path& thePath,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd = Handle(Message_ProgressIndicator)());
|
||||
//! Read a meshing from a binary file
|
||||
//! Raises NoMoreObject from Standard if a statement
|
||||
//! does not contain the right number of tokens
|
||||
//! Raises TypeMisMatch if a token has not the good
|
||||
//! type (often real)
|
||||
Standard_EXPORT static Handle(StlMesh_Mesh) ReadBinary (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL);
|
||||
|
||||
//! Read a meshing from a binary file
|
||||
//! Raises NoMoreObject from Standard if a statement
|
||||
//! does not contain the right number of tokens
|
||||
//! Raises TypeMisMatch if a token has not the good
|
||||
//! type (often real)
|
||||
//! Raises MoMoreObject if a file is finished before
|
||||
//! having found the word endsolid;
|
||||
Standard_EXPORT static Handle(StlMesh_Mesh) ReadAscii (const OSD_Path& aPath, const Handle(Message_ProgressIndicator)& aProgInd = NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//! Write ASCII version.
|
||||
static Standard_Boolean writeASCII (const Handle(Poly_Triangulation)& theMesh,
|
||||
FILE *theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd);
|
||||
|
||||
//! Write binary version.
|
||||
static Standard_Boolean writeBinary (const Handle(Poly_Triangulation)& theMesh,
|
||||
FILE *theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgInd);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _RWStl_HeaderFile
|
||||
|
@@ -1,420 +0,0 @@
|
||||
// Created: 2016-05-01
|
||||
// Author: Andrey Betenev
|
||||
// Copyright: Open CASCADE 2016
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <RWStl_Reader.hxx>
|
||||
|
||||
#include <gp_XY.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <FSD_BinaryFile.hxx>
|
||||
#include <OSD_OpenFile.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_CLocaleSentry.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(RWStl_Reader, Standard_Transient)
|
||||
|
||||
namespace
|
||||
{
|
||||
// Binary STL sizes
|
||||
static const size_t THE_STL_HEADER_SIZE = 84;
|
||||
static const size_t THE_STL_SIZEOF_FACET = 50;
|
||||
static const size_t THE_STL_MIN_FILE_SIZE = THE_STL_HEADER_SIZE + THE_STL_SIZEOF_FACET;
|
||||
|
||||
//! Auxiliary tool for merging nodes during STL reading.
|
||||
class MergeNodeTool
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
MergeNodeTool (RWStl_Reader* theReader)
|
||||
: myReader (theReader),
|
||||
myMap (1024, new NCollection_IncAllocator (1024 * 1024))
|
||||
{
|
||||
}
|
||||
|
||||
//! Add new triangle
|
||||
int AddNode (double theX, double theY, double theZ)
|
||||
{
|
||||
// use existing node if found at the same point
|
||||
gp_XYZ aPnt (theX, theY, theZ);
|
||||
|
||||
Standard_Integer anIndex = -1;
|
||||
if (myMap.Find (aPnt, anIndex))
|
||||
{
|
||||
return anIndex;
|
||||
}
|
||||
|
||||
anIndex = myReader->AddNode (aPnt);
|
||||
myMap.Bind (aPnt, anIndex);
|
||||
return anIndex;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Standard_Boolean IsEqual (const gp_XYZ& thePnt1, const gp_XYZ& thePnt2)
|
||||
{
|
||||
return (thePnt1 - thePnt2).SquareModulus() < Precision::SquareConfusion();
|
||||
}
|
||||
|
||||
static Standard_Integer HashCode (const gp_XYZ& thePnt, Standard_Integer theUpper)
|
||||
{
|
||||
return ::HashCode (thePnt.X() * M_LN10 + thePnt.Y() * M_PI + thePnt.Z() * M_E, theUpper);
|
||||
}
|
||||
|
||||
private:
|
||||
RWStl_Reader* myReader;
|
||||
NCollection_DataMap<gp_XYZ, Standard_Integer, MergeNodeTool> myMap;
|
||||
};
|
||||
|
||||
//! Read a Little Endian 32 bits float
|
||||
inline static float readStlFloat (const char* theData)
|
||||
{
|
||||
#if OCCT_BINARY_FILE_DO_INVERSE
|
||||
// on big-endian platform, map values byte-per-byte
|
||||
union
|
||||
{
|
||||
uint32_t i;
|
||||
float f;
|
||||
} bidargum;
|
||||
bidargum.i = theData[0] & 0xFF;
|
||||
bidargum.i |= (theData[1] & 0xFF) << 0x08;
|
||||
bidargum.i |= (theData[2] & 0xFF) << 0x10;
|
||||
bidargum.i |= (theData[3] & 0xFF) << 0x18;
|
||||
return bidargum.f;
|
||||
#else
|
||||
// on little-endian platform, use plain cast
|
||||
return *reinterpret_cast<const float*>(theData);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Read a Little Endian 32 bits float
|
||||
inline static gp_XYZ readStlFloatVec3 (const char* theData)
|
||||
{
|
||||
return gp_XYZ (readStlFloat (theData),
|
||||
readStlFloat (theData + sizeof(float)),
|
||||
readStlFloat (theData + sizeof(float) * 2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : Read
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
|
||||
Standard_Boolean RWStl_Reader::Read (const char* theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
std::filebuf aBuf;
|
||||
OSD_OpenStream (aBuf, theFile, std::ios::in | std::ios::binary);
|
||||
if (!aBuf.is_open())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_IStream aStream (&aBuf);
|
||||
|
||||
// get length of file to feed progress indicator in Ascii mode
|
||||
aStream.seekg (0, aStream.end);
|
||||
std::streampos theEnd = aStream.tellg();
|
||||
aStream.seekg (0, aStream.beg);
|
||||
|
||||
while (!aStream.eof() && !aStream.bad())
|
||||
{
|
||||
if (IsAscii (aStream))
|
||||
{
|
||||
if (!ReadAscii (aStream, theEnd, theProgress))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadBinary (aStream, theProgress))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
aStream >> std::ws; // skip any white spaces
|
||||
}
|
||||
return !aStream.bad();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : IsAscii
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
|
||||
Standard_Boolean RWStl_Reader::IsAscii (Standard_IStream& theStream)
|
||||
{
|
||||
// read first 134 bytes to detect file format
|
||||
char aBuffer[THE_STL_MIN_FILE_SIZE];
|
||||
std::streamsize aNbRead = theStream.read (aBuffer, THE_STL_MIN_FILE_SIZE).gcount();
|
||||
if (!theStream)
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: Cannot read file", Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
// put back the read symbols
|
||||
for (std::streamsize aByteIter = aNbRead; aByteIter > 0; --aByteIter)
|
||||
{
|
||||
theStream.unget();
|
||||
}
|
||||
|
||||
// if file is shorter than size of binary file with 1 facet, it must be ascii
|
||||
if (aNbRead < std::streamsize(THE_STL_MIN_FILE_SIZE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise, detect binary format by presence of non-ascii symbols in first 128 bytes
|
||||
// (note that binary STL file may start with the same bytes "solid " as Ascii one)
|
||||
for (Standard_Integer aByteIter = 0; aByteIter < aNbRead; ++aByteIter)
|
||||
{
|
||||
if ((unsigned char )aBuffer[aByteIter] > (unsigned char )'~')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// adapted from Standard_CString.cxx
|
||||
#ifdef __APPLE__
|
||||
// There are a lot of *_l functions availalbe on Mac OS X - we use them
|
||||
#define SAVE_TL()
|
||||
#elif defined(_MSC_VER)
|
||||
// MSVCRT has equivalents with slightly different syntax
|
||||
#define SAVE_TL()
|
||||
#define sscanf_l(theBuffer, theLocale, theFormat, ...) _sscanf_s_l(theBuffer, theFormat, theLocale, __VA_ARGS__)
|
||||
#else
|
||||
// glibc provides only limited xlocale implementation:
|
||||
// strtod_l/strtol_l/strtoll_l functions with explicitly specified locale
|
||||
// and newlocale/uselocale/freelocale to switch locale within current thread only.
|
||||
// So we switch to C locale temporarily
|
||||
#define SAVE_TL() Standard_CLocaleSentry aLocaleSentry;
|
||||
#define sscanf_l(theBuffer, theLocale, theFormat, ...) sscanf(theBuffer, theFormat, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Macro to get 64-bit position of the file from streampos
|
||||
#if defined(_MSC_VER)
|
||||
#define GETPOS(aPos) aPos.seekpos()
|
||||
#else
|
||||
#define GETPOS(aPos) ((int64_t)aPos)
|
||||
#endif
|
||||
|
||||
static inline bool str_starts_with (const char* theStr, const char* theWord, int theN)
|
||||
{
|
||||
while (isspace (*theStr) && *theStr != '\0') theStr++;
|
||||
return !strncmp (theStr, theWord, theN);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : ReadAscii
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream,
|
||||
const std::streampos theUntilPos,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
// use method seekpos() to get true 64-bit offset to enable
|
||||
// handling of large files (VS 2010 64-bit)
|
||||
const int64_t aStartPos = GETPOS(theStream.tellg());
|
||||
const int64_t aEndPos = (theUntilPos > 0 ? GETPOS(theUntilPos) : std::numeric_limits<int64_t>::max());
|
||||
|
||||
// skip header "solid ..."
|
||||
theStream.ignore (aEndPos - aStartPos, '\n');
|
||||
if (!theStream)
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: premature end of file", Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
MergeNodeTool aMergeTool (this);
|
||||
Standard_CLocaleSentry::clocale_t aLocale = Standard_CLocaleSentry::GetCLocale();
|
||||
(void)aLocale; // to avoid warning on GCC where it is actually not used
|
||||
SAVE_TL() // for GCC only, set C locale globally
|
||||
|
||||
// report progress every 1 MiB of read data
|
||||
const int aStepB = 1024 * 1024;
|
||||
const Standard_Integer aNbSteps = 1 + Standard_Integer((theUntilPos - aStartPos) / aStepB);
|
||||
Message_ProgressSentry aPSentry (theProgress, "Reading text STL file", 0, aNbSteps, 1);
|
||||
|
||||
int64_t aProgressPos = aStartPos + aStepB;
|
||||
const int64_t LINELEN = 1024;
|
||||
int aNbLine = 1;
|
||||
char aLine1[LINELEN], aLine2[LINELEN], aLine3[LINELEN];
|
||||
while (aPSentry.More())
|
||||
{
|
||||
if (GETPOS(theStream.tellg()) > aProgressPos)
|
||||
{
|
||||
aPSentry.Next();
|
||||
aProgressPos += aStepB;
|
||||
}
|
||||
|
||||
char facet[LINELEN], outer[LINELEN];
|
||||
theStream.getline (facet, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); // "facet normal nx ny nz"
|
||||
if (str_starts_with (facet, "endsolid", 8))
|
||||
{
|
||||
// end of STL code
|
||||
break;
|
||||
}
|
||||
theStream.getline (outer, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg()))); // "outer loop"
|
||||
if (!str_starts_with (facet, "facet", 5) || !str_starts_with (outer, "outer", 5))
|
||||
{
|
||||
TCollection_AsciiString aStr ("Error: unexpected format of facet at line ");
|
||||
aStr += aNbLine + 1;
|
||||
Message::DefaultMessenger()->Send (aStr, Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
theStream.getline (aLine1, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg())));
|
||||
theStream.getline (aLine2, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg())));
|
||||
theStream.getline (aLine3, std::min (LINELEN, aEndPos - GETPOS(theStream.tellg())));
|
||||
|
||||
// stop reading if end of file is reached;
|
||||
// note that well-formatted file never ends by the vertex line
|
||||
if (theStream.eof() || GETPOS(theStream.tellg()) >= aEndPos)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!theStream)
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: premature end of file", Message_Fail);
|
||||
return false;
|
||||
}
|
||||
aNbLine += 5;
|
||||
|
||||
Standard_Real x1, y1, z1, x2, y2, z2, x3, y3, z3;
|
||||
Standard_Integer aReadCount = // read 3 lines "vertex x y z"
|
||||
sscanf_l (aLine1, aLocale, "%*s %lf %lf %lf", &x1, &y1, &z1) +
|
||||
sscanf_l (aLine2, aLocale, "%*s %lf %lf %lf", &x2, &y2, &z2) +
|
||||
sscanf_l (aLine3, aLocale, "%*s %lf %lf %lf", &x3, &y3, &z3);
|
||||
if (aReadCount != 9)
|
||||
{
|
||||
TCollection_AsciiString aStr ("Error: cannot read vertex co-ordinates at line ");
|
||||
aStr += aNbLine;
|
||||
Message::DefaultMessenger()->Send(aStr, Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
// add triangle
|
||||
int n1 = aMergeTool.AddNode (x1, y1, z1);
|
||||
int n2 = aMergeTool.AddNode (x2, y2, z2);
|
||||
int n3 = aMergeTool.AddNode (x3, y3, z3);
|
||||
if (n1 != n2 && n2 != n3 && n3 != n1)
|
||||
{
|
||||
AddTriangle (n1, n2, n3);
|
||||
}
|
||||
|
||||
theStream.ignore (aEndPos - GETPOS(theStream.tellg()), '\n'); // skip "endloop"
|
||||
theStream.ignore (aEndPos - GETPOS(theStream.tellg()), '\n'); // skip "endfacet"
|
||||
|
||||
aNbLine += 2;
|
||||
}
|
||||
|
||||
return aPSentry.More();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
//function : readStlBinary
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
|
||||
Standard_Boolean RWStl_Reader::ReadBinary (Standard_IStream& theStream,
|
||||
const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
/*
|
||||
// the size of the file (minus the header size)
|
||||
// must be a multiple of SIZEOF_STL_FACET
|
||||
if ((theFileLen - THE_STL_HEADER_SIZE) % THE_STL_SIZEOF_FACET != 0
|
||||
|| (theFileLen < THE_STL_MIN_FILE_SIZE))
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: Corrupted binary STL file (inconsistent file size)!", Message_Fail);
|
||||
return Standard_False;
|
||||
}
|
||||
const Standard_Integer aNbFacets = Standard_Integer((theFileLen - THE_STL_HEADER_SIZE) / THE_STL_SIZEOF_FACET);
|
||||
*/
|
||||
|
||||
// read file header at first
|
||||
char aHeader[THE_STL_HEADER_SIZE + 1];
|
||||
if (theStream.read (aHeader, THE_STL_HEADER_SIZE).gcount() != std::streamsize(THE_STL_HEADER_SIZE))
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: Corrupted binary STL file!", Message_Fail);
|
||||
return false;
|
||||
}
|
||||
|
||||
// number of facets is stored as 32-bit integer at position 80
|
||||
const Standard_Integer aNbFacets = *(int32_t*)(aHeader + 80);
|
||||
|
||||
MergeNodeTool aMergeTool (this);
|
||||
|
||||
// don't trust the number of triangles which is coded in the file
|
||||
// sometimes it is wrong, and with this technique we don't need to swap endians for integer
|
||||
Message_ProgressSentry aPSentry (theProgress, "Reading binary STL file", 0, aNbFacets, 1);
|
||||
Standard_Integer aNbRead = 0;
|
||||
|
||||
// allocate buffer for 80 triangles
|
||||
const int THE_CHUNK_NBFACETS = 80;
|
||||
char aBuffer[THE_STL_SIZEOF_FACET * THE_CHUNK_NBFACETS];
|
||||
|
||||
// normal + 3 nodes + 2 extra bytes
|
||||
const size_t aVec3Size = sizeof(float) * 3;
|
||||
const size_t aFaceDataLen = aVec3Size * 4 + 2;
|
||||
const char* aBufferPtr = aBuffer;
|
||||
Standard_Integer aNbFacesInBuffer = 0;
|
||||
for (Standard_Integer aNbFacetRead = 0; aNbFacetRead < aNbFacets && aPSentry.More();
|
||||
++aNbFacetRead, ++aNbRead, --aNbFacesInBuffer, aBufferPtr += aFaceDataLen, aPSentry.Next())
|
||||
{
|
||||
// read more data
|
||||
if (aNbFacesInBuffer <= 0)
|
||||
{
|
||||
aNbFacesInBuffer = Min (THE_CHUNK_NBFACETS, aNbFacets - aNbFacetRead);
|
||||
const std::streamsize aDataToRead = aNbFacesInBuffer * aFaceDataLen;
|
||||
if (theStream.read (aBuffer, aDataToRead).gcount() != aDataToRead)
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Error: read filed", Message_Fail);
|
||||
return false;
|
||||
}
|
||||
aBufferPtr = aBuffer;
|
||||
}
|
||||
|
||||
// get points from buffer
|
||||
// readStlFloatVec3 (aBufferPtr); // skip normal
|
||||
gp_XYZ aP1 = readStlFloatVec3 (aBufferPtr + aVec3Size);
|
||||
gp_XYZ aP2 = readStlFloatVec3 (aBufferPtr + aVec3Size * 2);
|
||||
gp_XYZ aP3 = readStlFloatVec3 (aBufferPtr + aVec3Size * 3);
|
||||
|
||||
// add triangle
|
||||
int n1 = aMergeTool.AddNode (aP1.X(), aP1.Y(), aP1.Z());
|
||||
int n2 = aMergeTool.AddNode (aP2.X(), aP2.Y(), aP2.Z());
|
||||
int n3 = aMergeTool.AddNode (aP3.X(), aP3.Y(), aP3.Z());
|
||||
if (n1 != n2 && n2 != n3 && n3 != n1)
|
||||
{
|
||||
AddTriangle (n1, n2, n3);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
// Created: 2016-05-01
|
||||
// Author: Andrey Betenev
|
||||
// Copyright: Open CASCADE 2016
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _RWStl_Reader_HeaderFile
|
||||
#define _RWStl_Reader_HeaderFile
|
||||
|
||||
#include <Message_ProgressIndicator.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
|
||||
//! An abstract class implementing procedure to read STL file.
|
||||
//!
|
||||
//! This class is not bound to particular data structure and can be used to read the file directly into arbitrary data model.
|
||||
//! To use it, create descendant class and implement methods addNode() and addTriangle().
|
||||
//!
|
||||
//! Call method Read() to read the file. In the process of reading, the tool will call methods addNode() and addTriangle() to fill the mesh data structure.
|
||||
//!
|
||||
//! The nodes with equal coordinates are merged automatically on the fly.
|
||||
class RWStl_Reader : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(RWStl_Reader, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Reads data from STL file (either binary or Ascii).
|
||||
//! 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.
|
||||
//! Returns true if success, false on error or user break.
|
||||
Standard_EXPORT Standard_Boolean Read (const char* theFile,
|
||||
const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
//! Guess whether the stream is an Ascii STL file, by analysis of the first bytes (~200).
|
||||
//! The function attempts to put back the read symbols to the stream which thus must support ungetc().
|
||||
//! Returns true if the stream seems to contain Ascii STL.
|
||||
Standard_EXPORT Standard_Boolean IsAscii (Standard_IStream& theStream);
|
||||
|
||||
//! Reads STL data from binary stream.
|
||||
//! The stream must be opened in binary mode.
|
||||
//! Stops after reading the number of triangles recorded in the file header.
|
||||
//! Returns true if success, false on error or user break.
|
||||
Standard_EXPORT Standard_Boolean ReadBinary (Standard_IStream& theStream,
|
||||
const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
//! Reads data from the stream assumed to contain Ascii STL data.
|
||||
//! The stream can be opened either in binary or in Ascii mode.
|
||||
//! Reading stops at the position specified by theUntilPos,
|
||||
//! or end of file is reached, or when keyword "endsolid" is found.
|
||||
//! Empty lines are not supported and will read to reading failure.
|
||||
//! If theUntilPos is non-zero, reads not more than until that position.
|
||||
//! Returns true if success, false on error or user break.
|
||||
Standard_EXPORT Standard_Boolean ReadAscii (Standard_IStream& theStream,
|
||||
const std::streampos theUntilPos,
|
||||
const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
public:
|
||||
|
||||
//! Callback function to be implemented in descendant.
|
||||
//! Should create new node with specified coordinates in the target model, and return its ID as integer.
|
||||
virtual Standard_Integer AddNode (const gp_XYZ& thePnt) = 0;
|
||||
|
||||
//! Callback function to be implemented in descendant.
|
||||
//! 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;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@@ -34,20 +34,20 @@
|
||||
|
||||
// Primary definitions
|
||||
#define OCC_VERSION_MAJOR 7
|
||||
#define OCC_VERSION_MINOR 2
|
||||
#define OCC_VERSION_MAINTENANCE 0
|
||||
#define OCC_VERSION_MINOR 1
|
||||
#define OCC_VERSION_MAINTENANCE 1
|
||||
|
||||
//! This macro must be commented in official release, and set to non-empty
|
||||
//! string in other situations, to identify specifics of the version, e.g.:
|
||||
//! - "dev" for official (certified) version (master branch) between releases
|
||||
//! - "beta..." or "rc..." for beta releases or release candidates
|
||||
//! - "project..." for version containing project-specific fixes
|
||||
#define OCC_VERSION_DEVELOPMENT "beta"
|
||||
#define OCC_VERSION_DEVELOPMENT "dev"
|
||||
|
||||
// Derived (manually): version as real and string (major.minor)
|
||||
#define OCC_VERSION 7.2
|
||||
#define OCC_VERSION_STRING "7.2"
|
||||
#define OCC_VERSION_COMPLETE "7.2.0"
|
||||
#define OCC_VERSION 7.1
|
||||
#define OCC_VERSION_STRING "7.1"
|
||||
#define OCC_VERSION_COMPLETE "7.1.1"
|
||||
|
||||
//! Derived: extended version as string ("major.minor.maintenance.dev")
|
||||
#ifdef OCC_VERSION_DEVELOPMENT
|
||||
|
@@ -1,5 +1,6 @@
|
||||
StlAPI.cxx
|
||||
StlAPI.hxx
|
||||
StlAPI_ErrorStatus.hxx
|
||||
StlAPI_Reader.cxx
|
||||
StlAPI_Reader.hxx
|
||||
StlAPI_Writer.cxx
|
||||
|
@@ -11,32 +11,24 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <StlAPI.hxx>
|
||||
|
||||
#include <StlAPI.hxx>
|
||||
#include <StlAPI_Reader.hxx>
|
||||
#include <StlAPI_Writer.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
//=============================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean StlAPI::Write (const TopoDS_Shape& theShape,
|
||||
const Standard_CString theFile,
|
||||
const Standard_Boolean theAsciiMode)
|
||||
StlAPI_ErrorStatus StlAPI::Write(const TopoDS_Shape& aShape,
|
||||
const Standard_CString aFile,
|
||||
const Standard_Boolean aAsciiMode)
|
||||
{
|
||||
StlAPI_Writer aWriter;
|
||||
aWriter.ASCIIMode() = theAsciiMode;
|
||||
return aWriter.Write (theShape, theFile);
|
||||
StlAPI_Writer writer;
|
||||
writer.ASCIIMode() = aAsciiMode;
|
||||
return writer.Write (aShape, aFile);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Read
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean StlAPI::Read (TopoDS_Shape& theShape,
|
||||
const Standard_CString theFile)
|
||||
|
||||
void StlAPI::Read(TopoDS_Shape& aShape,const Standard_CString aFile)
|
||||
{
|
||||
StlAPI_Reader aReader;
|
||||
return aReader.Read(theShape, theFile);
|
||||
StlAPI_Reader reader;
|
||||
reader.Read (aShape, aFile);
|
||||
}
|
||||
|
@@ -17,37 +17,57 @@
|
||||
#ifndef _StlAPI_HeaderFile
|
||||
#define _StlAPI_HeaderFile
|
||||
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <StlAPI_ErrorStatus.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
class TopoDS_Shape;
|
||||
class StlAPI_Writer;
|
||||
class StlAPI_Reader;
|
||||
|
||||
|
||||
//! Offers the API for STL data manipulation.
|
||||
class StlAPI
|
||||
class StlAPI
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! Convert and write shape to STL format.
|
||||
//! File is written in binary if aAsciiMode is False otherwise it is written in Ascii (by default).
|
||||
Standard_EXPORT static Standard_Boolean Write (const TopoDS_Shape& theShape,
|
||||
const Standard_CString theFile,
|
||||
const Standard_Boolean theAsciiMode = Standard_True);
|
||||
//! file is written in binary if aAsciiMode is False
|
||||
//! otherwise it is written in Ascii (by default)
|
||||
Standard_EXPORT static StlAPI_ErrorStatus Write (const TopoDS_Shape& aShape, const Standard_CString aFile, const Standard_Boolean aAsciiMode = Standard_True);
|
||||
|
||||
//! Create a shape from a STL format.
|
||||
Standard_EXPORT static void Read (TopoDS_Shape& aShape, const Standard_CString aFile);
|
||||
|
||||
//! Legacy interface.
|
||||
//! Read STL file and create a shape composed of triangular faces, one per facet.
|
||||
//! This approach is very inefficient, especially for large files.
|
||||
//! Consider reading STL file to Poly_Triangulation object instead (see class RWStl).
|
||||
Standard_DEPRECATED("This method is very inefficient; see RWStl class for better alternative")
|
||||
Standard_EXPORT static Standard_Boolean Read (TopoDS_Shape& theShape,
|
||||
const Standard_CString aFile);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
friend class StlAPI_Writer;
|
||||
friend class StlAPI_Reader;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlAPI_HeaderFile
|
||||
|
30
src/StlAPI/StlAPI_ErrorStatus.hxx
Normal file
30
src/StlAPI/StlAPI_ErrorStatus.hxx
Normal file
@@ -0,0 +1,30 @@
|
||||
// Created on: 1997-05-13
|
||||
// Created by: Fabien REUTER
|
||||
// Copyright (c) 1997-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlAPI_ErrorStatus_HeaderFile
|
||||
#define _StlAPI_ErrorStatus_HeaderFile
|
||||
|
||||
//! Set of statuses to indicate a type of the error
|
||||
//! occurred during data retrieving and writing operations.
|
||||
enum StlAPI_ErrorStatus
|
||||
{
|
||||
StlAPI_StatusOK,
|
||||
StlAPI_MeshIsEmpty,
|
||||
StlAPI_CannotOpenFile,
|
||||
StlAPI_WriteError
|
||||
};
|
||||
|
||||
#endif // _StlAPI_ErrorStatus_HeaderFile
|
@@ -11,7 +11,6 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <StlAPI_Reader.hxx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
@@ -21,6 +20,9 @@
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <RWStl.hxx>
|
||||
#include <StlAPI_Reader.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshExplorer.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
@@ -29,68 +31,64 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
//=============================================================================
|
||||
//function : Read
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean StlAPI_Reader::Read (TopoDS_Shape& theShape,
|
||||
const Standard_CString theFileName)
|
||||
StlAPI_Reader::StlAPI_Reader() {}
|
||||
|
||||
void StlAPI_Reader::Read(TopoDS_Shape& aShape, const Standard_CString aFileName)
|
||||
{
|
||||
Handle(Poly_Triangulation) aMesh = RWStl::ReadFile (theFileName);
|
||||
if (aMesh.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
TopoDS_Vertex aTriVertexes[3];
|
||||
TopoDS_Face aFace;
|
||||
TopoDS_Wire aWire;
|
||||
OSD_Path aFile(aFileName);
|
||||
|
||||
Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile(aFile);
|
||||
Standard_Integer NumberDomains = aSTLMesh->NbDomains();
|
||||
Standard_Integer iND;
|
||||
gp_XYZ p1, p2, p3;
|
||||
TopoDS_Vertex Vertex1, Vertex2, Vertex3;
|
||||
TopoDS_Face AktFace;
|
||||
TopoDS_Wire AktWire;
|
||||
BRepBuilderAPI_Sewing aSewingTool;
|
||||
aSewingTool.Init (1.0e-06, Standard_True);
|
||||
|
||||
Standard_Real x1, y1, z1;
|
||||
Standard_Real x2, y2, z2;
|
||||
Standard_Real x3, y3, z3;
|
||||
|
||||
aSewingTool.Init(1.0e-06,Standard_True);
|
||||
|
||||
TopoDS_Compound aComp;
|
||||
BRep_Builder BuildTool;
|
||||
BuildTool.MakeCompound (aComp);
|
||||
BuildTool.MakeCompound( aComp );
|
||||
|
||||
const TColgp_Array1OfPnt& aNodes = aMesh->Nodes();
|
||||
const Poly_Array1OfTriangle& aTriangles = aMesh->Triangles();
|
||||
for (Standard_Integer aTriIdx = aTriangles.Lower();
|
||||
aTriIdx <= aTriangles.Upper();
|
||||
++aTriIdx)
|
||||
StlMesh_MeshExplorer aMExp (aSTLMesh);
|
||||
|
||||
for (iND=1;iND<=NumberDomains;iND++)
|
||||
{
|
||||
const Poly_Triangle& aTriangle = aTriangles(aTriIdx);
|
||||
|
||||
Standard_Integer anId[3];
|
||||
aTriangle.Get(anId[0], anId[1], anId[2]);
|
||||
|
||||
const gp_Pnt& aPnt1 = aNodes (anId[0]);
|
||||
const gp_Pnt& aPnt2 = aNodes (anId[1]);
|
||||
const gp_Pnt& aPnt3 = aNodes (anId[2]);
|
||||
if ((!(aPnt1.IsEqual (aPnt2, 0.0)))
|
||||
&& (!(aPnt1.IsEqual (aPnt3, 0.0))))
|
||||
for (aMExp.InitTriangle (iND); aMExp.MoreTriangle (); aMExp.NextTriangle ())
|
||||
{
|
||||
aTriVertexes[0] = BRepBuilderAPI_MakeVertex (aPnt1);
|
||||
aTriVertexes[1] = BRepBuilderAPI_MakeVertex (aPnt2);
|
||||
aTriVertexes[2] = BRepBuilderAPI_MakeVertex (aPnt3);
|
||||
|
||||
aWire = BRepBuilderAPI_MakePolygon (aTriVertexes[0], aTriVertexes[1], aTriVertexes[2], Standard_True);
|
||||
if (!aWire.IsNull())
|
||||
aMExp.TriangleVertices (x1,y1,z1,x2,y2,z2,x3,y3,z3);
|
||||
p1.SetCoord(x1,y1,z1);
|
||||
p2.SetCoord(x2,y2,z2);
|
||||
p3.SetCoord(x3,y3,z3);
|
||||
|
||||
if ((!(p1.IsEqual(p2,0.0))) && (!(p1.IsEqual(p3,0.0))))
|
||||
{
|
||||
aFace = BRepBuilderAPI_MakeFace (aWire);
|
||||
if (!aFace.IsNull())
|
||||
Vertex1 = BRepBuilderAPI_MakeVertex(p1);
|
||||
Vertex2 = BRepBuilderAPI_MakeVertex(p2);
|
||||
Vertex3 = BRepBuilderAPI_MakeVertex(p3);
|
||||
|
||||
AktWire = BRepBuilderAPI_MakePolygon( Vertex1, Vertex2, Vertex3, Standard_True);
|
||||
|
||||
if( !AktWire.IsNull())
|
||||
{
|
||||
BuildTool.Add (aComp, aFace);
|
||||
AktFace = BRepBuilderAPI_MakeFace( AktWire);
|
||||
if(!AktFace.IsNull())
|
||||
BuildTool.Add( aComp, AktFace );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aSTLMesh->Clear();
|
||||
|
||||
aSewingTool.Load (aComp);
|
||||
aSewingTool.Load( aComp );
|
||||
aSewingTool.Perform();
|
||||
theShape = aSewingTool.SewedShape();
|
||||
if (theShape.IsNull())
|
||||
{
|
||||
theShape = aComp;
|
||||
}
|
||||
return Standard_True;
|
||||
aShape = aSewingTool.SewedShape();
|
||||
if ( aShape.IsNull() )
|
||||
aShape = aComp;
|
||||
}
|
||||
|
||||
|
@@ -19,20 +19,44 @@
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
|
||||
#include <Standard_CString.hxx>
|
||||
class TopoDS_Shape;
|
||||
|
||||
|
||||
//! Reading from stereolithography format.
|
||||
class StlAPI_Reader
|
||||
class StlAPI_Reader
|
||||
{
|
||||
public:
|
||||
|
||||
//! Reads STL file to the TopoDS_Shape (each triangle is converted to the face).
|
||||
//! @return True if reading is successful
|
||||
Standard_EXPORT Standard_Boolean Read (TopoDS_Shape& theShape,
|
||||
const Standard_CString theFileName);
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
Standard_EXPORT StlAPI_Reader();
|
||||
|
||||
Standard_EXPORT void Read (TopoDS_Shape& aShape, const Standard_CString aFileName);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlAPI_Reader_HeaderFile
|
||||
|
@@ -11,102 +11,198 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <StlAPI_Writer.hxx>
|
||||
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <OSD_OpenFile.hxx>
|
||||
#include <RWStl.hxx>
|
||||
#include <StlAPI_Writer.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlTransfer.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
|
||||
//=============================================================================
|
||||
//function : StlAPI_Writer
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
StlAPI_Writer::StlAPI_Writer()
|
||||
: myASCIIMode (Standard_True)
|
||||
{
|
||||
//
|
||||
theStlMesh = new StlMesh_Mesh;
|
||||
theASCIIMode = Standard_True;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : Write
|
||||
//purpose :
|
||||
//=============================================================================
|
||||
Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape& theShape,
|
||||
const Standard_CString theFileName)
|
||||
Standard_Boolean& StlAPI_Writer::ASCIIMode()
|
||||
{
|
||||
Standard_Integer aNbNodes = 0;
|
||||
Standard_Integer aNbTriangles = 0;
|
||||
return theASCIIMode;
|
||||
}
|
||||
|
||||
// calculate total number of the nodes and triangles
|
||||
for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
|
||||
// Auxiliary tools
|
||||
namespace
|
||||
{
|
||||
// Tool to get triangles from triangulation taking into account face
|
||||
// orientation and location
|
||||
class TriangleAccessor
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc);
|
||||
aNbNodes += aTriangulation->NbNodes();
|
||||
aNbTriangles += aTriangulation->NbTriangles();
|
||||
}
|
||||
|
||||
// create temporary triangulation
|
||||
Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False);
|
||||
|
||||
// fill temporary triangulation
|
||||
Standard_Integer aNodeOffset = 0;
|
||||
Standard_Integer aTriangleOffet = 0;
|
||||
for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc);
|
||||
|
||||
const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
|
||||
const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
|
||||
|
||||
// copy nodes
|
||||
gp_Trsf aTrsf = aLoc.Transformation();
|
||||
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
|
||||
public:
|
||||
TriangleAccessor (const TopoDS_Face& aFace)
|
||||
{
|
||||
gp_Pnt aPnt = aNodes (aNodeIter);
|
||||
aPnt.Transform (aTrsf);
|
||||
aMesh->ChangeNode (aNodeIter + aNodeOffset) = aPnt;
|
||||
TopLoc_Location aLoc;
|
||||
myPoly = BRep_Tool::Triangulation (aFace, aLoc);
|
||||
myTrsf = aLoc.Transformation();
|
||||
myNbTriangles = (myPoly.IsNull() ? 0 : myPoly->Triangles().Length());
|
||||
myInvert = (aFace.Orientation() == TopAbs_REVERSED);
|
||||
if (myTrsf.IsNegative())
|
||||
myInvert = ! myInvert;
|
||||
}
|
||||
|
||||
// copy triangles
|
||||
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
|
||||
for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter)
|
||||
{
|
||||
Poly_Triangle aTri = aTriangles (aTriIter);
|
||||
int NbTriangles () const { return myNbTriangles; }
|
||||
|
||||
Standard_Integer anId[3];
|
||||
aTri.Get (anId[0], anId[1], anId[2]);
|
||||
if (anOrientation == TopAbs_REVERSED)
|
||||
// get i-th triangle and outward normal
|
||||
void GetTriangle (int iTri, gp_Vec &theNormal, gp_Pnt &thePnt1, gp_Pnt &thePnt2, gp_Pnt &thePnt3)
|
||||
{
|
||||
// get positions of nodes
|
||||
int iNode1, iNode2, iNode3;
|
||||
myPoly->Triangles()(iTri).Get (iNode1, iNode2, iNode3);
|
||||
thePnt1 = myPoly->Nodes()(iNode1);
|
||||
thePnt2 = myPoly->Nodes()(myInvert ? iNode3 : iNode2);
|
||||
thePnt3 = myPoly->Nodes()(myInvert ? iNode2 : iNode3);
|
||||
|
||||
// apply transormation if not identity
|
||||
if (myTrsf.Form() != gp_Identity)
|
||||
{
|
||||
// Swap 1, 2.
|
||||
Standard_Integer aTmpIdx = anId[1];
|
||||
anId[1] = anId[2];
|
||||
anId[2] = aTmpIdx;
|
||||
thePnt1.Transform (myTrsf);
|
||||
thePnt2.Transform (myTrsf);
|
||||
thePnt3.Transform (myTrsf);
|
||||
}
|
||||
|
||||
// Update nodes according to the offset.
|
||||
anId[0] += aNodeOffset;
|
||||
anId[1] += aNodeOffset;
|
||||
anId[2] += aNodeOffset;
|
||||
|
||||
aTri.Set (anId[0], anId[1], anId[2]);
|
||||
aMesh->ChangeTriangle (aTriIter + aTriangleOffet) = aTri;
|
||||
// calculate normal
|
||||
theNormal = (thePnt2.XYZ() - thePnt1.XYZ()) ^ (thePnt3.XYZ() - thePnt1.XYZ());
|
||||
Standard_Real aNorm = theNormal.Magnitude();
|
||||
if (aNorm > gp::Resolution())
|
||||
theNormal /= aNorm;
|
||||
}
|
||||
|
||||
aNodeOffset += aNodes.Size();
|
||||
aTriangleOffet += aTriangles.Size();
|
||||
private:
|
||||
Handle(Poly_Triangulation) myPoly;
|
||||
gp_Trsf myTrsf;
|
||||
int myNbTriangles;
|
||||
bool myInvert;
|
||||
};
|
||||
|
||||
// convert to float and, on big-endian platform, to little-endian representation
|
||||
inline float convertFloat (Standard_Real aValue)
|
||||
{
|
||||
#ifdef OCCT_BINARY_FILE_DO_INVERSE
|
||||
return OSD_BinaryFile::InverseShortReal ((float)aValue);
|
||||
#else
|
||||
return (float)aValue;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
StlAPI_ErrorStatus StlAPI_Writer::Write(const TopoDS_Shape& theShape, const Standard_CString theFileName)
|
||||
{
|
||||
// open file
|
||||
FILE* aFile = OSD_OpenFile (theFileName, "wb");
|
||||
if (!aFile)
|
||||
return StlAPI_CannotOpenFile;
|
||||
|
||||
// write
|
||||
if (theASCIIMode)
|
||||
{
|
||||
// header
|
||||
Fprintf (aFile, "solid shape, STL ascii file, created with Open CASCADE Technology\n");
|
||||
|
||||
// facets
|
||||
for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next())
|
||||
{
|
||||
TriangleAccessor aTool (TopoDS::Face (exp.Current()));
|
||||
for (int iTri = 1; iTri <= aTool.NbTriangles(); iTri++)
|
||||
{
|
||||
gp_Vec aNorm;
|
||||
gp_Pnt aPnt1, aPnt2, aPnt3;
|
||||
aTool.GetTriangle (iTri, aNorm, aPnt1, aPnt2, aPnt3);
|
||||
|
||||
Fprintf (aFile,
|
||||
" facet normal %12e %12e %12e\n"
|
||||
" outer loop\n"
|
||||
" vertex %12e %12e %12e\n"
|
||||
" vertex %12e %12e %12e\n"
|
||||
" vertex %12e %12e %12e\n"
|
||||
" endloop\n"
|
||||
" endfacet\n",
|
||||
aNorm.X(), aNorm.Y(), aNorm.Z(),
|
||||
aPnt1.X(), aPnt1.Y(), aPnt1.Z(),
|
||||
aPnt2.X(), aPnt2.Y(), aPnt2.Z(),
|
||||
aPnt3.X(), aPnt3.Y(), aPnt3.Z());
|
||||
}
|
||||
}
|
||||
|
||||
// footer
|
||||
Fprintf (aFile, "endsolid shape\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// header block (meaningless 80 bytes)
|
||||
Fprintf (aFile, "%-80.80s", "STL binary file, created with Open CASCADE Technology");
|
||||
|
||||
// number of facets
|
||||
int32_t aNbTri = 0;
|
||||
for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next())
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Poly_Triangulation) aPoly =
|
||||
BRep_Tool::Triangulation (TopoDS::Face (exp.Current()), aLoc);
|
||||
if (! aPoly.IsNull())
|
||||
aNbTri += aPoly->NbTriangles();
|
||||
}
|
||||
// suppose that number of triangles must be little endian...
|
||||
#ifdef OCCT_BINARY_FILE_DO_INVERSE
|
||||
aNbTri = OSD_BinaryFile::InverseInteger (aNbTri);
|
||||
#endif
|
||||
fwrite (&aNbTri, sizeof(int32_t), 1, aFile);
|
||||
|
||||
// facets
|
||||
struct Facet {
|
||||
float nx, ny, nz;
|
||||
float x1, y1, z1;
|
||||
float x2, y2, z2;
|
||||
float x3, y3, z3;
|
||||
uint16_t dummy;
|
||||
} f;
|
||||
f.dummy = 0;
|
||||
for (TopExp_Explorer exp (theShape, TopAbs_FACE); exp.More(); exp.Next())
|
||||
{
|
||||
TriangleAccessor aTool (TopoDS::Face (exp.Current()));
|
||||
for (int iTri = 1; iTri <= aTool.NbTriangles(); iTri++)
|
||||
{
|
||||
gp_Vec aNorm;
|
||||
gp_Pnt aPnt1, aPnt2, aPnt3;
|
||||
aTool.GetTriangle (iTri, aNorm, aPnt1, aPnt2, aPnt3);
|
||||
|
||||
f.nx = convertFloat (aNorm.X());
|
||||
f.ny = convertFloat (aNorm.Y());
|
||||
f.nz = convertFloat (aNorm.Z());
|
||||
|
||||
f.x1 = convertFloat (aPnt1.X());
|
||||
f.y1 = convertFloat (aPnt1.Y());
|
||||
f.z1 = convertFloat (aPnt1.Z());
|
||||
|
||||
f.x2 = convertFloat (aPnt2.X());
|
||||
f.y2 = convertFloat (aPnt2.Y());
|
||||
f.z2 = convertFloat (aPnt2.Z());
|
||||
|
||||
f.x3 = convertFloat (aPnt3.X());
|
||||
f.y3 = convertFloat (aPnt3.Y());
|
||||
f.z3 = convertFloat (aPnt3.Z());
|
||||
|
||||
fwrite (&f, 50 /* 50 bytes per facet */, 1, aFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSD_Path aPath (theFileName);
|
||||
return myASCIIMode
|
||||
? RWStl::WriteAscii (aMesh, aPath)
|
||||
: RWStl::WriteBinary (aMesh, aPath);
|
||||
fclose (aFile);
|
||||
return ferror(aFile) ? StlAPI_WriteError : StlAPI_StatusOK;
|
||||
}
|
||||
|
||||
|
@@ -16,39 +16,66 @@
|
||||
#ifndef _StlAPI_Writer_HeaderFile
|
||||
#define _StlAPI_Writer_HeaderFile
|
||||
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <StlAPI_ErrorStatus.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
class StlMesh_Mesh;
|
||||
class TopoDS_Shape;
|
||||
|
||||
|
||||
//! This class creates and writes
|
||||
//! STL files from Open CASCADE shapes. An STL file can be written to an existing STL file or to a new one.
|
||||
class StlAPI_Writer
|
||||
//! STL files from Open CASCADE shapes. An STL file can be
|
||||
//! written to an existing STL file or to a new one..
|
||||
class StlAPI_Writer
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Creates a writer object with default parameters: ASCIIMode.
|
||||
|
||||
//! Creates a writer object with
|
||||
//! default parameters: ASCIIMode.
|
||||
Standard_EXPORT StlAPI_Writer();
|
||||
|
||||
//! Returns the address to the flag defining the mode for writing the file.
|
||||
//! This address may be used to either read or change the flag.
|
||||
//! If the mode returns True (default value) the generated file is an ASCII file.
|
||||
//! If the mode returns False, the generated file is a binary file.
|
||||
Standard_Boolean& ASCIIMode() { return myASCIIMode; }
|
||||
|
||||
|
||||
//! Returns the address to the
|
||||
//! flag defining the mode for writing the file. This address
|
||||
//! may be used to either read or change the flag.
|
||||
//! If the mode returns True (default value) the generated
|
||||
//! file is an ASCII file. If the mode returns False, the
|
||||
//! generated file is a binary file.
|
||||
Standard_EXPORT Standard_Boolean& ASCIIMode();
|
||||
|
||||
//! Converts a given shape to STL format and writes it to file with a given filename.
|
||||
//! \return the error state.
|
||||
Standard_EXPORT Standard_Boolean Write (const TopoDS_Shape& theShape,
|
||||
const Standard_CString theFileName);
|
||||
Standard_EXPORT StlAPI_ErrorStatus Write (const TopoDS_Shape& aShape, const Standard_CString aFileName);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Standard_Boolean myASCIIMode;
|
||||
|
||||
|
||||
|
||||
Standard_Boolean theASCIIMode;
|
||||
Handle(StlMesh_Mesh) theStlMesh;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlAPI_Writer_HeaderFile
|
||||
|
16
src/StlMesh/FILES
Normal file
16
src/StlMesh/FILES
Normal file
@@ -0,0 +1,16 @@
|
||||
StlMesh.cxx
|
||||
StlMesh.hxx
|
||||
StlMesh_Mesh.cxx
|
||||
StlMesh_Mesh.hxx
|
||||
StlMesh_Mesh.lxx
|
||||
StlMesh_MeshDomain.cxx
|
||||
StlMesh_MeshDomain.hxx
|
||||
StlMesh_MeshDomain.lxx
|
||||
StlMesh_MeshExplorer.cxx
|
||||
StlMesh_MeshExplorer.hxx
|
||||
StlMesh_MeshExplorer.lxx
|
||||
StlMesh_MeshTriangle.cxx
|
||||
StlMesh_MeshTriangle.hxx
|
||||
StlMesh_SequenceOfMesh.hxx
|
||||
StlMesh_SequenceOfMeshDomain.hxx
|
||||
StlMesh_SequenceOfMeshTriangle.hxx
|
78
src/StlMesh/StlMesh.cxx
Normal file
78
src/StlMesh/StlMesh.cxx
Normal file
@@ -0,0 +1,78 @@
|
||||
// Created on: 1996-06-21
|
||||
// Created by: Bruno TACCI
|
||||
// Copyright (c) 1996-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <StlMesh.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Merge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(StlMesh_Mesh) StlMesh::Merge(const Handle(StlMesh_Mesh)& mesh1, const Handle(StlMesh_Mesh)& mesh2)
|
||||
{
|
||||
Handle(StlMesh_Mesh) mergeMesh = new StlMesh_Mesh;
|
||||
StlMesh_SequenceOfMeshTriangle aSeqOfTriangle;
|
||||
TColgp_SequenceOfXYZ aSeqOfVertex;
|
||||
Standard_Real xn,yn,zn;
|
||||
Standard_Integer v1,v2,v3;
|
||||
|
||||
// Chargement de mesh1 dans mergeMesh
|
||||
// Boucle sur les domaines puis sur les triangles
|
||||
|
||||
Standard_Integer idom;
|
||||
for (idom = 1; idom <= mesh1->NbDomains(); idom++) {
|
||||
aSeqOfTriangle = mesh1->Triangles(idom);
|
||||
aSeqOfVertex = mesh1->Vertices(idom);
|
||||
mergeMesh->AddDomain(mesh1->Deflection(idom));
|
||||
|
||||
for (Standard_Integer itri = 1; itri <= mesh1->NbTriangles(idom); itri++) {
|
||||
const Handle(StlMesh_MeshTriangle) aTrian = aSeqOfTriangle.Value(itri);
|
||||
aTrian->GetVertexAndOrientation(v1,v2,v3,xn,yn,zn);
|
||||
mergeMesh->AddTriangle(v1,v2,v3,xn,yn,zn);
|
||||
}
|
||||
|
||||
for (Standard_Integer iver = 1; iver <= mesh1->NbVertices(idom); iver++) {
|
||||
mergeMesh->AddVertex(aSeqOfVertex.Value(iver).X(),
|
||||
aSeqOfVertex.Value(iver).Y(),
|
||||
aSeqOfVertex.Value(iver).Z());
|
||||
}
|
||||
|
||||
}
|
||||
// Idem avec mesh2
|
||||
|
||||
for (idom = 1; idom <= mesh2->NbDomains(); idom++) {
|
||||
aSeqOfTriangle = mesh2->Triangles(idom);
|
||||
aSeqOfVertex = mesh2->Vertices(idom);
|
||||
mergeMesh->AddDomain(mesh2->Deflection(idom));
|
||||
|
||||
for (Standard_Integer itri = 1; itri <= mesh2->NbTriangles(idom); itri++) {
|
||||
const Handle(StlMesh_MeshTriangle) aTrian = aSeqOfTriangle.Value(itri);
|
||||
aTrian->GetVertexAndOrientation(v1,v2,v3,xn,yn,zn);
|
||||
mergeMesh->AddTriangle(v1,v2,v3,xn,yn,zn);
|
||||
}
|
||||
|
||||
for (Standard_Integer iver = 1; iver <= mesh2->NbVertices(idom); iver++) {
|
||||
mergeMesh->AddVertex(aSeqOfVertex.Value(iver).X(),
|
||||
aSeqOfVertex.Value(iver).Y(),
|
||||
aSeqOfVertex.Value(iver).Z());
|
||||
}
|
||||
}
|
||||
return mergeMesh;
|
||||
}
|
73
src/StlMesh/StlMesh.hxx
Normal file
73
src/StlMesh/StlMesh.hxx
Normal file
@@ -0,0 +1,73 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlMesh_HeaderFile
|
||||
#define _StlMesh_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
class StlMesh_Mesh;
|
||||
class StlMesh_Mesh;
|
||||
class StlMesh_MeshExplorer;
|
||||
class StlMesh_MeshDomain;
|
||||
class StlMesh_MeshTriangle;
|
||||
|
||||
|
||||
//! Implements a basic mesh data-structure for the
|
||||
//! needs of the application fast prototyping.
|
||||
class StlMesh
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! Sequence of meshes
|
||||
//! Make a merge of two Mesh and returns a new Mesh.
|
||||
//! Very useful if you want to merge partMesh and CheckSurfaceMesh
|
||||
//! for example
|
||||
Standard_EXPORT static Handle(StlMesh_Mesh) Merge (const Handle(StlMesh_Mesh)& mesh1, const Handle(StlMesh_Mesh)& mesh2);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
friend class StlMesh_Mesh;
|
||||
friend class StlMesh_MeshExplorer;
|
||||
friend class StlMesh_MeshDomain;
|
||||
friend class StlMesh_MeshTriangle;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlMesh_HeaderFile
|
181
src/StlMesh/StlMesh_Mesh.cxx
Normal file
181
src/StlMesh/StlMesh_Mesh.cxx
Normal file
@@ -0,0 +1,181 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_NegativeValue.hxx>
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Standard_NullValue.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshDomain.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(StlMesh_Mesh,Standard_Transient)
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_Mesh
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
StlMesh_Mesh::StlMesh_Mesh()
|
||||
: nbTriangles (0), nbVertices (0), xyzmax (-(Precision::Infinite()), -(Precision::Infinite()), -(Precision::Infinite())), xyzmin (Precision::Infinite(), Precision::Infinite(), Precision::Infinite())
|
||||
{ }
|
||||
|
||||
//=======================================================================
|
||||
//function : AddDomain
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_Mesh::AddDomain()
|
||||
{
|
||||
Handle(StlMesh_MeshDomain) MD = new StlMesh_MeshDomain;
|
||||
domains.Append (MD);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddDomain
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_Mesh::AddDomain(const Standard_Real Deflection)
|
||||
{
|
||||
Handle(StlMesh_MeshDomain) MD = new StlMesh_MeshDomain (Deflection);
|
||||
domains.Append (MD);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_Mesh::AddTriangle(const Standard_Integer V1, const Standard_Integer V2,
|
||||
const Standard_Integer V3, const Standard_Real Xn,
|
||||
const Standard_Real Yn, const Standard_Real Zn)
|
||||
{
|
||||
nbTriangles++;
|
||||
return (domains.Last())->AddTriangle (V1, V2, V3, Xn, Yn, Zn);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertex
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_Mesh::AddVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z)
|
||||
{
|
||||
nbVertices++;
|
||||
if (X > xyzmax.X()) xyzmax.SetX (X);
|
||||
if (Y > xyzmax.Y()) xyzmax.SetY (Y);
|
||||
if (Z > xyzmax.Z()) xyzmax.SetZ (Z);
|
||||
if (X < xyzmin.X()) xyzmin.SetX (X);
|
||||
if (Y < xyzmin.Y()) xyzmin.SetY (Y);
|
||||
if (Z < xyzmin.Z()) xyzmin.SetZ (Z);
|
||||
|
||||
return (domains.Last())->AddVertex (X, Y, Z);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddOnlyNewVertex
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_Mesh::AddOnlyNewVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z)
|
||||
{
|
||||
Standard_Boolean IsNew = Standard_True;
|
||||
Standard_Integer VIndex = (domains.Last())->AddOnlyNewVertex (X, Y, Z, IsNew);
|
||||
if (IsNew) nbVertices++;
|
||||
return VIndex;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Bounds
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_Mesh::Bounds(gp_XYZ& XYZmax, gp_XYZ& XYZmin) const
|
||||
{
|
||||
XYZmax = xyzmax;
|
||||
XYZmin = xyzmin;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Clear
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_Mesh::Clear()
|
||||
{
|
||||
nbTriangles = 0;
|
||||
nbVertices = 0;
|
||||
xyzmax.SetCoord(-(Precision::Infinite()),-(Precision::Infinite()),-(Precision::Infinite()));
|
||||
xyzmin.SetCoord(Precision::Infinite(),Precision::Infinite(),Precision::Infinite());
|
||||
domains.Clear ();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real StlMesh_Mesh::Deflection(const Standard_Integer DomainIndex) const
|
||||
{return (domains.Value (DomainIndex))->Deflection ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbTriangles
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_Mesh::NbTriangles(const Standard_Integer DomainIndex) const
|
||||
{ return (domains.Value(DomainIndex))->NbTriangles ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbVertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_Mesh::NbVertices(const Standard_Integer DomainIndex) const
|
||||
{ return (domains.Value(DomainIndex))->NbVertices ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangles
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
const StlMesh_SequenceOfMeshTriangle& StlMesh_Mesh::Triangles(const Standard_Integer DomainIndex) const
|
||||
{ return (domains.Value (DomainIndex))->Triangles ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : Vertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
const TColgp_SequenceOfXYZ& StlMesh_Mesh::Vertices(const Standard_Integer DomainIndex) const
|
||||
{ return (domains.Value (DomainIndex))->Vertices ();}
|
||||
|
160
src/StlMesh/StlMesh_Mesh.hxx
Normal file
160
src/StlMesh/StlMesh_Mesh.hxx
Normal file
@@ -0,0 +1,160 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlMesh_Mesh_HeaderFile
|
||||
#define _StlMesh_Mesh_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <StlMesh_SequenceOfMeshDomain.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
class Standard_NegativeValue;
|
||||
class Standard_NullValue;
|
||||
class Standard_NoSuchObject;
|
||||
class gp_XYZ;
|
||||
|
||||
|
||||
class StlMesh_Mesh;
|
||||
DEFINE_STANDARD_HANDLE(StlMesh_Mesh, Standard_Transient)
|
||||
|
||||
//! Mesh definition. The mesh contains one or several
|
||||
//! domains. Each mesh domain contains a set of
|
||||
//! triangles. Each domain can have its own deflection
|
||||
//! value.
|
||||
class StlMesh_Mesh : public Standard_Transient
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//! Creates an empty mesh.
|
||||
Standard_EXPORT StlMesh_Mesh();
|
||||
|
||||
//! Adds a new mesh domain. The mesh deflection is
|
||||
//! defaulted to Confusion from package Precision.
|
||||
Standard_EXPORT virtual void AddDomain();
|
||||
|
||||
//! Adds a new mesh domain.
|
||||
//! Raised if the deflection is lower than zero
|
||||
//! Raised if the deflection is lower than Confusion
|
||||
//! from package Precision
|
||||
Standard_EXPORT virtual void AddDomain (const Standard_Real Deflection);
|
||||
|
||||
//! Build a triangle with the triplet of vertices (V1,
|
||||
//! V2, V3). This triplet defines the indexes of the
|
||||
//! vertex in the current domain The coordinates Xn,
|
||||
//! Yn, Zn defines the normal direction to the
|
||||
//! triangle. Returns the range of the triangle in
|
||||
//! the current domain.
|
||||
Standard_EXPORT virtual Standard_Integer AddTriangle (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn);
|
||||
|
||||
//! Returns the range of the vertex in the current
|
||||
//! domain.
|
||||
Standard_EXPORT virtual Standard_Integer AddVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z);
|
||||
|
||||
//! Returns the range of the vertex in the current
|
||||
//! domain. The current vertex is not inserted in the
|
||||
//! mesh if it already exist.
|
||||
Standard_EXPORT virtual Standard_Integer AddOnlyNewVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z);
|
||||
|
||||
//! Each vertex of the mesh verifies the following
|
||||
//! relations :
|
||||
//! XYZMin.X() <= X <= XYZMax.X()
|
||||
//! XYZMin.Y() <= Y <= XYZMax.y()
|
||||
//! XYZMin.Z() <= Z <= XYZMax.Z()
|
||||
Standard_EXPORT virtual void Bounds (gp_XYZ& XYZmax, gp_XYZ& XYZmin) const;
|
||||
|
||||
Standard_EXPORT virtual void Clear();
|
||||
|
||||
//! Returns the deflection of the mesh of the domain
|
||||
//! of range <DomainIndex>.
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT virtual Standard_Real Deflection (const Standard_Integer DomainIndex) const;
|
||||
|
||||
virtual Standard_Boolean IsEmpty() const;
|
||||
|
||||
//! Number of domains in the mesh.
|
||||
virtual Standard_Integer NbDomains() const;
|
||||
|
||||
//! Cumulative Number of triangles in the mesh.
|
||||
Standard_Integer NbTriangles() const;
|
||||
|
||||
//! Number of triangles in the domain of range
|
||||
//! <DomainIndex>.
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT virtual Standard_Integer NbTriangles (const Standard_Integer DomainIndex) const;
|
||||
|
||||
//! Cumulative Number of vertices in the mesh.
|
||||
virtual Standard_Integer NbVertices() const;
|
||||
|
||||
//! Number of vertices in the domain of range
|
||||
//! <DomainIndex>.
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT virtual Standard_Integer NbVertices (const Standard_Integer DomainIndex) const;
|
||||
|
||||
//! Returns the set of triangle of the mesh domain of range
|
||||
//! <DomainIndex>.
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT virtual const StlMesh_SequenceOfMeshTriangle& Triangles (const Standard_Integer DomainIndex = 1) const;
|
||||
|
||||
//! Returns the coordinates of the vertices of the
|
||||
//! mesh domain of range <DomainIndex>. {XV1, YV1,
|
||||
//! ZV1, XV2, YV2, ZV2, XV3,.....}
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT virtual const TColgp_SequenceOfXYZ& Vertices (const Standard_Integer DomainIndex = 1) const;
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(StlMesh_Mesh,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
Standard_Integer nbTriangles;
|
||||
Standard_Integer nbVertices;
|
||||
StlMesh_SequenceOfMeshDomain domains;
|
||||
gp_XYZ xyzmax;
|
||||
gp_XYZ xyzmin;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#include <StlMesh_Mesh.lxx>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlMesh_Mesh_HeaderFile
|
61
src/StlMesh/StlMesh_Mesh.lxx
Normal file
61
src/StlMesh/StlMesh_Mesh.lxx
Normal file
@@ -0,0 +1,61 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
//function : IsEmpty
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean StlMesh_Mesh::IsEmpty() const
|
||||
{return domains.IsEmpty ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbDomains
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer StlMesh_Mesh::NbDomains() const
|
||||
{ return domains.Length ();}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbTriangles
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer StlMesh_Mesh::NbTriangles() const
|
||||
{return nbTriangles;}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbVertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer StlMesh_Mesh::NbVertices() const
|
||||
{return nbVertices;}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
101
src/StlMesh/StlMesh_MeshDomain.cxx
Normal file
101
src/StlMesh/StlMesh_MeshDomain.cxx
Normal file
@@ -0,0 +1,101 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_NegativeValue.hxx>
|
||||
#include <Standard_NullValue.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <StlMesh_MeshDomain.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(StlMesh_MeshDomain,Standard_Transient)
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_MeshDomain
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
StlMesh_MeshDomain::StlMesh_MeshDomain() : deflection (Precision::Confusion ()), nbVertices (0), nbTriangles (0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_MeshDomain
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
StlMesh_MeshDomain::StlMesh_MeshDomain(const Standard_Real Deflection)
|
||||
: deflection (Deflection), nbVertices (0), nbTriangles (0) { }
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AddTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_MeshDomain::AddTriangle(const Standard_Integer V1,
|
||||
const Standard_Integer V2, const Standard_Integer V3,
|
||||
const Standard_Real Xn, const Standard_Real Yn,
|
||||
const Standard_Real Zn)
|
||||
{
|
||||
const Handle (StlMesh_MeshTriangle) tri = new StlMesh_MeshTriangle (V1, V2, V3, Xn, Yn, Zn);
|
||||
trianglesVertex.Append (tri);
|
||||
nbTriangles++;
|
||||
return nbTriangles;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertex
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_MeshDomain::AddVertex(const Standard_Real X, const Standard_Real Y, const Standard_Real Z)
|
||||
{
|
||||
gp_XYZ Vx (X, Y, Z);
|
||||
vertexCoords.Append (Vx);
|
||||
nbVertices++;
|
||||
return nbVertices;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddOnlyNewVertex
|
||||
//design : Adds the vertex only if X and Y and Z doesn`t already exists.
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer StlMesh_MeshDomain::AddOnlyNewVertex(const Standard_Real X,
|
||||
const Standard_Real Y,
|
||||
const Standard_Real Z,
|
||||
Standard_Boolean& IsNew)
|
||||
{
|
||||
gp_XYZ Vx (X, Y, Z);
|
||||
IsNew = Standard_True;
|
||||
vertexCoords.Append (Vx);
|
||||
nbVertices++;
|
||||
return nbVertices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
117
src/StlMesh/StlMesh_MeshDomain.hxx
Normal file
117
src/StlMesh/StlMesh_MeshDomain.hxx
Normal file
@@ -0,0 +1,117 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlMesh_MeshDomain_HeaderFile
|
||||
#define _StlMesh_MeshDomain_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
class Standard_NegativeValue;
|
||||
class Standard_NullValue;
|
||||
|
||||
|
||||
class StlMesh_MeshDomain;
|
||||
DEFINE_STANDARD_HANDLE(StlMesh_MeshDomain, Standard_Transient)
|
||||
|
||||
//! A mesh domain is a set of triangles defined with
|
||||
//! three geometric vertices and a given orientation.
|
||||
//! The mesh domain has its own deflection.
|
||||
//! Internal class used to classify the triangles of each domain.
|
||||
class StlMesh_MeshDomain : public Standard_Transient
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//! The mesh deflection is defaulted to Confusion from
|
||||
//! package Precision.
|
||||
Standard_EXPORT StlMesh_MeshDomain();
|
||||
|
||||
//! Raised if the deflection is lower than zero
|
||||
//! Raised if the deflection is lower than Confusion
|
||||
//! from package Precision
|
||||
Standard_EXPORT StlMesh_MeshDomain(const Standard_Real Deflection);
|
||||
|
||||
//! Build a triangle with the triplet of vertices (V1,
|
||||
//! V2, V3). This triplet defines the indexes of the
|
||||
//! vertex in the current domain The coordinates Xn,
|
||||
//! Yn, Zn defines the normal direction to the
|
||||
//! triangle. Returns the range of the triangle in
|
||||
//! the current domain.
|
||||
Standard_EXPORT virtual Standard_Integer AddTriangle (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn);
|
||||
|
||||
//! Returns the range of the vertex in the current
|
||||
//! domain.
|
||||
Standard_EXPORT virtual Standard_Integer AddVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z);
|
||||
|
||||
//! Returns the range of the vertex in the current
|
||||
//! domain. The current vertex is not inserted in the
|
||||
//! mesh if it already exist.
|
||||
Standard_EXPORT virtual Standard_Integer AddOnlyNewVertex (const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Boolean& IsNew);
|
||||
|
||||
virtual Standard_Real Deflection() const;
|
||||
|
||||
//! Number of triangles in the mesh.
|
||||
virtual Standard_Integer NbTriangles() const;
|
||||
|
||||
//! Number of vertices in the mesh.
|
||||
virtual Standard_Integer NbVertices() const;
|
||||
|
||||
//! Returns the set of triangles of the current mesh domain
|
||||
virtual const StlMesh_SequenceOfMeshTriangle& Triangles() const;
|
||||
|
||||
//! Returns the coordinates of the vertices of the
|
||||
//! mesh domain of range <DomainIndex>. {XV1, YV1,
|
||||
//! ZV1, XV2, YV2, ZV2, XV3,.....}
|
||||
virtual const TColgp_SequenceOfXYZ& Vertices() const;
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(StlMesh_MeshDomain,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Standard_Real deflection;
|
||||
Standard_Integer nbVertices;
|
||||
Standard_Integer nbTriangles;
|
||||
TColgp_SequenceOfXYZ vertexCoords;
|
||||
StlMesh_SequenceOfMeshTriangle trianglesVertex;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#include <StlMesh_MeshDomain.lxx>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlMesh_MeshDomain_HeaderFile
|
63
src/StlMesh/StlMesh_MeshDomain.lxx
Normal file
63
src/StlMesh/StlMesh_MeshDomain.lxx
Normal file
@@ -0,0 +1,63 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Real StlMesh_MeshDomain::Deflection() const
|
||||
{ return deflection; }
|
||||
|
||||
//=======================================================================
|
||||
//function : NbTriangles
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer StlMesh_MeshDomain::NbTriangles() const
|
||||
{ return nbTriangles; }
|
||||
|
||||
//=======================================================================
|
||||
//function : NbVertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Integer StlMesh_MeshDomain::NbVertices() const
|
||||
{ return nbVertices; }
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangles
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline const StlMesh_SequenceOfMeshTriangle& StlMesh_MeshDomain::Triangles() const
|
||||
{ return trianglesVertex; }
|
||||
|
||||
//=======================================================================
|
||||
//function : Vertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline const TColgp_SequenceOfXYZ& StlMesh_MeshDomain::Vertices() const
|
||||
{ return vertexCoords; }
|
||||
|
121
src/StlMesh/StlMesh_MeshExplorer.cxx
Normal file
121
src/StlMesh/StlMesh_MeshExplorer.cxx
Normal file
@@ -0,0 +1,121 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#include <Standard_NoMoreObject.hxx>
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshExplorer.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_MeshExplorer
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
StlMesh_MeshExplorer::StlMesh_MeshExplorer(const Handle(StlMesh_Mesh)& M)
|
||||
: domainIndex (0), nbTriangles (0) ,triangleIndex (0) { mesh = M;}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Deflection
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Real StlMesh_MeshExplorer::Deflection() const
|
||||
{ return mesh->Deflection (domainIndex);}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : InitTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshExplorer::InitTriangle(const Standard_Integer DomainIndex)
|
||||
{
|
||||
triangleIndex = 1;
|
||||
domainIndex = DomainIndex;
|
||||
nbTriangles = mesh->NbTriangles (domainIndex);
|
||||
if (nbTriangles > 0) {
|
||||
trianglesdef.Assign (mesh->Triangles (DomainIndex));
|
||||
trianglesVertex.Assign (mesh->Vertices (DomainIndex));
|
||||
const Handle (StlMesh_MeshTriangle) trian = trianglesdef.First();
|
||||
trian->GetVertexAndOrientation (v1,v2,v3,xn,yn,zn);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NextTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshExplorer::NextTriangle()
|
||||
{
|
||||
triangleIndex++;
|
||||
if (triangleIndex <= nbTriangles) {
|
||||
const Handle (StlMesh_MeshTriangle) trian = trianglesdef.Value (triangleIndex);
|
||||
trian->GetVertexAndOrientation (v1,v2,v3,xn,yn,zn);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TriangleVertices
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshExplorer::TriangleVertices(Standard_Real& X1, Standard_Real& Y1,
|
||||
Standard_Real& Z1, Standard_Real& X2,
|
||||
Standard_Real& Y2, Standard_Real& Z2,
|
||||
Standard_Real& X3, Standard_Real& Y3,
|
||||
Standard_Real& Z3) const
|
||||
{
|
||||
Standard_NoSuchObject_Raise_if (triangleIndex > nbTriangles, " StlMesh_MeshExplorer::TriangleVertices");
|
||||
|
||||
X1 = (trianglesVertex.Value(v1)).X();
|
||||
Y1 = (trianglesVertex.Value(v1)).Y();
|
||||
Z1 = (trianglesVertex.Value(v1)).Z();
|
||||
X2 = (trianglesVertex.Value(v2)).X();
|
||||
Y2 = (trianglesVertex.Value(v2)).Y();
|
||||
Z2 = (trianglesVertex.Value(v2)).Z();
|
||||
X3 = (trianglesVertex.Value(v3)).X();
|
||||
Y3 = (trianglesVertex.Value(v3)).Y();
|
||||
Z3 = (trianglesVertex.Value(v3)).Z();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : TriangleDirection
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshExplorer::TriangleOrientation(Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const
|
||||
{
|
||||
Xn = xn;
|
||||
Yn = yn;
|
||||
Zn = zn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
105
src/StlMesh/StlMesh_MeshExplorer.hxx
Normal file
105
src/StlMesh/StlMesh_MeshExplorer.hxx
Normal file
@@ -0,0 +1,105 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlMesh_MeshExplorer_HeaderFile
|
||||
#define _StlMesh_MeshExplorer_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
class StlMesh_Mesh;
|
||||
class Standard_OutOfRange;
|
||||
class Standard_NoMoreObject;
|
||||
class Standard_NoSuchObject;
|
||||
|
||||
|
||||
//! Provides facilities to explore the triangles of
|
||||
//! each mesh domain.
|
||||
class StlMesh_MeshExplorer
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
Standard_EXPORT StlMesh_MeshExplorer(const Handle(StlMesh_Mesh)& M);
|
||||
|
||||
//! Returns the mesh deflection of the current domain.
|
||||
Standard_EXPORT Standard_Real Deflection() const;
|
||||
|
||||
//! Initializes the exploration of the triangles of
|
||||
//! the mesh domain of range <DomainIndex>.
|
||||
//! Raised if <DomainIndex> is lower than 1 or greater
|
||||
//! than the number of domains.
|
||||
Standard_EXPORT void InitTriangle (const Standard_Integer DomainIndex = 1);
|
||||
|
||||
Standard_Boolean MoreTriangle() const;
|
||||
|
||||
//! Raised if there is no more triangle in the current
|
||||
//! domain.
|
||||
Standard_EXPORT void NextTriangle();
|
||||
|
||||
//! Raised if there is no more triangle in the current
|
||||
//! domain.
|
||||
Standard_EXPORT void TriangleVertices (Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1, Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2, Standard_Real& X3, Standard_Real& Y3, Standard_Real& Z3) const;
|
||||
|
||||
//! Raised if there is no more triangle in the current
|
||||
//! domain.
|
||||
Standard_EXPORT void TriangleOrientation (Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
Handle(StlMesh_Mesh) mesh;
|
||||
Standard_Real xn;
|
||||
Standard_Real yn;
|
||||
Standard_Real zn;
|
||||
Standard_Integer v1;
|
||||
Standard_Integer v2;
|
||||
Standard_Integer v3;
|
||||
Standard_Integer domainIndex;
|
||||
Standard_Integer nbTriangles;
|
||||
Standard_Integer triangleIndex;
|
||||
TColgp_SequenceOfXYZ trianglesVertex;
|
||||
StlMesh_SequenceOfMeshTriangle trianglesdef;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#include <StlMesh_MeshExplorer.lxx>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlMesh_MeshExplorer_HeaderFile
|
27
src/StlMesh/StlMesh_MeshExplorer.lxx
Normal file
27
src/StlMesh/StlMesh_MeshExplorer.lxx
Normal file
@@ -0,0 +1,27 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
//function : MoreTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
inline Standard_Boolean StlMesh_MeshExplorer::MoreTriangle() const
|
||||
{ return triangleIndex <= nbTriangles; }
|
||||
|
117
src/StlMesh/StlMesh_MeshTriangle.cxx
Normal file
117
src/StlMesh/StlMesh_MeshTriangle.cxx
Normal file
@@ -0,0 +1,117 @@
|
||||
// Created on: 1995-09-25
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_NegativeValue.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(StlMesh_MeshTriangle,Standard_Transient)
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_MeshTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
StlMesh_MeshTriangle::StlMesh_MeshTriangle()
|
||||
: MyV1 (0), MyV2 (0), MyV3 (0), MyXn (0.0), MyYn (0.0), MyZn (0.0) { }
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : StlMesh_MeshTriangle
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
StlMesh_MeshTriangle::StlMesh_MeshTriangle(const Standard_Integer V1,
|
||||
const Standard_Integer V2,
|
||||
const Standard_Integer V3,
|
||||
const Standard_Real Xn,
|
||||
const Standard_Real Yn,
|
||||
const Standard_Real Zn)
|
||||
: MyV1 (V1), MyV2 (V2), MyV3 (V3), MyXn (Xn), MyYn (Yn), MyZn (Zn) { }
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : GetVertexAndOrientation
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshTriangle::GetVertexAndOrientation(Standard_Integer& V1,
|
||||
Standard_Integer& V2,
|
||||
Standard_Integer& V3,
|
||||
Standard_Real& Xn,
|
||||
Standard_Real& Yn,
|
||||
Standard_Real& Zn) const
|
||||
{
|
||||
V1 = MyV1;
|
||||
V2 = MyV2;
|
||||
V3 = MyV3;
|
||||
Xn = MyXn;
|
||||
Yn = MyYn;
|
||||
Zn = MyZn;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetVertexAndOrientation
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshTriangle::SetVertexAndOrientation(const Standard_Integer V1, const Standard_Integer V2,
|
||||
const Standard_Integer V3, const Standard_Real Xn,
|
||||
const Standard_Real Yn, const Standard_Real Zn)
|
||||
{
|
||||
MyV1 = V1;
|
||||
MyV2 = V2;
|
||||
MyV3 = V3;
|
||||
MyXn = Xn;
|
||||
MyYn = Yn;
|
||||
MyZn = Zn;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetVertex
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshTriangle::GetVertex(Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3) const
|
||||
{
|
||||
V1 = MyV1;
|
||||
V2 = MyV2;
|
||||
V3 = MyV3;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetVertex
|
||||
//design :
|
||||
//warning :
|
||||
//=======================================================================
|
||||
|
||||
void StlMesh_MeshTriangle::SetVertex(const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3)
|
||||
{
|
||||
MyV1 = V1;
|
||||
MyV2 = V2;
|
||||
MyV3 = V3;
|
||||
}
|
||||
|
||||
|
||||
|
91
src/StlMesh/StlMesh_MeshTriangle.hxx
Normal file
91
src/StlMesh/StlMesh_MeshTriangle.hxx
Normal file
@@ -0,0 +1,91 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlMesh_MeshTriangle_HeaderFile
|
||||
#define _StlMesh_MeshTriangle_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
class Standard_NegativeValue;
|
||||
|
||||
|
||||
class StlMesh_MeshTriangle;
|
||||
DEFINE_STANDARD_HANDLE(StlMesh_MeshTriangle, Standard_Transient)
|
||||
|
||||
//! A mesh triangle is defined with
|
||||
//! three geometric vertices and an orientation
|
||||
class StlMesh_MeshTriangle : public Standard_Transient
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
//! empty constructor
|
||||
Standard_EXPORT StlMesh_MeshTriangle();
|
||||
|
||||
//! create a triangle defined with the indexes of its three vertices
|
||||
//! and its orientation
|
||||
//! Raised if V1, V2 or V3 is lower than zero
|
||||
Standard_EXPORT StlMesh_MeshTriangle(const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn);
|
||||
|
||||
//! get indexes of the three vertices (V1,V2,V3) and the orientation
|
||||
Standard_EXPORT void GetVertexAndOrientation (Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3, Standard_Real& Xn, Standard_Real& Yn, Standard_Real& Zn) const;
|
||||
|
||||
//! set indexes of the three vertices (V1,V2,V3) and the orientation
|
||||
//! Raised if V1, V2 or V3 is lower than zero
|
||||
Standard_EXPORT void SetVertexAndOrientation (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3, const Standard_Real Xn, const Standard_Real Yn, const Standard_Real Zn);
|
||||
|
||||
//! get indexes of the three vertices (V1,V2,V3)
|
||||
Standard_EXPORT void GetVertex (Standard_Integer& V1, Standard_Integer& V2, Standard_Integer& V3) const;
|
||||
|
||||
//! set indexes of the three vertices (V1,V2,V3)
|
||||
//! Raised if V1, V2 or V3 is lower than zero
|
||||
Standard_EXPORT void SetVertex (const Standard_Integer V1, const Standard_Integer V2, const Standard_Integer V3);
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(StlMesh_MeshTriangle,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Standard_Integer MyV1;
|
||||
Standard_Integer MyV2;
|
||||
Standard_Integer MyV3;
|
||||
Standard_Real MyXn;
|
||||
Standard_Real MyYn;
|
||||
Standard_Real MyZn;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlMesh_MeshTriangle_HeaderFile
|
26
src/StlMesh/StlMesh_SequenceOfMesh.hxx
Normal file
26
src/StlMesh/StlMesh_SequenceOfMesh.hxx
Normal file
@@ -0,0 +1,26 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef StlMesh_SequenceOfMesh_HeaderFile
|
||||
#define StlMesh_SequenceOfMesh_HeaderFile
|
||||
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
typedef NCollection_Sequence<Handle(StlMesh_Mesh)> StlMesh_SequenceOfMesh;
|
||||
|
||||
|
||||
#endif
|
26
src/StlMesh/StlMesh_SequenceOfMeshDomain.hxx
Normal file
26
src/StlMesh/StlMesh_SequenceOfMeshDomain.hxx
Normal file
@@ -0,0 +1,26 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef StlMesh_SequenceOfMeshDomain_HeaderFile
|
||||
#define StlMesh_SequenceOfMeshDomain_HeaderFile
|
||||
|
||||
#include <StlMesh_MeshDomain.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
typedef NCollection_Sequence<Handle(StlMesh_MeshDomain)> StlMesh_SequenceOfMeshDomain;
|
||||
|
||||
|
||||
#endif
|
26
src/StlMesh/StlMesh_SequenceOfMeshTriangle.hxx
Normal file
26
src/StlMesh/StlMesh_SequenceOfMeshTriangle.hxx
Normal file
@@ -0,0 +1,26 @@
|
||||
// Created on: 1995-09-21
|
||||
// Created by: Philippe GIRODENGO
|
||||
// Copyright (c) 1995-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef StlMesh_SequenceOfMeshTriangle_HeaderFile
|
||||
#define StlMesh_SequenceOfMeshTriangle_HeaderFile
|
||||
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
#include <NCollection_Sequence.hxx>
|
||||
|
||||
typedef NCollection_Sequence<Handle(StlMesh_MeshTriangle)> StlMesh_SequenceOfMeshTriangle;
|
||||
|
||||
|
||||
#endif
|
2
src/StlTransfer/FILES
Normal file
2
src/StlTransfer/FILES
Normal file
@@ -0,0 +1,2 @@
|
||||
StlTransfer.cxx
|
||||
StlTransfer.hxx
|
187
src/StlTransfer/StlTransfer.cxx
Normal file
187
src/StlTransfer/StlTransfer.cxx
Normal file
@@ -0,0 +1,187 @@
|
||||
// Created on: 2000-06-23
|
||||
// Created by: Sergey MOZOKHIN
|
||||
// Copyright (c) 2000-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
//=======================================================================
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <CSLib.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <Poly_Connect.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlTransfer.hxx>
|
||||
#include <TColgp_Array1OfDir.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <TopAbs.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
//function computes normals for surface
|
||||
static void Normal(const TopoDS_Face& aFace,
|
||||
Poly_Connect& pc,
|
||||
TColgp_Array1OfDir& Nor)
|
||||
{
|
||||
const Handle(Poly_Triangulation)& T = pc.Triangulation();
|
||||
BRepAdaptor_Surface S;
|
||||
Standard_Boolean hasUV = T->HasUVNodes();
|
||||
Standard_Integer i;
|
||||
TopLoc_Location l;
|
||||
Handle(Geom_Surface) GS = BRep_Tool::Surface(aFace, l);
|
||||
|
||||
if (hasUV && !GS.IsNull()) {
|
||||
Standard_Boolean OK = Standard_True;
|
||||
gp_Vec D1U,D1V;
|
||||
gp_Vec D2U,D2V,D2UV;
|
||||
gp_Pnt P;
|
||||
Standard_Real U, V;
|
||||
CSLib_DerivativeStatus aStatus;
|
||||
CSLib_NormalStatus NStat;
|
||||
S.Initialize(aFace, Standard_False);
|
||||
const TColgp_Array1OfPnt2d& UVNodes = T->UVNodes();
|
||||
if (S.GetType() != GeomAbs_Plane) {
|
||||
for (i = UVNodes.Lower(); i <= UVNodes.Upper(); i++) {
|
||||
U = UVNodes(i).X();
|
||||
V = UVNodes(i).Y();
|
||||
S.D1(U,V,P,D1U,D1V);
|
||||
CSLib::Normal (D1U, D1V, Precision::Angular(), aStatus, Nor (i));
|
||||
if (aStatus != CSLib_Done) {
|
||||
S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
|
||||
CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,Nor(i));
|
||||
}
|
||||
if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
|
||||
}
|
||||
}
|
||||
else {
|
||||
gp_Dir NPlane;
|
||||
U = UVNodes(UVNodes.Lower()).X();
|
||||
V = UVNodes(UVNodes.Lower()).Y();
|
||||
S.D1(U,V,P,D1U,D1V);
|
||||
CSLib::Normal (D1U, D1V, Precision::Angular(), aStatus, NPlane);
|
||||
if (aStatus != CSLib_Done) {
|
||||
S.D2(U,V,P,D1U,D1V,D2U,D2V,D2UV);
|
||||
CSLib::Normal(D1U,D1V,D2U,D2V,D2UV,Precision::Angular(),OK,NStat,NPlane);
|
||||
}
|
||||
if (aFace.Orientation() == TopAbs_REVERSED) NPlane.Reverse();
|
||||
Nor.Init(NPlane);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
const TColgp_Array1OfPnt& Nodes = T->Nodes();
|
||||
Standard_Integer n[3];
|
||||
const Poly_Array1OfTriangle& triangles = T->Triangles();
|
||||
|
||||
for (i = Nodes.Lower(); i <= Nodes.Upper(); i++) {
|
||||
gp_XYZ eqPlan(0, 0, 0);
|
||||
for (pc.Initialize(i); pc.More(); pc.Next()) {
|
||||
triangles(pc.Value()).Get(n[0], n[1], n[2]);
|
||||
gp_XYZ v1(Nodes(n[1]).Coord()-Nodes(n[0]).Coord());
|
||||
gp_XYZ v2(Nodes(n[2]).Coord()-Nodes(n[1]).Coord());
|
||||
eqPlan += (v1^v2).Normalized();
|
||||
}
|
||||
Nor(i) = gp_Dir(eqPlan);
|
||||
if (aFace.Orientation() == TopAbs_REVERSED) (Nor(i)).Reverse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void StlTransfer::RetrieveMesh (const TopoDS_Shape& Shape,
|
||||
const Handle(StlMesh_Mesh)& Mesh)
|
||||
{
|
||||
for (TopExp_Explorer itf(Shape,TopAbs_FACE); itf.More(); itf.Next()) {
|
||||
TopoDS_Face face = TopoDS::Face(itf.Current());
|
||||
TopLoc_Location Loc, loc;
|
||||
Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, Loc);
|
||||
if (theTriangulation.IsNull()) continue; //Meshing was not done for this face!
|
||||
Poly_Array1OfTriangle theTriangles(1,theTriangulation->NbTriangles());
|
||||
theTriangles.Assign(theTriangulation->Triangles());
|
||||
Mesh->AddDomain (theTriangulation->Deflection());
|
||||
|
||||
TColgp_Array1OfPnt thePoints(1, theTriangulation->NbNodes());
|
||||
thePoints.Assign(theTriangulation->Nodes());
|
||||
//compute normal of face
|
||||
const TColgp_Array1OfPnt& Nodes = theTriangulation->Nodes();
|
||||
TColgp_Array1OfDir NORMAL(Nodes.Lower(), Nodes.Upper());
|
||||
Poly_Connect pc(theTriangulation);
|
||||
Normal(face, pc, NORMAL);
|
||||
Standard_Integer i;
|
||||
for(i=1;i<=thePoints.Length();i++) {
|
||||
Standard_Real X1, Y1, Z1;
|
||||
gp_Pnt p = thePoints.Value(i);
|
||||
p.Transform(Loc.Transformation());
|
||||
p.Coord (X1, Y1, Z1);
|
||||
Mesh->AddVertex (X1, Y1, Z1);
|
||||
}
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
for (i=1;i<=theTriangles.Length();i++) {
|
||||
Standard_Integer V1, V2, V3;
|
||||
Poly_Triangle triangle = theTriangles.Value(i);
|
||||
triangle.Get(V1, V2, V3);
|
||||
gp_Pnt P1, P2, P3;
|
||||
P1 = Mesh->Vertices(Mesh->NbDomains()).Value(V1);
|
||||
P2 = Mesh->Vertices(Mesh->NbDomains()).Value(V2);
|
||||
P3 = Mesh->Vertices(Mesh->NbDomains()).Value(V3);
|
||||
gp_Vec average = NORMAL(V1);;
|
||||
|
||||
//check angle between vectors
|
||||
gp_Vec V1V2(P1, P2), V2V3(P2, P3);
|
||||
Standard_Integer A,B,C;
|
||||
gp_Vec vec = V1V2^V2V3;
|
||||
Standard_Real modul1, modul2;
|
||||
modul1 = average.XYZ().Modulus();
|
||||
modul2 = vec.XYZ().Modulus();
|
||||
if (modul2>Precision::Confusion ()) vec.Divide(modul2);
|
||||
A=V1;B=V2;C=V3;
|
||||
// vec.Transform(loc);
|
||||
if (modul1>Precision::Confusion () && modul2>Precision::Confusion ()) {
|
||||
Standard_Real an = vec.Angle(average);
|
||||
if ( an > M_PI/2) {
|
||||
A = V3;B=V2;C=V1;
|
||||
}
|
||||
else {
|
||||
A=V1;B=V2;C=V3;
|
||||
}
|
||||
}
|
||||
Mesh->AddTriangle (A, B, C, average.X(), average.Y(), average.Z());
|
||||
}
|
||||
}
|
||||
catch(Standard_Failure)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "Fail in StlTransfer::BuildIncrementalMesh" << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
66
src/StlTransfer/StlTransfer.hxx
Normal file
66
src/StlTransfer/StlTransfer.hxx
Normal file
@@ -0,0 +1,66 @@
|
||||
// Created on: 1994-11-14
|
||||
// Created by: Jean Claude VAUTHIER
|
||||
// Copyright (c) 1994-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _StlTransfer_HeaderFile
|
||||
#define _StlTransfer_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class StlMesh_Mesh;
|
||||
|
||||
|
||||
//! The package Algorithm for Meshing implements
|
||||
//! facilities to retrieve the Mesh data-structure from a shape of package
|
||||
//! TopoDS. The triangulation should be computed before.
|
||||
//! The result is stored in the mesh
|
||||
//! data-structure Mesh from package StlMesh.
|
||||
class StlTransfer
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! Retrieve a Mesh data-structure from the Shape, convert and store it into the Mesh.
|
||||
Standard_EXPORT static void RetrieveMesh (const TopoDS_Shape& Shape, const Handle(StlMesh_Mesh)& Mesh);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _StlTransfer_HeaderFile
|
@@ -1,2 +1,4 @@
|
||||
StlMesh
|
||||
StlAPI
|
||||
StlTransfer
|
||||
RWStl
|
||||
|
@@ -16,4 +16,3 @@ CSF_Appkit
|
||||
CSF_IOKit
|
||||
CSF_FreeImagePlus
|
||||
CSF_FREETYPE
|
||||
CSF_FFmpeg
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include <AIS_ListOfInteractive.hxx>
|
||||
#include <AIS_ListIteratorOfListOfInteractive.hxx>
|
||||
#include <DBRep.hxx>
|
||||
#include <Draw_ProgressIndicator.hxx>
|
||||
#include <Graphic3d_ArrayOfPolylines.hxx>
|
||||
#include <Graphic3d_AspectMarker3d.hxx>
|
||||
#include <Graphic3d_ExportFormat.hxx>
|
||||
@@ -47,7 +46,6 @@
|
||||
#include <V3d_DirectionalLight.hxx>
|
||||
#include <V3d_PositionalLight.hxx>
|
||||
#include <V3d_SpotLight.hxx>
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_DoubleMap.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
@@ -56,7 +54,6 @@
|
||||
#include <Draw.hxx>
|
||||
#include <Draw_Appli.hxx>
|
||||
#include <Image_AlienPixMap.hxx>
|
||||
#include <Image_VideoRecorder.hxx>
|
||||
#include <OpenGl_GraphicDriver.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <TColStd_HSequenceOfAsciiString.hxx>
|
||||
@@ -6265,48 +6262,6 @@ namespace
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//! Auxiliary class for flipping image upside-down.
|
||||
class ImageFlipper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Empty constructor.
|
||||
ImageFlipper() : myTmp (NCollection_BaseAllocator::CommonBaseAllocator()) {}
|
||||
|
||||
//! Perform flipping.
|
||||
Standard_Boolean FlipY (Image_PixMap& theImage)
|
||||
{
|
||||
if (theImage.IsEmpty()
|
||||
|| theImage.SizeX() == 0
|
||||
|| theImage.SizeY() == 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
const Standard_Size aRowSize = theImage.SizeRowBytes();
|
||||
if (myTmp.Size() < aRowSize
|
||||
&& !myTmp.Allocate (aRowSize))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// for odd height middle row should be left as is
|
||||
Standard_Size aNbRowsHalf = theImage.SizeY() / 2;
|
||||
for (Standard_Size aRowT = 0, aRowB = theImage.SizeY() - 1; aRowT < aNbRowsHalf; ++aRowT, --aRowB)
|
||||
{
|
||||
Standard_Byte* aTop = theImage.ChangeRow (aRowT);
|
||||
Standard_Byte* aBot = theImage.ChangeRow (aRowB);
|
||||
memcpy (myTmp.ChangeData(), aTop, aRowSize);
|
||||
memcpy (aTop, aBot, aRowSize);
|
||||
memcpy (aBot, myTmp.Data(), aRowSize);
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
private:
|
||||
NCollection_Buffer myTmp;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -6635,13 +6590,10 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
Standard_Real aPlaySpeed = 1.0;
|
||||
Standard_Real aPlayStartTime = anAnimation->StartPts();
|
||||
Standard_Real aPlayDuration = anAnimation->Duration();
|
||||
Standard_Integer aFpsNum = 0;
|
||||
Standard_Integer aFpsDen = 1;
|
||||
Standard_Boolean isFreeCamera = Standard_False;
|
||||
Standard_Boolean isLockLoop = Standard_False;
|
||||
|
||||
// video recording parameters
|
||||
TCollection_AsciiString aRecFile;
|
||||
Image_VideoParams aRecParams;
|
||||
|
||||
Handle(V3d_View) aView = ViewerTest::CurrentView();
|
||||
for (; anArgIter < theArgNb; ++anArgIter)
|
||||
{
|
||||
@@ -6727,37 +6679,6 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
{
|
||||
isFreeCamera = Standard_True;
|
||||
}
|
||||
// video recodring options
|
||||
else if (anArg == "-rec"
|
||||
|| anArg == "-record")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
aRecFile = theArgVec[anArgIter];
|
||||
if (aRecParams.FpsNum <= 0)
|
||||
{
|
||||
aRecParams.FpsNum = 24;
|
||||
}
|
||||
|
||||
if (anArgIter + 2 < theArgNb
|
||||
&& *theArgVec[anArgIter + 1] != '-'
|
||||
&& *theArgVec[anArgIter + 2] != '-')
|
||||
{
|
||||
TCollection_AsciiString aWidthArg (theArgVec[anArgIter + 1]);
|
||||
TCollection_AsciiString aHeightArg (theArgVec[anArgIter + 2]);
|
||||
if (aWidthArg .IsIntegerValue()
|
||||
&& aHeightArg.IsIntegerValue())
|
||||
{
|
||||
aRecParams.Width = aWidthArg .IntegerValue();
|
||||
aRecParams.Height = aHeightArg.IntegerValue();
|
||||
anArgIter += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (anArg == "-fps")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
@@ -6770,66 +6691,22 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
Standard_Integer aSplitIndex = aFpsArg.FirstLocationInSet ("/", 1, aFpsArg.Length());
|
||||
if (aSplitIndex == 0)
|
||||
{
|
||||
aRecParams.FpsNum = aFpsArg.IntegerValue();
|
||||
aFpsNum = aFpsArg.IntegerValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
const TCollection_AsciiString aDenStr = aFpsArg.Split (aSplitIndex);
|
||||
aFpsArg.Split (aFpsArg.Length() - 1);
|
||||
const TCollection_AsciiString aNumStr = aFpsArg;
|
||||
aRecParams.FpsNum = aNumStr.IntegerValue();
|
||||
aRecParams.FpsDen = aDenStr.IntegerValue();
|
||||
if (aRecParams.FpsDen < 1)
|
||||
aFpsNum = aNumStr.IntegerValue();
|
||||
aFpsDen = aDenStr.IntegerValue();
|
||||
if (aFpsDen < 1)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (anArg == "-format")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
aRecParams.Format = theArgVec[anArgIter];
|
||||
}
|
||||
else if (anArg == "-pix_fmt"
|
||||
|| anArg == "-pixfmt"
|
||||
|| anArg == "-pixelformat")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
aRecParams.PixelFormat = theArgVec[anArgIter];
|
||||
}
|
||||
else if (anArg == "-codec"
|
||||
|| anArg == "-vcodec"
|
||||
|| anArg == "-videocodec")
|
||||
{
|
||||
if (++anArgIter >= theArgNb)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
aRecParams.VideoCodec = theArgVec[anArgIter];
|
||||
}
|
||||
else if (anArg == "-crf"
|
||||
|| anArg == "-preset"
|
||||
|| anArg == "-qp")
|
||||
{
|
||||
const TCollection_AsciiString aParamName = anArg.SubString (2, anArg.Length());
|
||||
if (++anArgIter >= theArgNb)
|
||||
{
|
||||
std::cout << "Syntax error at " << anArg << ".\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
aRecParams.VideoCodecParams.Bind (aParamName, theArgVec[anArgIter]);
|
||||
}
|
||||
// animation definition options
|
||||
else if (anArg == "-start"
|
||||
|| anArg == "-starttime"
|
||||
@@ -7081,7 +6958,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
}
|
||||
}
|
||||
|
||||
if (!toPlay && aRecFile.IsEmpty())
|
||||
if (!toPlay)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -7097,7 +6974,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
}
|
||||
|
||||
const Standard_Real anUpperPts = aPlayStartTime + aPlayDuration;
|
||||
if (aRecParams.FpsNum <= 0)
|
||||
if (aFpsNum <= 0)
|
||||
{
|
||||
while (!anAnimation->IsStopped())
|
||||
{
|
||||
@@ -7151,35 +7028,12 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
OSD_Timer aPerfTimer;
|
||||
aPerfTimer.Start();
|
||||
|
||||
Handle(Image_VideoRecorder) aRecorder;
|
||||
ImageFlipper aFlipper;
|
||||
Handle(Draw_ProgressIndicator) aProgress;
|
||||
if (!aRecFile.IsEmpty())
|
||||
{
|
||||
if (aRecParams.Width <= 0
|
||||
|| aRecParams.Height <= 0)
|
||||
{
|
||||
aView->Window()->Size (aRecParams.Width, aRecParams.Height);
|
||||
}
|
||||
|
||||
aRecorder = new Image_VideoRecorder();
|
||||
if (!aRecorder->Open (aRecFile.ToCString(), aRecParams))
|
||||
{
|
||||
std::cout << "Error: failed to open video file for recording\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
aProgress = new Draw_ProgressIndicator (theDI, 1);
|
||||
}
|
||||
|
||||
// Manage frame-rated animation here
|
||||
Standard_Real aPts = aPlayStartTime;
|
||||
int64_t aNbFrames = 0;
|
||||
Message_ProgressSentry aPSentry (aProgress, "Video recording, sec", 0, Max (1, Standard_Integer(aPlayDuration / aPlaySpeed)), 1);
|
||||
Standard_Integer aSecondsProgress = 0;
|
||||
for (; aPts <= anUpperPts && aPSentry.More();)
|
||||
for (; aPts <= anUpperPts;)
|
||||
{
|
||||
const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aRecParams.FpsDen) / Standard_Real(aRecParams.FpsNum)) * Standard_Real(aNbFrames));
|
||||
const Standard_Real aRecPts = aPlaySpeed * ((Standard_Real(aFpsDen) / Standard_Real(aFpsNum)) * Standard_Real(aNbFrames));
|
||||
aPts = aPlayStartTime + aRecPts;
|
||||
++aNbFrames;
|
||||
if (!anAnimation->Update (aPts))
|
||||
@@ -7187,35 +7041,7 @@ static Standard_Integer VAnimation (Draw_Interpretor& theDI,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!aRecorder.IsNull())
|
||||
{
|
||||
V3d_ImageDumpOptions aDumpParams;
|
||||
aDumpParams.Width = aRecParams.Width;
|
||||
aDumpParams.Height = aRecParams.Height;
|
||||
aDumpParams.BufferType = Graphic3d_BT_RGBA;
|
||||
aDumpParams.StereoOptions = V3d_SDO_MONO;
|
||||
aDumpParams.ToAdjustAspect = Standard_True;
|
||||
if (!aView->ToPixMap (aRecorder->ChangeFrame(), aDumpParams))
|
||||
{
|
||||
std::cout << "Error: view dump is failed!\n";
|
||||
return 0;
|
||||
}
|
||||
aFlipper.FlipY (aRecorder->ChangeFrame());
|
||||
if (!aRecorder->PushFrame())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aView->Redraw();
|
||||
}
|
||||
|
||||
while (aSecondsProgress < Standard_Integer(aRecPts / aPlaySpeed))
|
||||
{
|
||||
aPSentry.Next();
|
||||
++aSecondsProgress;
|
||||
}
|
||||
aView->Redraw();
|
||||
}
|
||||
|
||||
aPerfTimer.Stop();
|
||||
@@ -11346,17 +11172,6 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
|
||||
"\n\t\t: %Pts overall animation presentation timestamp"
|
||||
"\n\t\t: %LocalPts local animation timestamp"
|
||||
"\n\t\t: %Normalized local animation normalized value in range 0..1"
|
||||
"\n\t\t:"
|
||||
"\n\t\t: Video recording:"
|
||||
"\n\t\t: vanim name -record FileName [Width Height] [-fps FrameRate=24]"
|
||||
"\n\t\t: [-format Format] [-vcodec Codec] [-pix_fmt PixelFormat]"
|
||||
"\n\t\t: [-crf Value] [-preset Preset]"
|
||||
"\n\t\t: -fps video framerate"
|
||||
"\n\t\t: -format file format, container (matroska, etc.)"
|
||||
"\n\t\t: -vcodec video codec identifier (ffv1, mjpeg, etc.)"
|
||||
"\n\t\t: -pix_fmt image pixel format (yuv420p, rgb24, etc.)"
|
||||
"\n\t\t: -crf constant rate factor (specific to codec)"
|
||||
"\n\t\t: -preset codec parameters preset (specific to codec)"
|
||||
__FILE__, VAnimation, group);
|
||||
|
||||
theCommands.Add("vchangeselected",
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include <AIS_InteractiveContext.hxx>
|
||||
#include <Aspect_TypeOfMarker.hxx>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <DBRep.hxx>
|
||||
#include <Draw.hxx>
|
||||
#include <Draw_Interpretor.hxx>
|
||||
@@ -46,12 +45,13 @@
|
||||
#include <StdSelect_ViewerSelector3d.hxx>
|
||||
#include <StlAPI.hxx>
|
||||
#include <StlAPI_Writer.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_HPackedMapOfInteger.hxx>
|
||||
#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <V3d_View.hxx>
|
||||
#include <ViewerTest.hxx>
|
||||
@@ -90,50 +90,27 @@ static Standard_Integer writestl
|
||||
}
|
||||
StlAPI_Writer aWriter;
|
||||
aWriter.ASCIIMode() = isASCIIMode;
|
||||
Standard_Boolean isOK = aWriter.Write (aShape, argv[2]);
|
||||
if (!isOK)
|
||||
di << "** Error **: Mesh writing has been failed.\n";
|
||||
StlAPI_ErrorStatus aStatus = aWriter.Write (aShape, argv[2]);
|
||||
|
||||
switch (aStatus)
|
||||
{
|
||||
case StlAPI_MeshIsEmpty: di << "** Error **: Mesh is empty. Please, compute triangulation before."; break;
|
||||
case StlAPI_CannotOpenFile: di << "** Error **: Cannot create/open a file with the passed name."; break;
|
||||
case StlAPI_StatusOK: default: break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//function : readstl
|
||||
//purpose : Reads stl file
|
||||
//=============================================================================
|
||||
static Standard_Integer readstl(Draw_Interpretor& theDI,
|
||||
Standard_Integer theArgc,
|
||||
const char** theArgv)
|
||||
static Standard_Integer readstl
|
||||
(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
||||
{
|
||||
if (theArgc < 3)
|
||||
{
|
||||
theDI << "wrong number of parameters" << "\n";
|
||||
return 1;
|
||||
if (argc<3) di << "wrong number of parameters" << "\n";
|
||||
else {
|
||||
TopoDS_Shape aShape ;
|
||||
StlAPI::Read(aShape,argv[2]);
|
||||
DBRep::Set(argv[1],aShape);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (theArgc == 4 &&
|
||||
strcmp("triangulation", theArgv[3]) == 0)
|
||||
{
|
||||
// Read STL file to the triangulation.
|
||||
Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (theArgv[2]);
|
||||
|
||||
TopoDS_Face aFace;
|
||||
BRep_Builder aB;
|
||||
aB.MakeFace(aFace);
|
||||
aB.UpdateFace(aFace, aTriangulation);
|
||||
DBRep::Set(theArgv[1], aFace);
|
||||
}
|
||||
else
|
||||
{
|
||||
TopoDS_Shape aShape;
|
||||
Standard_DISABLE_DEPRECATION_WARNINGS
|
||||
StlAPI::Read(aShape, theArgv[2]);
|
||||
Standard_ENABLE_DEPRECATION_WARNINGS
|
||||
DBRep::Set(theArgv[1], aShape);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -283,7 +260,7 @@ static Standard_Integer createmesh
|
||||
// Progress indicator
|
||||
OSD_Path aFile( argv[2] );
|
||||
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
|
||||
Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
|
||||
Handle(StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
|
||||
|
||||
di << "Reading OK...\n";
|
||||
Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
|
||||
@@ -298,7 +275,7 @@ static Standard_Integer createmesh
|
||||
|
||||
// Hide all nodes by default
|
||||
Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
|
||||
Standard_Integer aLen = aSTLMesh->Nodes().Length();
|
||||
Standard_Integer aLen = aSTLMesh->Vertices().Length();
|
||||
for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
|
||||
aNodes->ChangeMap().Add( anIndex );
|
||||
aMesh->SetHiddenNodes( aNodes );
|
||||
@@ -1246,7 +1223,7 @@ void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
|
||||
|
||||
theCommands.Add ("writevrml", "shape file [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 1 by default]",__FILE__,writevrml,g);
|
||||
theCommands.Add ("writestl", "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
|
||||
theCommands.Add ("readstl", "shape file [triangulation: no by default]",__FILE__,readstl,g);
|
||||
theCommands.Add ("readstl", "shape file",__FILE__,readstl,g);
|
||||
theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
|
||||
|
||||
theCommands.Add ("meshfromstl", "creates MeshVS_Mesh from STL file", __FILE__, createmesh, g );
|
||||
|
@@ -13,13 +13,15 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <XSDRAWSTLVRML_DataSource.hxx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <StlMesh_Mesh.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <TColStd_DataMapOfIntegerInteger.hxx>
|
||||
#include <TColStd_DataMapOfIntegerReal.hxx>
|
||||
#include <XSDRAWSTLVRML_DataSource.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(XSDRAWSTLVRML_DataSource,MeshVS_DataSource)
|
||||
|
||||
@@ -27,13 +29,13 @@ IMPLEMENT_STANDARD_RTTIEXT(XSDRAWSTLVRML_DataSource,MeshVS_DataSource)
|
||||
// Function : Constructor
|
||||
// Purpose :
|
||||
//================================================================
|
||||
XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource (const Handle(Poly_Triangulation)& aMesh)
|
||||
XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource( const Handle( StlMesh_Mesh )& aMesh )
|
||||
{
|
||||
myMesh = aMesh;
|
||||
|
||||
if( !myMesh.IsNull() )
|
||||
{
|
||||
const TColgp_Array1OfPnt& aCoords = myMesh->Nodes();
|
||||
const TColgp_SequenceOfXYZ& aCoords = myMesh->Vertices();
|
||||
Standard_Integer len = aCoords.Length(), i, j;
|
||||
myNodeCoords = new TColStd_HArray2OfReal(1, len, 1, 3);
|
||||
cout << "Nodes : " << len << endl;
|
||||
@@ -43,14 +45,14 @@ XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource (const Handle(Poly_Triangulat
|
||||
for( i = 1; i <= len; i++ )
|
||||
{
|
||||
myNodes.Add( i );
|
||||
xyz = aCoords(i).XYZ();
|
||||
xyz = aCoords(i);
|
||||
|
||||
myNodeCoords->SetValue(i, 1, xyz.X());
|
||||
myNodeCoords->SetValue(i, 2, xyz.Y());
|
||||
myNodeCoords->SetValue(i, 3, xyz.Z());
|
||||
}
|
||||
|
||||
const Poly_Array1OfTriangle& aSeq = myMesh->Triangles();
|
||||
const StlMesh_SequenceOfMeshTriangle& aSeq = myMesh->Triangles();
|
||||
len = aSeq.Length();
|
||||
myElemNormals = new TColStd_HArray2OfReal(1, len, 1, 3);
|
||||
myElemNodes = new TColStd_HArray2OfInteger(1, len, 1, 3);
|
||||
@@ -60,33 +62,19 @@ XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource (const Handle(Poly_Triangulat
|
||||
for( i = 1; i <= len; i++ )
|
||||
{
|
||||
myElements.Add( i );
|
||||
Handle( StlMesh_MeshTriangle ) aTriangle = aSeq.Value( i );
|
||||
Standard_Integer V[3]; Standard_Real nx, ny, nz;
|
||||
|
||||
const Poly_Triangle& aTri = aSeq(i);
|
||||
|
||||
Standard_Integer V[3];
|
||||
aTri.Get (V[0], V[1], V[2]);
|
||||
|
||||
const gp_Pnt aP1 = aCoords (V[0]);
|
||||
const gp_Pnt aP2 = aCoords (V[1]);
|
||||
const gp_Pnt aP3 = aCoords (V[2]);
|
||||
|
||||
gp_Vec aV1(aP1, aP2);
|
||||
gp_Vec aV2(aP2, aP3);
|
||||
|
||||
gp_Vec aN = aV1.Crossed(aV2);
|
||||
if (aN.SquareMagnitude() > Precision::SquareConfusion())
|
||||
aN.Normalize();
|
||||
else
|
||||
aN.SetCoord(0.0, 0.0, 0.0);
|
||||
aTriangle->GetVertexAndOrientation( V[0], V[1], V[2], nx, ny, nz );
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
myElemNodes->SetValue(i, j+1, V[j]);
|
||||
}
|
||||
|
||||
myElemNormals->SetValue (i, 1, aN.X());
|
||||
myElemNormals->SetValue (i, 2, aN.Y());
|
||||
myElemNormals->SetValue (i, 3, aN.Z());
|
||||
myElemNormals->SetValue(i, 1, nx);
|
||||
myElemNormals->SetValue(i, 2, ny);
|
||||
myElemNormals->SetValue(i, 3, nz);
|
||||
}
|
||||
}
|
||||
cout << "Construction is finished" << endl;
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include <Standard_Address.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
class StlMesh_Mesh;
|
||||
|
||||
|
||||
class XSDRAWSTLVRML_DataSource;
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
|
||||
//! Constructor
|
||||
Standard_EXPORT XSDRAWSTLVRML_DataSource(const Handle(Poly_Triangulation)& aMesh);
|
||||
Standard_EXPORT XSDRAWSTLVRML_DataSource(const Handle(StlMesh_Mesh)& aMesh);
|
||||
|
||||
//! Returns geometry information about node ( if IsElement is False ) or element ( IsElement is True )
|
||||
//! by co-ordinates. For element this method must return all its nodes co-ordinates in the strict order: X, Y, Z and
|
||||
@@ -85,7 +85,7 @@ protected:
|
||||
private:
|
||||
|
||||
|
||||
Handle(Poly_Triangulation) myMesh;
|
||||
Handle(StlMesh_Mesh) myMesh;
|
||||
TColStd_PackedMapOfInteger myNodes;
|
||||
TColStd_PackedMapOfInteger myElements;
|
||||
Handle(TColStd_HArray2OfInteger) myElemNodes;
|
||||
|
@@ -15,6 +15,8 @@
|
||||
|
||||
|
||||
#include <Standard_Type.hxx>
|
||||
#include <StlMesh_MeshTriangle.hxx>
|
||||
#include <StlMesh_SequenceOfMeshTriangle.hxx>
|
||||
#include <TColgp_SequenceOfXYZ.hxx>
|
||||
#include <TColStd_DataMapOfIntegerInteger.hxx>
|
||||
#include <TColStd_DataMapOfIntegerReal.hxx>
|
||||
|
@@ -1,28 +0,0 @@
|
||||
puts "TODO OCC24909 ALL: Tcl Exception: Buildsweep : Not Done"
|
||||
|
||||
puts "TODO OCC24909 ALL: An exception was caught"
|
||||
puts "TODO OCC24909 ALL: \\*\\* Exception \\*\\*.*"
|
||||
|
||||
puts "TODO OCC24909 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC24909"
|
||||
puts "========"
|
||||
puts ""
|
||||
##################################
|
||||
# 0024909: SIGSEGV in buildsweep
|
||||
##################################
|
||||
|
||||
restore [locate_data_file bug24909_sweep3-draw-Sweep-0-spine.brep] Sweep-0-spine
|
||||
|
||||
mksweep Sweep-0-spine
|
||||
setsweep -CF
|
||||
|
||||
restore [locate_data_file bug24909_sweep3-draw-Sweep-0-section-00-Sketch.brep] Sweep-0-section-00-Sketch
|
||||
|
||||
addsweep Sweep-0-section-00-Sketch
|
||||
|
||||
restore [locate_data_file bug24909_sweep3-draw-Sweep-0-section-01-Sketch001.brep] Sweep-0-section-01-Sketch001
|
||||
addsweep Sweep-0-section-01-Sketch001
|
||||
|
||||
buildsweep Sweep
|
@@ -1,31 +0,0 @@
|
||||
puts "TODO OCC24909 ALL: Tcl Exception: Buildsweep : Not Done"
|
||||
|
||||
puts "TODO OCC24909 ALL: An exception was caught"
|
||||
puts "TODO OCC24909 ALL: \\*\\* Exception \\*\\*.*"
|
||||
|
||||
puts "TODO OCC24909 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC24909"
|
||||
puts "========"
|
||||
puts ""
|
||||
##################################
|
||||
# 0024909: SIGSEGV in buildsweep
|
||||
##################################
|
||||
|
||||
circle c1 0 0 0 40
|
||||
mkedge e1 c1
|
||||
wire w1 e1
|
||||
tcopy w1 Sketch002
|
||||
tcopy w1 Sketch001
|
||||
renamevar w1 Sketch
|
||||
trotate Sketch 0 0 0 0. 1. 0. 90
|
||||
ttranslate Sketch 0. 0. 75.
|
||||
trotate Sketch001 0 0 0 0. 1. 0. 90
|
||||
ttranslate Sketch001 0. 0. -75.
|
||||
ttranslate Sketch002 50. 0. 0.
|
||||
mksweep Sketch002
|
||||
setsweep -CF
|
||||
addsweep Sketch001
|
||||
addsweep Sketch
|
||||
buildsweep Sweep
|
@@ -1,32 +0,0 @@
|
||||
puts "TODO OCC24909 ALL: Tcl Exception: Buildsweep : Not Done"
|
||||
puts "TODO OCC24909 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC24909"
|
||||
puts "========"
|
||||
puts ""
|
||||
##################################
|
||||
# 0024909: SIGSEGV in buildsweep
|
||||
##################################
|
||||
|
||||
restore [locate_data_file bug24909_minihyd-draw-BezCurve.brep] BezCurve
|
||||
|
||||
ttranslate BezCurve 0 -8 0
|
||||
explode BezCurve E
|
||||
wire Sweep001-0-spine BezCurve_1
|
||||
mksweep Sweep001-0-spine
|
||||
setsweep -CF
|
||||
circle Circle-curve 0 0 0 18
|
||||
mkedge Circle-edge Circle-curve 0 0
|
||||
wire Circle Circle-edge
|
||||
trotate Circle 0 0 0 0.577350269189625731 0.577350269189625731 0.577350269189625731 120
|
||||
ttranslate Circle 0 -71 203.5
|
||||
addsweep Circle
|
||||
circle Circle001-curve 0 0 0 16
|
||||
mkedge Circle001-edge Circle001-curve 0 0
|
||||
wire Circle001 Circle001-edge
|
||||
trotate Circle001 0 0 0 0.577350269189625731 0.577350269189625731 0.577350269189625731 120
|
||||
ttranslate Circle001 0 -71 203.5
|
||||
addsweep Circle001
|
||||
|
||||
buildsweep Sweep001 -C -S
|
@@ -1,15 +0,0 @@
|
||||
puts "TODO OCC24997 ALL: An exception was caught"
|
||||
puts "TODO OCC24997 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC24997 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC24997"
|
||||
puts "========"
|
||||
puts ""
|
||||
#########################################
|
||||
# SIGSEGV in BRepOffsetAPI_ThruSections
|
||||
#########################################
|
||||
|
||||
restore [locate_data_file bug24997_loft3-draw-Loft-00-section.brep] Loft-00-section
|
||||
restore [locate_data_file bug24997_loft3-draw-Loft-01-section.brep] Loft-01-section
|
||||
thrusections Loft 0 0 Loft-00-section Loft-01-section
|
@@ -1,22 +0,0 @@
|
||||
puts "TODO OCC25081 ALL: TEST INCOMPLETE"
|
||||
puts "TODO OCC25081 ALL: Process killed by CPU limit"
|
||||
|
||||
puts "========"
|
||||
puts "OCC25081"
|
||||
puts "========"
|
||||
puts ""
|
||||
############################
|
||||
# bopcheck does not return
|
||||
############################
|
||||
|
||||
cpulimit 1200
|
||||
|
||||
restore [locate_data_file bug25081_v1-sweep-draw-Sweep-0-spine.brep] Sweep-0-spine
|
||||
restore [locate_data_file bug25081_v1-sweep-draw-Sweep-0-section-00-Wire.brep] Sweep-0-section-00-Wire
|
||||
|
||||
mksweep Sweep-0-spine
|
||||
setsweep -FR
|
||||
addsweep Sweep-0-section-00-Wire
|
||||
buildsweep Sweep -C -S
|
||||
|
||||
bopcheck Sweep
|
@@ -1,20 +0,0 @@
|
||||
puts "TODO OCC25110 ALL: An exception was caught"
|
||||
puts "TODO OCC25110 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC25110 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC25110"
|
||||
puts "========"
|
||||
puts ""
|
||||
########################################################################################
|
||||
# TCollection_IndexedDataMap::FindFromKey error when sweeping circle along BezierCurve
|
||||
########################################################################################
|
||||
|
||||
restore [locate_data_file bug25110_unsweepable1-draw-Sweep-0-spine.brep] Sweep-0-spine
|
||||
restore [locate_data_file bug25110_unsweepable1-draw-Sweep-0-section-00-Circle.brep] Sweep-0-section-00-Circle
|
||||
|
||||
mksweep Sweep-0-spine
|
||||
setsweep -CF
|
||||
addsweep Sweep-0-section-00-Circle
|
||||
|
||||
buildsweep Sweep -C -S
|
@@ -1,21 +0,0 @@
|
||||
puts "TODO OCC26030 ALL: An exception was caught"
|
||||
puts "TODO OCC26030 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC26030 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC26030"
|
||||
puts "========"
|
||||
puts ""
|
||||
#################################################
|
||||
# Offset of a lofted body fails after long time
|
||||
#################################################
|
||||
|
||||
restore [locate_data_file bug26030_thickness-crash1-tcl-Loft001-00-section.brep] Loft001-00-section
|
||||
restore [locate_data_file bug26030_thickness-crash1-tcl-Loft001-01-section.brep] Loft001-01-section
|
||||
|
||||
thrusections Loft001 1 0 Loft001-00-section Loft001-01-section
|
||||
explode Loft001 F
|
||||
offsetparameter 1e-7 p i
|
||||
offsetload Loft001 1
|
||||
|
||||
offsetperform Offset
|
@@ -1,16 +0,0 @@
|
||||
puts "TODO OCC26088 ALL: An exception was caught"
|
||||
puts "TODO OCC26088 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC26088 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC26088"
|
||||
puts "========"
|
||||
puts ""
|
||||
###############################
|
||||
# Exception in pipe algorithm
|
||||
###############################
|
||||
|
||||
restore [locate_data_file bug26088_path0.brep] p
|
||||
restore [locate_data_file bug26088_profile0.brep] pr
|
||||
|
||||
pipe result p pr
|
23
tests/bugs/moddata_1/bug1048
Executable file
23
tests/bugs/moddata_1/bug1048
Executable file
@@ -0,0 +1,23 @@
|
||||
puts "================"
|
||||
puts "OCC1048"
|
||||
puts "================"
|
||||
puts ""
|
||||
|
||||
pload QAcommands
|
||||
|
||||
restore [locate_data_file OCC1048.brep] result
|
||||
|
||||
set list [OCC1048 result]
|
||||
|
||||
set NBTRIANGLES 0
|
||||
regexp {Info: +Number +of +triangles += +([-0-9.+eE]+)} $list full NBTRIANGLES
|
||||
|
||||
if { ${NBTRIANGLES} > 0 } {
|
||||
puts "OCC1048: OK"
|
||||
} else {
|
||||
puts "OCC1048: Error"
|
||||
}
|
||||
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
||||
|
||||
|
@@ -1,17 +0,0 @@
|
||||
puts "TODO OCC24621 ALL: An exception was caught"
|
||||
puts "TODO OCC24621 ALL: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC24621 ALL: TEST INCOMPLETE"
|
||||
|
||||
puts "========"
|
||||
puts "OCC24621"
|
||||
puts "========"
|
||||
puts ""
|
||||
##################################################
|
||||
# Failed to build Geom_OffsetSurface on B-Spline
|
||||
##################################################
|
||||
|
||||
restore [locate_data_file bug24621_bs.draw] bs
|
||||
|
||||
offset obs bs -2
|
||||
setunotperiodic bs
|
||||
offset obs bs -2
|
@@ -1,8 +0,0 @@
|
||||
readstl m [locate_data_file bug28680_sample01b.stl] triangulation
|
||||
|
||||
# Number of triangles check
|
||||
checktrinfo m -tri 62075 -nod 31879
|
||||
|
||||
# Visual check
|
||||
checkview -display m -3d -vdispmode 0 -path ${imagedir}/${test_image}_edges.png
|
||||
checkview -display m -3d -vdispmode 1 -path ${imagedir}/${test_image}_shading.png
|
@@ -1,17 +0,0 @@
|
||||
puts "================"
|
||||
puts "OCC25382"
|
||||
puts "================"
|
||||
puts ""
|
||||
puts "==============================================================="
|
||||
puts "Visualization, TKOpenGl - improved video recording capability"
|
||||
puts "==============================================================="
|
||||
|
||||
set aFile ${imagedir}/propeller.mkv
|
||||
file delete -force ${aFile}
|
||||
|
||||
source $env(CSF_OCCTTestsPath)/v3d/anim/propeller
|
||||
vraytrace 1
|
||||
vrenderparams -msaa 8
|
||||
vrenderparams -fsaa 1
|
||||
XProgress +g
|
||||
vanimation anim -play -record ${aFile} 1920 1080 -vcodec ffv1 -fps 30 -speed 0.5
|
Reference in New Issue
Block a user