- add parallel execution on the level of STEPControl_ActorRead. Sendingsimple shapes for healing in parallel;
- add parameter to turn ON/OFF this behavior read.step.parallel.healing, ON by default;
- add jemalloc allocator;
- add CMake option to chose the allocator, jemalloc by default.
endif()
endmacro()
+# set using memory manager option for TKernel
+set (USE_MMGR_TYPE "JEMALLOC" CACHE STRING "Select using memory manager tool.")
+set_property(CACHE USE_MMGR_TYPE PROPERTY STRINGS "NATIVE" "TBB" "JEMALLOC")
+
# include variable description
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/vardescr")
OCCT_CHECK_AND_UNSET ("3RDPARTY_FLEX_EXECUTABLE")
endif()
+# Jemalloc
+if ("${USE_MMGR_TYPE}" STREQUAL "JEMALLOC")
+ OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/jemalloc")
+else()
+ OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_JEMALLOC")
+ OCCT_CHECK_AND_UNSET ("INSTALL_JEMALLOC")
+endif()
+
# qt for inspector and samples
if (BUILD_Inspector OR BUILD_SAMPLES_QT)
# check qt 3rdparty path
--- /dev/null
+# JeMalloc
+
+if (NOT DEFINED INSTALL_JEMALLOC)
+ set (INSTALL_JEMALLOC OFF CACHE BOOL "${INSTALL_INSTALL_JEMALLOC_DESCR}")
+endif()
+
+# include occt macros. compiler_bitness, os_with_bit, compiler
+OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/occt_macros")
+
+# specify JEMALLOC folder in connection with 3RDPARTY_DIR
+if (3RDPARTY_DIR AND EXISTS "${3RDPARTY_DIR}")
+ if (NOT 3RDPARTY_JEMALLOC_DIR OR NOT EXISTS "${3RDPARTY_JEMALLOC_DIR}")
+ FIND_PRODUCT_DIR ("${3RDPARTY_DIR}" jemalloc JEMALLOC_DIR_NAME)
+ if (JEMALLOC_DIR_NAME)
+ set (3RDPARTY_JEMALLOC_DIR "${3RDPARTY_DIR}/${JEMALLOC_DIR_NAME}" CACHE PATH "The directory containing JEMALLOC" FORCE)
+ set (3RDPARTY_JEMALLOC_DIR "${3RDPARTY_DIR}/${JEMALLOC_DIR_NAME}")
+ message(STATUS "Info: JEMALLOC detected in ${3RDPARTY_JEMALLOC_DIR}")
+ endif()
+ endif()
+ else()
+endif()
+
+# define required JEMALLOC variables
+if (NOT DEFINED 3RDPARTY_JEMALLOC_INCLUDE_DIR)
+ set (3RDPARTY_JEMALLOC_INCLUDE_DIR "" CACHE PATH "the path of headers directory")
+endif()
+
+# check 3RDPARTY_${PRODUCT_NAME}_ paths for consistency with specified 3RDPARTY_${PRODUCT_NAME}_DIR
+if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
+ CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_JEMALLOC_DIR 3RDPARTY_JEMALLOC_INCLUDE_DIR PATH "the path to JEMALLOC")
+ CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_JEMALLOC_DIR 3RDPARTY_JEMALLOC_LIBRARY_DIR FILEPATH "The directory containing JEMALLOC libraries")
+endif()
+
+# header
+if (NOT 3RDPARTY_JEMALLOC_INCLUDE_DIR OR NOT EXISTS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
+ set (HEADER_NAMES jemalloc.h)
+
+ # set 3RDPARTY_JEMALLOC_INCLUDE_DIR as notfound, otherwise find_library can't assign a new value to 3RDPARTY_JEMALLOC_INCLUDE_DIR
+ set (3RDPARTY_JEMALLOC_INCLUDE_DIR "3RDPARTY_JEMALLOC_INCLUDE_DIR-NOTFOUND" CACHE FILEPATH "the path to header directory" FORCE)
+
+ if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
+ find_path (3RDPARTY_JEMALLOC_INCLUDE_DIR NAMES ${HEADER_NAMES}
+ PATHS ${3RDPARTY_JEMALLOC_DIR}
+ PATH_SUFFIXES include/jemalloc
+ CMAKE_FIND_ROOT_PATH_BOTH
+ NO_DEFAULT_PATH)
+ endif()
+endif()
+
+if (3RDPARTY_JEMALLOC_INCLUDE_DIR AND EXISTS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
+ list (APPEND 3RDPARTY_INCLUDE_DIRS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
+else()
+ list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_JEMALLOC_INCLUDE_DIR)
+ set (3RDPARTY_JEMALLOC_INCLUDE_DIR "" CACHE FILEPATH "the path to jemalloc.h" FORCE)
+endif()
+
+# Installing destination path
+if (WIN32)
+ set (JEMALLOC_INSTALL_DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_BIN}")
+else()
+ set (JEMALLOC_INSTALL_DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_LIB}")
+endif()
+
+macro (JEMALLOC_LIB_SEARCH MMGR_LIB PREFIX)
+if (NOT 3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB})
+ set (JEMALLOC_PATH_SUFFIXES "lib" "bin")
+ set (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} "3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}-NOTFOUND")
+ if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
+ find_library (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} NAMES ${MMGR_LIB}
+ PATHS "${3RDPARTY_JEMALLOC_LIBRARY_DIR}" "${3RDPARTY_JEMALLOC_DIR}"
+ PATH_SUFFIXES ${JEMALLOC_PATH_SUFFIXES}
+ CMAKE_FIND_ROOT_PATH_BOTH
+ NO_DEFAULT_PATH)
+ else()
+ find_library (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} NAMES ${MMGR_LIB}
+ PATH_SUFFIXES ${JEMALLOC_PATH_SUFFIXES}
+ CMAKE_FIND_ROOT_PATH_BOTH)
+ endif()
+ if (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB})
+ get_filename_component (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}}" PATH)
+ set (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}")
+ else()
+ set (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "")
+ endif()
+endif()
+if (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB})
+ list (APPEND 3RDPARTY_LIBRARY_DIRS "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}")
+ set (3RDPARTY_JEMALLOC_LIBRARY_DIR "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}" CACHE PATH "The directory containing JEMALLOC libraries" FORCE)
+else()
+ message("Cannot find ${MMGR_LIB} library in jemalloc 3rdparty")
+ list (APPEND 3RDPARTY_NO_LIBS 3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB})
+ set (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} "")
+endif()
+set (JEMALLOC_IS_STATIC_LIB FALSE)
+if (((${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} MATCHES "lib$")) OR ((${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} MATCHES "a$")))
+ get_filename_component(STATIC_LIB_NAME ${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} NAME)
+ list(APPEND CSF_MMGR "${STATIC_LIB_NAME}")
+ set (JEMALLOC_IS_STATIC_LIB TRUE)
+endif()
+# install instructions
+if (INSTALL_JEMALLOC AND NOT JEMALLOC_IS_STATIC_LIB)
+ OCCT_MAKE_OS_WITH_BITNESS()
+ OCCT_MAKE_COMPILER_SHORT_NAME()
+ get_filename_component(3RDPARTY_JEMALLOC_LIBRARY ${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} REALPATH)
+ if (SINGLE_GENERATOR)
+ install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
+ DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_LIB}")
+ else()
+ install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
+ CONFIGURATIONS Debug
+ DESTINATION "${JEMALLOC_INSTALL_DESTINATION}d")
+ install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
+ CONFIGURATIONS Release
+ DESTINATION "${JEMALLOC_INSTALL_DESTINATION}")
+ install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
+ CONFIGURATIONS RelWithDebInfo
+ DESTINATION "${JEMALLOC_INSTALL_DESTINATION}i")
+ endif()
+ set (USED_3RDPARTY_JEMALLOC_DIR "")
+elseif(NOT JEMALLOC_IS_STATIC_LIB)
+ # the library directory for using by the executable
+ set (USED_3RDPARTY_JEMALLOC_DIR ${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}})
+endif()
+unset(3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} CACHE)
+unset(3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} CACHE)
+endmacro()
+
+# Reset CSF variable
+set (CSF_MMGR "")
+
+# find static jemalloc lib
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
+if (WIN32)
+ JEMALLOC_LIB_SEARCH ("jemalloc" "STATIC")
+elseif(NOT WIN32)
+ JEMALLOC_LIB_SEARCH ("jemalloc_pic" "STATIC")
+ SET(CMAKE_FIND_LIBRARY_SUFFIXES "" "so")
+ JEMALLOC_LIB_SEARCH ("jemalloc.so.2" "SHARED")
+endif()
+
+# find shared jemalloc lib
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".so")
+JEMALLOC_LIB_SEARCH ("jemalloc" "SHARED")
# project can be switched later to use Intel Compiler (ICC).
# Enforcing -fp:precise ensures that in such case ICC will use correct
# option instead of its default -fp:fast which is harmful for OCCT.
+# Enforcing OMP only for internal test env
if (MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fp:precise")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp")
+ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp")
endif()
# add SSE2 option for old MSVC compilers (VS 2005 - 2010, 32 bit only)
set "TBB_DIR=@3RDPARTY_TBB_DLL_DIR@"
set "VTK_DIR=@3RDPARTY_VTK_DLL_DIR@"
set "FFMPEG_DIR=@3RDPARTY_FFMPEG_DLL_DIR@"
+ set "JEMALLOC_DIR=@3RDPARTY_JEMALLOC_LIBRARY_DIR@"
set "OPENVR_DIR=@3RDPARTY_OPENVR_DLL_DIRS@"
if not "@3RDPARTY_QT_DIR@" == "" (
set "CSF_OCCTTestsPath=@CMAKE_SOURCE_DIR@/tests"
set "CSF_OCCTDocPath=@CMAKE_SOURCE_DIR@/doc"
- rem for compatability with external application using CASROOT
+ rem for compatibility with external application using CASROOT
set "CASROOT=@CMAKE_SOURCE_DIR@"
)
)
export TBB_DIR="@3RDPARTY_TBB_LIBRARY_DIR@"
export VTK_DIR="@3RDPARTY_VTK_LIBRARY_DIR@"
export FFMPEG_DIR="@3RDPARTY_FFMPEG_LIBRARY_DIR@"
+ export JEMALLOC_DIR="@3RDPARTY_JEMALLOC_LIBRARY_DIR@"
if [ "x@3RDPARTY_QT_DIR" != "x" ]; then
export QTDIR="@3RDPARTY_QT_DIR@"
export CSF_OCCTTestsPath="@CMAKE_SOURCE_DIR@/tests"
export CSF_OCCTDocPath="@CMAKE_SOURCE_DIR@/doc"
- # for compatability with external application using CASROOT
+ # for compatibility with external application using CASROOT
export CASROOT="@CMAKE_SOURCE_DIR@"
fi
fi
set "TBB_DIR=@USED_3RDPARTY_TBB_DIR@"
set "VTK_DIR=@USED_3RDPARTY_VTK_DIR@"
set "FFMPEG_DIR=@USED_3RDPARTY_FFMPEG_DIR@"
+ set "JEMALLOC_DIR=@USED_3RDPARTY_JEMALLOC_DIR@"
set "OPENVR_DIR=@USED_3RDPARTY_OPENVR_DIR@"
if not "@USED_3RDPARTY_QT_DIR@" == "" (
export TBB_DIR="@USED_3RDPARTY_TBB_DIR@"
export VTK_DIR="@USED_3RDPARTY_VTK_DIR@"
export FFMPEG_DIR="@USED_3RDPARTY_FFMPEG_DIR@"
+ export JEMALLOC_DIR="@USED_3RDPARTY_JEMALLOC_DIR@"
if [ "x@USED_3RDPARTY_QT_DIR@" != "x" ]; then
export QTDIR="@USED_3RDPARTY_QT_DIR@"
for /f "usebackq delims=" %%i in (`vswhere.exe -version "[16.0,16.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
set "DevEnvDir=%%i\Common7\IDE\"
)
+) else if /I "%VCFMT%" == "vc143" (
+ for /f "usebackq delims=" %%i in (`vswhere.exe -version "[17.0,17.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
+ set "DevEnvDir=%%i\Common7\IDE\"
+ )
) else if /I "%VCFMT%" == "gcc" (
rem MinGW
) else (
set "VCVARS=%%i\VC\Auxiliary\Build\vcvarsall.bat"
)
set "VCPlatformToolSet=v142"
+) else if /I "%VCFMT%" == "vc143" (
+ for /f "usebackq delims=" %%i in (`vswhere.exe -version "[17.0,17.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
+ set "VCVARS=%%i\VC\Auxiliary\Build\vcvarsall.bat"
+ )
+ set "VCPlatformToolSet=v142"
) else if /I "%VCFMT%" == "gcc" (
rem MinGW
) else (
exit
)
-rem ----- For compatability with external application using CASROOT -----
+rem ----- For compatibility with external application using CASROOT -----
if ["%CASROOT%"] == [""] set "CASROOT=%SCRIPTROOT%"
rem ----- Define path to 3rdparty products -----
if /I ["%1"] == ["vc141"] set "VCVER=vc14"
if /I ["%1"] == ["vc142"] set "VCVER=vc14"
+if /I ["%1"] == ["vc143"] set "VCVER=vc14"
if exist "%CASROOT%\custom.bat" (
call "%CASROOT%\custom.bat" %VCVER% %ARCH% %CASDEB%
)
+if not ["%QTDIR%"] == [""] (
+ set "PATH=%QTDIR%/bin;%PATH%"
+ set "QT_PLUGIN_PATH=%QTDIR%/plugins"
+)
if not ["%TCL_DIR%"] == [""] set "PATH=%TCL_DIR%;%PATH%"
if not ["%TK_DIR%"] == [""] set "PATH=%TK_DIR%;%PATH%"
if not ["%FREETYPE_DIR%"] == [""] set "PATH=%FREETYPE_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 ["%JEMALLOC_DIR%"] == [""] set "PATH=%JEMALLOC_DIR%;%PATH%"
if not ["%OPENVR_DIR%"] == [""] set "PATH=%OPENVR_DIR%;%PATH%"
-if not ["%QTDIR%"] == [""] (
- set "PATH=%QTDIR%/bin;%PATH%"
- set "QT_PLUGIN_PATH=%QTDIR%/plugins"
-)
rem ----- Set path to 3rd party and OCCT libraries -----
if not "%CSF_OCCTBinPath%" == "" (
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
-# ----- For compatability with external application using CASROOT -----
+# ----- For compatibility with external application using CASROOT -----
if [ "${CASROOT}" == "" ]; then
export CASROOT="${aScriptPath}"
fi
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
fi
+if [ "$JEMALLOC_DIR" != "" ]; then
+ THRDPARTY_PATH="${JEMALLOC_DIR}:${THRDPARTY_PATH}"
+fi
+
if [ "$QTDIR" != "" ]; then
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
fi
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
-# ----- For compatability with external application using CASROOT -----
+# ----- For compatibility with external application using CASROOT -----
if [ "${CASROOT}" == "" ]; then
export CASROOT="@INSTALL_DIR@"
fi
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
fi
+if [ "$JEMALLOC_DIR" != "" ]; then
+ THRDPARTY_PATH="${JEMALLOC_DIR}:${THRDPARTY_PATH}"
+fi
+
if [ "$QTDIR" != "" ]; then
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
fi
//gka,abv 14.04.99 S4136: maintain unit context, precision and maxtolerance values
#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepCheck_Status.hxx>
#include <Geom_Axis2Placement.hxx>
#include <Message_ProgressScope.hxx>
#include <OSD_Timer.hxx>
#include <Precision.hxx>
+#include <ShapeProcess_ShapeContext.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <Standard_Transient.hxx>
}
// [END] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
Standard_Boolean aTrsfUse = (Interface_Static::IVal("read.step.root.transformation") == 0);
- return TransferShape(start, TP, Standard_True, aTrsfUse, theProgress);
+ auto aResult = TransferShape(start, TP, Standard_True, aTrsfUse, theProgress);
+ if (Interface_Static::IVal("read.step.parallel.healing") == 0)
+ PostHealing(TP);
+ return aResult;
}
if (found && myShapeBuilder.IsDone()) {
mappedShape = myShapeBuilder.Value();
// Apply ShapeFix (on manifold shapes only. Non-manifold topology is processed separately: ssv; 13.11.2010)
- if (isManifold && aHasGeom)
+ if (isManifold&& aHasGeom)
{
- Handle(Standard_Transient) info;
- mappedShape =
- XSAlgo::AlgoContainer()->ProcessShape( mappedShape, myPrecision, myMaxTol,
- "read.step.resource.name",
- "read.step.sequence", info,
- aPS.Next());
- XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
+ if (Interface_Static::IVal("read.step.parallel.healing") != 0)
+ {
+ Handle(Standard_Transient) info;
+ mappedShape =
+ XSAlgo::AlgoContainer()->ProcessShape(mappedShape, myPrecision, myMaxTol,
+ "read.step.resource.name",
+ "read.step.sequence", info,
+ aPS.Next());
+ XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
+ }
+ else
+ myShapesToHeal.Add(mappedShape);
}
}
found = !mappedShape.IsNull();
shellClosingsMap.Add(shellA, closingShells);
}
}
+
+//=======================================================================
+// Method : PostHealing
+// Purpose : postprocess shape healing
+//=======================================================================
+Standard_EXPORT void STEPControl_ActorRead::PostHealing(const Handle(Transfer_TransientProcess)& TP)
+{
+ NCollection_Array1<Handle(ShapeProcess_ShapeContext)> aInfos(1, myShapesToHeal.Size());
+ NCollection_Array1<TopTools_DataMapOfShapeShape> aOrigToCopyMapArr(1, myShapesToHeal.Size());
+ NCollection_Array1<TopTools_DataMapOfShapeShape> aCopyToOrigMapArr(1, myShapesToHeal.Size());
+
+#pragma omp parallel for
+ for (int i = 1; i <= myShapesToHeal.Size(); i++)
+ {
+ TopoDS_Shape anOrig = myShapesToHeal.FindKey(i);
+ BRepBuilderAPI_Copy aCurCopy(anOrig, true, true);
+ TopoDS_Shape aCopy = aCurCopy.Shape();
+ // Collect all the modified shapes in Copy() for futher update of binders not to lost attached attributes
+ for (int aTypeIt = anOrig.ShapeType() + 1; aTypeIt <= TopAbs_VERTEX; aTypeIt++)
+ {
+ for (TopExp_Explorer anExp(anOrig, (TopAbs_ShapeEnum)aTypeIt); anExp.More(); anExp.Next())
+ {
+ const TopoDS_Shape& aSx = anExp.Current();
+ const TopoDS_Shape& aModifShape = aCurCopy.ModifiedShape(aSx);
+ aOrigToCopyMapArr.ChangeValue(i).Bind(aSx, aModifShape);
+ aCopyToOrigMapArr.ChangeValue(i).Bind(aModifShape, aSx);
+ }
+ }
+ Handle(Standard_Transient) anInfo;
+ aCopy = XSAlgo::AlgoContainer()->ProcessShape(aCopy, myPrecision, myMaxTol,
+ "read.step.resource.name",
+ "read.step.sequence", aInfos[i],
+ Message_ProgressRange());
+ *(Handle(TopoDS_TShape)&)anOrig.TShape() = *aCopy.TShape();
+ }
+
+ // Update Shape context for correct attributes attaching
+ Handle(ShapeProcess_ShapeContext) aFullContext = new ShapeProcess_ShapeContext(TopoDS_Shape(), "", "");
+ TopTools_DataMapOfShapeShape& aHealedMap = (TopTools_DataMapOfShapeShape&)aFullContext->Map();
+
+ // Copy maps to the common binders map
+ for (int i = 1; i <= aOrigToCopyMapArr.Size(); i++)
+ {
+ const auto& aForwMap = aOrigToCopyMapArr.Value(i);
+ const auto& aRevMap = aCopyToOrigMapArr.Value(i);
+ Handle(ShapeProcess_ShapeContext) aContext = aInfos.Value(i);
+
+ for (TopTools_DataMapOfShapeShape::Iterator aMapIt(aForwMap); aMapIt.More(); aMapIt.Next())
+ {
+ aHealedMap.Bind(aMapIt.Key(), aMapIt.Value());
+ }
+ for (TopTools_DataMapOfShapeShape::Iterator anIter(aContext->Map()); anIter.More(); anIter.Next())
+ {
+ TopoDS_Shape aShape;
+ if (aRevMap.Find(anIter.Key(), aShape))
+ {
+ aHealedMap.Bind(aShape, anIter.Value());
+ }
+ }
+ }
+
+ XSAlgo::AlgoContainer()->MergeTransferInfo(TP, aFullContext);
+
+ CleanShapesToHeal();
+}
#include <TopTools_ListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <Message_ProgressRange.hxx>
+#include <NCollection_IndexedMap.hxx>
class StepRepr_Representation;
class Standard_Transient;
//! REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION
Standard_EXPORT Standard_Boolean ComputeSRRWT (const Handle(StepRepr_RepresentationRelationship)& SRR, const Handle(Transfer_TransientProcess)& TP, gp_Trsf& Trsf);
+ //! Heals the collected during transferring shapes
+ Standard_EXPORT void PostHealing(const Handle(Transfer_TransientProcess)& TP);
-
+ //! Cleans collected for post healing shapes.
+ inline void CleanShapesToHeal()
+ {
+ myShapesToHeal.Clear();
+ }
DEFINE_STANDARD_RTTIEXT(STEPControl_ActorRead,Transfer_ActorOfTransientProcess)
Standard_Real myPrecision;
Standard_Real myMaxTol;
Handle(StepRepr_Representation) mySRContext;
-
-
+ NCollection_IndexedMap<TopoDS_Shape> myShapesToHeal;
};
Interface_Static::Init("step", "read.step.root.transformation", '&', "eval OFF");
Interface_Static::SetCVal("read.step.root.transformation", "ON");
+ Interface_Static::Init("step", "read.step.parallel.healing", 'e', "");
+ Interface_Static::Init("step", "read.step.parallel.healing", '&', "enum 0");
+ Interface_Static::Init("step", "read.step.parallel.healing", '&', "eval ON");
+ Interface_Static::Init("step", "read.step.parallel.healing", '&', "eval OFF");
+ Interface_Static::SetCVal("read.step.parallel.healing", "ON");
+
// STEP file encoding for names translation
// Note: the numbers should be consistent with Resource_FormatType enumeration
Interface_Static::Init("step", "read.step.codepage", 'e', "");
-// Created on: 2005-03-15
-// Created by: Peter KURNEV
-// Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 1999-2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-
#include <Standard.hxx>
-#include <Standard_MMgrOpt.hxx>
-#include <Standard_MMgrRaw.hxx>
-#include <Standard_MMgrTBBalloc.hxx>
-#include <Standard_Assert.hxx>
+
+#include <Standard_OutOfMemory.hxx>
#include <stdlib.h>
+
#if(defined(_WIN32) || defined(__WIN32__))
- #include <windows.h>
- #include <malloc.h>
- #include <locale.h>
+#include <windows.h>
+#include <malloc.h>
+#include <locale.h>
#endif
#if defined(_MSC_VER) || defined(__ANDROID__) || defined(__QNX__)
- #include <malloc.h>
+#include <malloc.h>
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
- #include <mm_malloc.h>
+#include <mm_malloc.h>
#else
- extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theSize);
-#endif
-
-// There is no support for environment variables in UWP
-// OSD_Environment could not be used here because of cyclic dependency
-#ifdef OCCT_UWP
-#define getenv(x) NULL
+extern "C" int posix_memalign(void** thePtr, size_t theAlign, size_t theSize);
#endif
-#ifndef OCCT_MMGT_OPT_DEFAULT
-#define OCCT_MMGT_OPT_DEFAULT 0
-#endif
-
-//=======================================================================
-//class : Standard_MMgrFactory
-//purpose : Container for pointer to memory manager;
-// used to construct appropriate memory manager according
-// to environment settings, and to ensure destruction upon exit
-//=======================================================================
-class Standard_MMgrFactory
-{
-public:
- static Standard_MMgrRoot* GetMMgr();
- ~Standard_MMgrFactory();
-
-private:
- Standard_MMgrFactory();
- Standard_MMgrFactory (const Standard_MMgrFactory&);
- Standard_MMgrFactory& operator= (const Standard_MMgrFactory&);
-
-private:
- Standard_MMgrRoot* myFMMgr;
-};
-
-//=======================================================================
-//function : Standard_MMgrFactory
-//purpose : Check environment variables and create appropriate memory manager
-//=======================================================================
-
-Standard_MMgrFactory::Standard_MMgrFactory()
-: myFMMgr (NULL)
-{
-/*#if defined(_MSC_VER) && (_MSC_VER > 1400)
- // Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads.
- // After this call all following _configthreadlocale() will be ignored assuming
- // Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale)
- // should be used explicitly to ensure thread-safety!
-
- // This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason.
- // -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour
- // although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread).
- _configthreadlocale (-1);
-#endif*/
-
- // Check basic assumption.
- // If assertion happens, then OCCT should be corrected for compatibility with such CPU architecture.
- Standard_STATIC_ASSERT(sizeof(Standard_Utf8Char) == 1);
- Standard_STATIC_ASSERT(sizeof(short) == 2);
- Standard_STATIC_ASSERT(sizeof(Standard_Utf16Char) == 2);
- Standard_STATIC_ASSERT(sizeof(Standard_Utf32Char) == 4);
-#ifdef _WIN32
- Standard_STATIC_ASSERT(sizeof(Standard_WideChar) == sizeof(Standard_Utf16Char));
-#endif
+#ifdef OCCT_MMGT_OPT_JEMALLOC
+#define JEMALLOC_NO_DEMANGLE
+#include <jemalloc.h>
+#endif // OCCT_MMGT_OPT_JEMALLOC
- char* aVar;
- aVar = getenv ("MMGT_OPT");
- Standard_Integer anAllocId = (aVar ? atoi (aVar): OCCT_MMGT_OPT_DEFAULT);
-
-#if defined(HAVE_TBB) && defined(_M_IX86)
- if (anAllocId == 2)
- {
- // CR25396: Check if SSE2 instructions are supported on 32-bit x86 processor on Windows platform,
- // if not then use MMgrRaw instead of MMgrTBBalloc.
- // It is to avoid runtime crash when running on a CPU
- // that supports SSE but does not support SSE2 (some modifications of AMD Sempron).
- static const DWORD _SSE2_FEATURE_BIT(0x04000000);
- DWORD volatile dwFeature;
- _asm
- {
- push eax
- push ebx
- push ecx
- push edx
-
- // get the CPU feature bits
- mov eax, 1
- cpuid
- mov dwFeature, edx
-
- pop edx
- pop ecx
- pop ebx
- pop eax
- }
- if ((dwFeature & _SSE2_FEATURE_BIT) == 0)
- anAllocId = 0;
- }
+// paralleling with Intel TBB
+#ifdef HAVE_TBB
+#include <tbb/scalable_allocator.h>
+#else
+#ifdef OCCT_MMGT_OPT_TBB
+#undef OCCT_MMGT_OPT_TBB
#endif
-
- aVar = getenv ("MMGT_CLEAR");
- Standard_Boolean toClear = (aVar ? (atoi (aVar) != 0) : Standard_True);
-
- // on Windows (actual for XP and 2000) activate low fragmentation heap
- // for CRT heap in order to get best performance.
- // Environment variable MMGT_LFH can be used to switch off this action (if set to 0)
-#if defined(_MSC_VER)
- aVar = getenv ("MMGT_LFH");
- if ( aVar == NULL || atoi (aVar) != 0 )
- {
- ULONG aHeapInfo = 2;
- HANDLE aCRTHeap = (HANDLE)_get_heap_handle();
- HeapSetInformation (aCRTHeap, HeapCompatibilityInformation, &aHeapInfo, sizeof(aHeapInfo));
- }
+#define scalable_malloc malloc
+#define scalable_calloc calloc
+#define scalable_realloc realloc
+#define scalable_free free
#endif
- switch (anAllocId)
- {
- case 1: // OCCT optimized memory allocator
- {
- aVar = getenv ("MMGT_MMAP");
- Standard_Boolean bMMap = (aVar ? (atoi (aVar) != 0) : Standard_True);
- aVar = getenv ("MMGT_CELLSIZE");
- Standard_Integer aCellSize = (aVar ? atoi (aVar) : 200);
- aVar = getenv ("MMGT_NBPAGES");
- Standard_Integer aNbPages = (aVar ? atoi (aVar) : 1000);
- aVar = getenv ("MMGT_THRESHOLD");
- Standard_Integer aThreshold = (aVar ? atoi (aVar) : 40000);
- myFMMgr = new Standard_MMgrOpt (toClear, bMMap, aCellSize, aNbPages, aThreshold);
- break;
- }
- case 2: // TBB memory allocator
- myFMMgr = new Standard_MMgrTBBalloc (toClear);
- break;
- case 0:
- default: // system default memory allocator
- myFMMgr = new Standard_MMgrRaw (toClear);
- }
-}
-
-//=======================================================================
-//function : ~Standard_MMgrFactory
-//purpose :
-//=======================================================================
-
-Standard_MMgrFactory::~Standard_MMgrFactory()
-{
- if ( myFMMgr )
- myFMMgr->Purge(Standard_True);
-}
-
-//=======================================================================
-// function: GetMMgr
-//
-// This static function has a purpose to wrap static holder for memory
-// manager instance.
-//
-// Wrapping holder inside a function is needed to ensure that it will
-// be initialized not later than the first call to memory manager (that
-// would be impossible to guarantee if holder was static variable on
-// global or file scope, because memory manager may be called from
-// constructors of other static objects).
-//
-// Note that at the same time we could not guarantee that the holder
-// object is destroyed after last call to memory manager, since that
-// last call may be from static Handle() object which has been initialized
-// dynamically during program execution rather than in its constructor.
-//
-// Therefore holder currently does not call destructor of the memory manager
-// but only its method Purge() with Standard_True.
-//
-// To free the memory completely, we probably could use compiler-specific
-// pragmas (such as '#pragma fini' on SUN Solaris and '#pragma init_seg' on
-// WNT MSVC++) to put destructing function in code segment that is called
-// after destructors of other (even static) objects. However, this is not
-// done by the moment since it is compiler-dependent and there is no guarantee
-// thatsome other object calling memory manager is not placed also in that segment...
-//
-// Note that C runtime function atexit() could not help in this problem
-// since its behaviour is the same as for destructors of static objects
-// (see ISO 14882:1998 "Programming languages -- C++" 3.6.3)
-//
-// The correct approach to deal with the problem would be to have memory manager
-// to properly control its memory allocation and caching free blocks so
-// as to release all memory as soon as it is returned to it, and probably
-// even delete itself if all memory it manages has been released and
-// last call to method Purge() was with True.
-//
-// Note that one possible method to control memory allocations could
-// be counting calls to Allocate() and Free()...
-//
-//=======================================================================
-Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr()
-{
- static Standard_MMgrFactory aFactory;
- return aFactory.myFMMgr;
-}
+// Available macros definition
+// - OCCT_MMGT_OPT_TBB, using tbb::scalable_allocator
+// - OCCT_MMGT_OPT_NATIVE, using native calloc, free
+// - OCCT_MMGT_OPT_JEMALLOC, using external jecalloc, jefree
//=======================================================================
//function : Allocate
-//purpose :
+//purpose :
//=======================================================================
-
-Standard_Address Standard::Allocate(const Standard_Size size)
+Standard_Address Standard::Allocate(const Standard_Size theSize)
{
- return Standard_MMgrFactory::GetMMgr()->Allocate(size);
+#if defined OCCT_MMGT_OPT_JEMALLOC
+ Standard_Address aPtr = je_calloc(theSize, sizeof(char));
+ if (!aPtr)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
+ return aPtr;
+#elif defined OCCT_MMGT_OPT_TBB
+ Standard_Address aPtr = scalable_calloc(theSize, sizeof(char));
+ if (!aPtr)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
+ return aPtr;
+#else
+ Standard_Address aPtr = calloc(theSize, sizeof(char));
+ if (!aPtr)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
+ return aPtr;
+#endif
}
//=======================================================================
//function : Free
-//purpose :
+//purpose :
//=======================================================================
-
-void Standard::Free (Standard_Address theStorage)
+void Standard::Free(Standard_Address theStorage)
{
- Standard_MMgrFactory::GetMMgr()->Free(theStorage);
+#if defined OCCT_MMGT_OPT_JEMALLOC
+ je_free(theStorage);
+#elif defined OCCT_MMGT_OPT_TBB
+ scalable_free(theStorage);
+#else
+ free(theStorage);
+#endif
}
//=======================================================================
//function : Reallocate
-//purpose :
+//purpose :
//=======================================================================
-
-Standard_Address Standard::Reallocate (Standard_Address theStorage,
- const Standard_Size theSize)
+Standard_Address Standard::Reallocate(Standard_Address theStorage,
+ const Standard_Size theSize)
{
- return Standard_MMgrFactory::GetMMgr()->Reallocate (theStorage, theSize);
+ // Note that it is not possible to ensure that additional memory
+ // allocated by realloc will be cleared (so as to satisfy myClear mode);
+ // in order to do that we would need using memset..
+#if defined OCCT_MMGT_OPT_JEMALLOC
+ Standard_Address aNewStorage = (Standard_Address)je_realloc(theStorage, theSize);
+ if (!aNewStorage)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
+ return aNewStorage;
+#elif defined OCCT_MMGT_OPT_TBB
+ Standard_Address aNewStorage = (Standard_Address)scalable_realloc(theStorage, theSize);
+ if (!aNewStorage)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
+ return aNewStorage;
+#else
+ Standard_Address aNewStorage = (Standard_Address)realloc(theStorage, theSize);
+ if (!aNewStorage)
+ throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
+ return aNewStorage;
+#endif
}
//=======================================================================
//function : Purge
-//purpose :
+//purpose :
//=======================================================================
-
Standard_Integer Standard::Purge()
{
- return Standard_MMgrFactory::GetMMgr()->Purge();
+ return true;
}
//=======================================================================
//function : AllocateAligned
//purpose :
//=======================================================================
-
-Standard_Address Standard::AllocateAligned (const Standard_Size theSize,
- const Standard_Size theAlign)
+Standard_Address Standard::AllocateAligned(const Standard_Size theSize,
+ const Standard_Size theAlign)
{
+#ifdef OCCT_MMGT_OPT_JEMALLOC
+ return je_aligned_alloc(theAlign, theSize);
+#elif defined OCCT_MMGT_OPT_TBB
+ return scalable_aligned_malloc(theSize, theAlign);
+#else
#if defined(_MSC_VER)
- return _aligned_malloc (theSize, theAlign);
+ return _aligned_malloc(theSize, theAlign);
#elif defined(__ANDROID__) || defined(__QNX__)
- return memalign (theAlign, theSize);
+ return memalign(theAlign, theSize);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
- return _mm_malloc (theSize, theAlign);
+ return _mm_malloc(theSize, theAlign);
#else
void* aPtr;
- if (posix_memalign (&aPtr, theAlign, theSize))
+ if (posix_memalign(&aPtr, theAlign, theSize))
{
return NULL;
}
return aPtr;
#endif
+#endif
}
//=======================================================================
//function : FreeAligned
//purpose :
//=======================================================================
-
-void Standard::FreeAligned (Standard_Address thePtrAligned)
+void Standard::FreeAligned(Standard_Address thePtrAligned)
{
+#ifdef OCCT_MMGT_OPT_JEMALLOC
+return je_free(thePtrAligned);
+#elif defined OCCT_MMGT_OPT_TBB
+ return scalable_aligned_free(thePtrAligned);
+#else
#if defined(_MSC_VER)
- _aligned_free (thePtrAligned);
+ _aligned_free(thePtrAligned);
#elif defined(__ANDROID__) || defined(__QNX__)
- free (thePtrAligned);
+ free(thePtrAligned);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
- _mm_free (thePtrAligned);
+ _mm_free(thePtrAligned);
#else
- free (thePtrAligned);
+ free(thePtrAligned);
+#endif
#endif
}
project(TKernel)
OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
+
+# Set desired Memory Manager
+if ("${USE_MMGR_TYPE}" STREQUAL "TBB")
+ target_compile_definitions("TKernel" PRIVATE "OCCT_MMGT_OPT_TBB")
+elseif ("${USE_MMGR_TYPE}" STREQUAL "JEMALLOC")
+ target_compile_definitions("TKernel" PRIVATE "OCCT_MMGT_OPT_JEMALLOC")
+else ()
+ message (STATUS "Info: Used native memory manager")
+endif()
CSF_wsock32
CSF_psapi
CSF_androidlog
+CSF_MMGR