#
IF(HAVE_SALOME)
- SET(SUIT_INCLUDE ${SALOME_GUI_INCLUDE})
- MESSAGE(STATUS "SUIT_INCLUDE: ${SALOME_GUI_INCLUDE}")
+ SET(SUIT_INCLUDE "${GUI_ROOT_DIR}/include/salome")
SET(SUIT_LIB_DIR "${GUI_ROOT_DIR}/lib/salome")
ELSE(HAVE_SALOME)
SET(SUIT_DIR $ENV{SUIT_DIR})
IF(EXISTS ${SUIT_DIR})
-
MESSAGE(STATUS "SUIT found at ${SUIT_DIR}")
IF(WIN32)
SET(SUIT_LIB_DIR ${SUIT_DIR}/lib)
FILE(TO_CMAKE_PATH ${SUIT_LIB_DIR} SUIT_LIB_DIR)
FILE(TO_CMAKE_PATH ${SUIT_INCLUDE} SUIT_INCLUDE)
+MESSAGE(STATUS "SUIT includes: ${SUIT_INCLUDE}")
+MESSAGE(STATUS "SUIT libraries: ${SUIT_LIB_DIR}")
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL directory")
-SET(GUI_ROOT_DIR $ENV{GUI_ROOT_DIR} CACHE PATH "Path to the Salome GUI directory")
-SET(HAVE_SALOME NO)
-IF(EXISTS ${GUI_ROOT_DIR})
- MESSAGE("-- SALOME found at " ${GUI_ROOT_DIR})
- SET(HAVE_SALOME YES)
-
+IF(${HAVE_SALOME})
FIND_LIBRARY(caf caf ${GUI_ROOT_DIR}/lib/salome)
FIND_LIBRARY(CAM CAM ${GUI_ROOT_DIR}/lib/salome)
FIND_LIBRARY(CASCatch CASCatch ${GUI_ROOT_DIR}/lib/salome)
FIND_LIBRARY(vtkTools vtkTools ${GUI_ROOT_DIR}/lib/salome)
FIND_LIBRARY(SalomeGuiHelpers SalomeGuiHelpers ${GUI_ROOT_DIR}/lib/salome)
FIND_LIBRARY(SalomeTreeData SalomeTreeData ${GUI_ROOT_DIR}/lib/salome)
-
- SET(SALOME_GUI_INCLUDE ${GUI_ROOT_DIR}/include/salome)
- SET(SALOME_KERNEL_INCLUDE ${KERNEL_ROOT_DIR}/include/salome)
- SET(SALOME_KERNEL_LIBDIR ${KERNEL_ROOT_DIR}/lib/salome)
- ADD_DEFINITIONS( -DHAVE_SALOME )
-ENDIF(EXISTS ${GUI_ROOT_DIR})
+ENDIF()
ENDIF()
ENDIF()
ENDMACRO(SWIG_CHECK_GENERATION)
+
+#########################################################################
+# SALOME_SETUP_VERSION()
+#
+# USAGE: SALOME_SETUP_VERSION(version [DEVELOPMENT])
+#
+# ARGUMENTS:
+# version [in] Version decriptor (string).
+#
+# OPTIONS:
+# DEVELOPMENT Forces setting development flag.
+#
+# The macro sets the following variables:
+# - PROJECTNAME_MAJOR_VERSION - major version number
+# - PROJECTNAME_MINOR_VERSION - minor version number
+# - PROJECTNAME_PATCH_VERSION - release version number
+# - PROJECTNAME_VERSION - full qualified version
+# - PROJECTNAME_VERSION_DEV - development flag (0 value for released version)
+# - PROJECTNAME_XVERSION - hexadecimal representation of version
+# - PROJECTNAME_GIT_SHA1 - git commit's sha1
+#
+FUNCTION(SALOME_SETUP_VERSION version)
+ # parse arguments
+ PARSE_ARGUMENTS(SALOME_SETUP_VERSION "" "DEVELOPMENT" ${ARGN})
+ # project name in upper case (if not set in master CMakeLists.txt)
+ STRING(TOUPPER ${PROJECT_NAME} _pkg_uc)
+ # parse version component
+ STRING(REGEX MATCHALL "[^.]" _components "${version}")
+ LIST(LENGTH _components _length)
+ IF(${_length} GREATER 0)
+ LIST(GET _components 0 _major)
+ LIST(REMOVE_AT _components 0)
+ ELSE()
+ SET(_major 0)
+ ENDIF()
+ LIST(LENGTH _components _length)
+ IF(${_length} GREATER 0)
+ LIST(GET _components 0 _minor)
+ LIST(REMOVE_AT _components 0)
+ ELSE()
+ SET(_minor 0)
+ ENDIF()
+ LIST(LENGTH _components _length)
+ IF(${_length} GREATER 0)
+ LIST(GET _components 0 _patch)
+ LIST(REMOVE_AT _components 0)
+ ELSE()
+ SET(_patch 0)
+ ENDIF()
+ # set project version: 'major', 'minor' and 'patch' components
+ SET(${_pkg_uc}_MAJOR_VERSION ${_major} PARENT_SCOPE)
+ SET(${_pkg_uc}_MINOR_VERSION ${_minor} PARENT_SCOPE)
+ SET(${_pkg_uc}_PATCH_VERSION ${_patch} PARENT_SCOPE)
+ SET(${_pkg_uc}_VERSION ${_major}.${_minor}.${_patch} PARENT_SCOPE)
+ # set 'development' flag
+ IF(SALOME_SETUP_VERSION_DEVELOPMENT)
+ SET(${_pkg_uc}_VERSION_DEV 1 PARENT_SCOPE)
+ ELSE()
+ SET(${_pkg_uc}_VERSION_DEV 0 PARENT_SCOPE)
+ ENDIF()
+ # set hexa representation of version
+ SALOME_TOHEXA(${_major} _major_h)
+ SALOME_TOHEXA(${_minor} _minor_h)
+ SALOME_TOHEXA(${_patch} _patch_h)
+ SET(${_pkg_uc}_XVERSION "0x${_major_h}${_minor_h}${_patch_h}" PARENT_SCOPE)
+ # detect git sha1
+ EXECUTE_PROCESS(COMMAND git describe --dirty --tags --match=V* --always
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ OUTPUT_VARIABLE _git_version
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ IF(_git_version)
+ SET(${_pkg_uc}_GIT_SHA1 "${_git_version}" PARENT_SCOPE)
+ ELSE(_)
+ SET(${_pkg_uc}_GIT_SHA1 "unknown" PARENT_SCOPE)
+ ENDIF()
+ENDFUNCTION()
# Full path to the python test file beeing executed
SET(aTestFileName "${testdir}/${eachFileName}")
+ IF(NOT EXISTS ${aTestFileName})
+ SET(aTestFileName "${testdir}/Test/${eachFileName}")
+ ENDIF(NOT EXISTS ${aTestFileName})
IF(EXISTS ${aTestFileName})
ADD_TEST(NAME ${aTestName}
COMMAND ${PYTHON_EXECUTABLE} ${aTestFileName})
# Debug output...
#MESSAGE(STATUS "Test added: ${aTestName} file: ${aTestFileName}")
ELSE(EXISTS ${aTestFileName})
- MESSAGE(WARNING "Can not find the test file: ${aTestFileName}")
+ MESSAGE(WARNING "Can not find the test file: ${eachFileName}")
+ MESSAGE(STATUS "Search paths are: ${testdir}")
+ MESSAGE(STATUS " ${testdir}/Test")
ENDIF(EXISTS ${aTestFileName})
endforeach(eachFileName ${ARGN})
endfunction(GENERATE_TESTS)
function(ADD_UNIT_TESTS)
- GENERATE_TESTS(PATH "${CMAKE_CURRENT_SOURCE_DIR}/Test" TESTS ${ARGN})
+ GENERATE_TESTS(PATH "${CMAKE_CURRENT_SOURCE_DIR}" TESTS ${ARGN})
endfunction(ADD_UNIT_TESTS)
function(ADD_UNIT_TESTS_API)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.10)
-PROJECT (SHAPER)
-SET(${PROJECT_NAME}_MAJOR_VERSION 9)
-SET(${PROJECT_NAME}_MINOR_VERSION 7)
-SET(${PROJECT_NAME}_PATCH_VERSION 0)
-SET(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION})
-SET(COMPONENT_NAME SHAPER)
+# Project name
+# ============
+PROJECT(SHAPER)
-# Ensure a proper linker behavior:
+# Ensure a proper linker behavior
+# ===============================
CMAKE_POLICY(SET CMP0003 NEW)
IF(WIN32)
CMAKE_POLICY(SET CMP0020 OLD) # disable automatic linking to qtmain.lib
ENDIF(WIN32)
+# Append path to common macros
+# ===========================
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH})
+# Detect SALOME mode; append path to SALOME macros
+# ================================================
+SET(HAVE_SALOME NO)
+SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
+IF(EXISTS ${CONFIGURATION_ROOT_DIR})
+ SET(HAVE_SALOME YES)
+ MESSAGE(STATUS "SALOME found; building with SALOME!")
+ SET(CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake" ${CMAKE_MODULE_PATH})
+ INCLUDE(SalomeMacros)
+ELSE()
+ MESSAGE(STATUS "SALOME is not found; building without it!")
+ INCLUDE(SalomeMacros)
+ENDIF()
+
+# Versioning
+# ===========
+SALOME_SETUP_VERSION(9.7.0 DEVELOPMENT)
+MESSAGE(STATUS "Building ${PROJECT_NAME} ${${PROJECT_NAME}_VERSION} from \"${${PROJECT_NAME}_GIT_SHA1}\"")
+SET(COMPONENT_NAME SHAPER)
+
+# Options
+# =======
IF (NOT CADBUILDER_BUILD_DOC)
OPTION(SHAPER_BUILD_DOC "Generate SHAPER documentation" ON)
ENDIF(NOT CADBUILDER_BUILD_DOC)
INCLUDE(FindEclipse)
INCLUDE(Common)
-INCLUDE(FindSalome)
-INCLUDE(FindSUIT)
INCLUDE(FindTInspector)
+INCLUDE(FindSalomeQt5)
IF(HAVE_SALOME)
- SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files")
- IF(EXISTS ${CONFIGURATION_ROOT_DIR})
- SET(CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake" ${CMAKE_MODULE_PATH})
- INCLUDE(SalomeMacros)
- INCLUDE(FindSalomeQt5)
- ELSE()
- MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !")
- ENDIF()
+ INCLUDE(SalomeSetupPlatform) # From CONFIGURATION
+
+ ADD_DEFINITIONS(-DHAVE_SALOME)
+
SET(KERNEL_ROOT_DIR $ENV{KERNEL_ROOT_DIR} CACHE PATH "Path to the Salome KERNEL")
IF(EXISTS ${KERNEL_ROOT_DIR})
FIND_PACKAGE(SalomeKERNEL REQUIRED)
ADD_DEFINITIONS(${KERNEL_DEFINITIONS})
INCLUDE_DIRECTORIES(${KERNEL_INCLUDE_DIRS})
+ SET(SALOME_KERNEL_LIBDIR ${KERNEL_ROOT_DIR}/lib/salome)
ELSE(EXISTS ${KERNEL_ROOT_DIR})
MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR")
ENDIF(EXISTS ${KERNEL_ROOT_DIR})
+
SET(GUI_ROOT_DIR $ENV{GUI_ROOT_DIR} CACHE PATH "Path to the Salome GUI")
IF(EXISTS ${GUI_ROOT_DIR})
FIND_PACKAGE(SalomeGUI REQUIRED)
ELSE(EXISTS ${GUI_ROOT_DIR})
MESSAGE(FATAL_ERROR "We absolutely need a Salome GUI, please define GUI_ROOT_DIR")
ENDIF(EXISTS ${GUI_ROOT_DIR})
- INCLUDE(SalomeSetupPlatform) # From CONFIGURATION
FIND_PACKAGE(SalomePythonInterp REQUIRED)
FIND_PACKAGE(SalomePythonLibs REQUIRED)
-
FIND_PACKAGE(SalomeOpenCASCADE REQUIRED)
-
+ INCLUDE(FindSalome)
ELSE()
- INCLUDE(SalomeMacros)
- INCLUDE(FindSalomeQt5)
INCLUDE(FindPython)
INCLUDE(FindSalomeOpenCASCADE)
ENDIF()
-# Common CMake macros
-# ===================
-
+INCLUDE(FindSUIT)
# Find LibXml2
IF(DEFINED ENV{LIBXML2_ROOT_DIR})
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-import os
+import os, inspect
from salome.shaper import model
+from PyQt5.Qt import QApplication
+
import salome
+salome.salome_init_without_session()
salome.salome_init(1)
+if QApplication.instance() is None:
+ app = QApplication([])
-data_dir = os.path.join(os.path.dirname(sys.argv[0]), "data")
+data_dir = os.path.join(os.path.dirname(inspect.getfile(lambda: None)), "data")
model.begin()
partSet = model.moduleDocument()
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
-import os
+import os, inspect
from salome.shaper import model
+from PyQt5.Qt import QApplication
+
import salome
+salome.salome_init_without_session()
salome.salome_init(1)
+if QApplication.instance() is None:
+ app = QApplication([])
-data_dir = os.path.join(os.path.dirname(sys.argv[0]), "data")
+data_dir = os.path.join(os.path.dirname(inspect.getfile(lambda: None)), "data")
from tempfile import TemporaryDirectory
tmp_dir = TemporaryDirectory()
return false; // no cuts
}
+//=================================================================================================
+void FeaturesPlugin_CompositeBoolean::addSubShapes (const GeomShapePtr theCompound,
+ const ListOfShape& theSubShapesToAvoid,
+ ListOfShape& theSubShapesToAdd) {
+ for (GeomAPI_ShapeIterator aCompoundIt (theCompound);
+ aCompoundIt.more();
+ aCompoundIt.next()) {
+ GeomShapePtr aCompoundSS = aCompoundIt.current();
+ ListOfShape::const_iterator aUseIt = theSubShapesToAvoid.cbegin();
+ for (; aUseIt != theSubShapesToAvoid.cend(); aUseIt++) {
+ if (aCompoundSS->isEqual(*aUseIt)) {
+ break;
+ }
+ }
+ if (aUseIt == theSubShapesToAvoid.cend()) {
+ if (aCompoundSS->shapeType() == GeomAPI_Shape::COMPSOLID ||
+ aCompoundSS->shapeType() == GeomAPI_Shape::COMPOUND) {
+ addSubShapes(aCompoundSS, theSubShapesToAvoid, theSubShapesToAdd);
+ }
+ else {
+ theSubShapesToAdd.push_back(aCompoundSS);
+ }
+ }
+ }
+}
+
//=================================================================================================
bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools,
ListOfShape& theObjects,
ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
if(aResCompSolidPtr.get()) {
ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true);
- if (!aCompoundsMap.isBound(aResRootPtr->shape()) || myOperationType != BOOL_CUT) {
+ if (!aCompoundsMap.isBound(aResRootPtr->shape())) {
// Compsolid or a simple (one-level) compound
- // Or not CUT
- // TODO: correct FUSE for complex compounds?
GeomShapePtr aContextShape = aResCompSolidPtr->shape();
std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
for(; anIt != aCompSolidsObjects.end(); anIt++) {
theObjects.insert(theObjects.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
theObjects.insert(theObjects.end(), anObjects.begin(), anObjects.end());
theObjects.insert(theObjects.end(), aCompSolids.begin(), aCompSolids.end());
+ theObjects.insert(theObjects.end(), aCompounds.begin(), aCompounds.end());
// Filter edges and faces in tools.
ListOfShape aTools;
}
}
- if((anObjects.size() + aTools.size() +
+ if((anObjects.size() + aTools.size() + aCompounds.size() +
aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
myFeature->setError("Error: Not enough objects for boolean operation.");
return false;
aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
- // Collecting solids from compsolids which will not be
+ // Collecting solids and compsolids from compounds which will not be
// modified in boolean operation and will be added to result.
ListOfShape aShapesToAdd;
- for(std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
- anIt != aCompSolidsObjects.end(); anIt++) {
+ for (ListOfShape::iterator anIt = aCompounds.begin();
+ anIt != aCompounds.end(); anIt++) {
+ GeomShapePtr aCompound = (*anIt);
+ addSubShapes(aCompound, anObjects, aShapesToAdd);
+ }
+
+ // Collecting solids from compsolids which will not be
+ // modified in boolean operation and will be added to result.
+ for (std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+ anIt != aCompSolidsObjects.end(); anIt++) {
GeomShapePtr aCompSolid = anIt->first;
ListOfShape& aUsedShapes = anIt->second;
- aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end());
-
- // Collect solids from compsolid which will not be modified in boolean operation.
- for (GeomAPI_ShapeIterator aCompSolidIt(aCompSolid);
- aCompSolidIt.more();
- aCompSolidIt.next())
- {
- GeomShapePtr aSolidInCompSolid = aCompSolidIt.current();
- ListOfShape::iterator aUseIt = aUsedShapes.begin();
- for(; aUseIt != aUsedShapes.end(); aUseIt++) {
- if(aSolidInCompSolid->isEqual(*aUseIt)) {
- break;
- }
- }
- if(aUseIt == aUsedShapes.end()) {
- aShapesToAdd.push_back(aSolidInCompSolid);
- }
- }
+ aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end()); //???
+ addSubShapes(aCompSolid, aUsedShapes, aShapesToAdd);
}
// Cut edges and faces(if we have any) with solids.
const GeomShapePtr theResultShapesCompound);
private:
- /// Makes cut operation recursively. Called from makeBoolean().
+ /// Makes cut operation recursively.
+ /// Called from makeBoolean().
/// \param[in] theCompound the shape to be cut.
/// \param[in] theTools list of tools.
/// \param[out] theMakeShapeList list of according algos.
std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theMakeShapeList,
GeomShapePtr& theResult);
+ /// Add subshapes of \a theCompound to \a theSubShapesToAdd list,
+ /// except ones from \a theSubShapesToAvoid.
+ /// Called from makeBoolean().
+ /// \param[in] theCompound the shape to collect sub-shapes of.
+ /// \param[in] theSubShapesToAvoid list of shapes that should not be added to the result.
+ /// \param[out] theSubShapesToAdd list of found sub-shapes.
+ void addSubShapes (const GeomShapePtr theCompound,
+ const ListOfShape& theSubShapesToAvoid,
+ ListOfShape& theSubShapesToAdd);
+
protected:
ModelAPI_Feature* myFeature;
OperationType myOperationType;
$1 = 0;
}
} else
+ if (!PyFloat_Check(item) && PyLong_Check(item))
+ $1 = 0;
+ else
if (!PyUnicode_Check(item) && !PyBool_Check(item))
$1 = 0;
}
%typemap(in) const std::list<FiltersAPI_Argument> & (std::list<FiltersAPI_Argument> temp) {
ModelHighAPI_Selection* temp_selection;
std::string* temp_string;
+ ModelHighAPI_Double* temp_double;
int newmem = 0;
if (PySequence_Check($input)) {
for (Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
PyObject * item = PySequence_GetItem($input, i);
if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_selection, $descriptor(ModelHighAPI_Selection*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
if (!temp_selection) {
- PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string or boolean.");
+ PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string, double or boolean.1");
return NULL;
}
temp.push_back(FiltersAPI_Argument(*temp_selection));
} else
if ((SWIG_ConvertPtrAndOwn(item, (void **)&temp_string, $descriptor(std::string*), SWIG_POINTER_EXCEPTION, &newmem)) == 0) {
if (!temp_string) {
- PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string or boolean.");
+ PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string, double or boolean.2");
return NULL;
}
temp.push_back(FiltersAPI_Argument(*temp_string));
} else
if (PyBool_Check(item)) {
temp.push_back(FiltersAPI_Argument(item == Py_True));
+ } else
+ if (PyFloat_Check(item) || PyLong_Check(item)) {
+ temp.push_back(FiltersAPI_Argument(ModelHighAPI_Double(PyFloat_AsDouble(item))));
} else {
- PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string or boolean.");
+ PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string, double or boolean.4");
return NULL;
}
Py_DECREF(item);
}
$1 = &temp;
} else {
- PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string or boolean.");
+ PyErr_SetString(PyExc_TypeError, "argument must be ModelHighAPI_Selection, string, double or boolean.5");
return NULL;
}
}
{
}
+FiltersAPI_Argument::FiltersAPI_Argument(const ModelHighAPI_Double theValue)
+ : myDouble(theValue)
+{
+}
+
+FiltersAPI_Argument::FiltersAPI_Argument(const double& theValue)
+{
+ myDouble = theValue;
+}
+
FiltersAPI_Argument::FiltersAPI_Argument(const std::string& theValue)
: myValue(theValue)
{
theDumper << "model.selection()"; // mySelectionAttr;
}
else if (mySelection.variantType() == ModelHighAPI_Selection::VT_Empty) {
- if (myValue.empty())
+ if (myDouble.value() > std::numeric_limits<double>::lowest() ) {
+ theDumper << myDouble.value();
+ }
+ else if (myValue.empty()) {
theDumper << myBoolean;
- else
+ }
+ else{
theDumper << "\"" << myValue << "\"";
+ }
}
}
#include "FiltersAPI.h"
#include <ModelAPI_AttributeSelection.h>
+#include <ModelHighAPI_Double.h>
#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Selection.h>
+#include <limits>
+
/**\class FiltersAPI_Argument
* \ingroup CPPHighAPI
* \brief Argument of the Filter
FILTERSAPI_EXPORT
FiltersAPI_Argument(const bool theValue);
+ FILTERSAPI_EXPORT
+ FiltersAPI_Argument(const ModelHighAPI_Double theValue);
+
+ FILTERSAPI_EXPORT
+ FiltersAPI_Argument(const double& theValue);
+
FILTERSAPI_EXPORT
FiltersAPI_Argument(const std::string& theValue);
const bool boolean() const { return myBoolean; }
const std::string& string() const { return myValue; }
const ModelHighAPI_Selection& selection() const { return mySelection; }
-
+ const ModelHighAPI_Double& dble() const { return myDouble; }
/// Dump wrapped feature
FILTERSAPI_EXPORT
void dump(ModelHighAPI_Dumper& theDumper) const;
private:
bool myBoolean;
+ ModelHighAPI_Double myDouble = std::numeric_limits<double>::lowest() ;
std::string myValue;
ModelHighAPI_Selection mySelection;
AttributeSelectionPtr mySelectionAttr;
#include "FiltersAPI_Feature.h"
#include <ModelAPI_Feature.h>
+#include <ModelAPI_FiltersFactory.h>
+#include <ModelAPI_Session.h>
#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Tools.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_FiltersFactory.h>
FiltersAPI_Feature::FiltersAPI_Feature(
const std::shared_ptr<ModelAPI_Feature> & theFeature)
static void separateArguments(const std::list<FiltersAPI_Argument>& theArguments,
std::list<ModelHighAPI_Selection>& theSelections,
std::list<std::string>& theTextArgs,
- std::list<bool>& theBoolArgs)
+ std::list<bool>& theBoolArgs,
+ std::list<ModelHighAPI_Double>& theDoubleArgs)
{
std::list<FiltersAPI_Argument>::const_iterator anIt = theArguments.begin();
for (; anIt != theArguments.end(); ++anIt) {
if (anIt->selection().variantType() != ModelHighAPI_Selection::VT_Empty)
theSelections.push_back(anIt->selection());
- else if (anIt->string().empty())
+ else if (anIt->dble().value() > std::numeric_limits<double>::lowest()) {
+ theDoubleArgs.push_back(anIt->dble());
+ }
+ else if (anIt->string().empty()) {
theBoolArgs.push_back(anIt->boolean());
+ }
else
theTextArgs.push_back(anIt->string());
}
std::list<ModelHighAPI_Selection> aSelections;
std::list<std::string> aTexts;
std::list<bool> aBools;
- separateArguments(anArgs, aSelections, aTexts, aBools);
+ std::list<ModelHighAPI_Double> aDoubles;
+ separateArguments(anArgs, aSelections, aTexts, aBools, aDoubles);
std::list<AttributePtr> aFilterArgs = aBase->filterArgs(aFilterID);
std::list<AttributePtr>::iterator aFIt = aFilterArgs.begin();
if (aReversedFlag)
++aFIt;
// fill arguments of the filter
+ std::list<ModelHighAPI_Double>::const_iterator anItDle = aDoubles.begin();
for (; aFIt != aFilterArgs.end(); ++aFIt) {
AttributeSelectionListPtr aSelList =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aFIt);
else {
AttributeBooleanPtr aBoolean =
std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(*aFIt);
- if (aBoolean && aBools.size() == 1)
- fillAttribute(aBools.front(), aBoolean);
+ if (aBoolean) {
+ if (aBools.size() == 1)
+ fillAttribute(aBools.front(), aBoolean);
+ } else {
+ AttributeDoublePtr aDouble =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*aFIt);
+ if (aDouble) {
+ fillAttribute((*anItDle).value(), aDouble);
+ anItDle++;
+ }
+ }
}
}
}
#include <ModelAPI_Attribute.h>
#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeString.h>
continue;
}
+ AttributeDoublePtr aDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*anArgIt);
+ if (aDouble) {
+ myFilterArguments.push_back(FiltersAPI_Argument(aDouble->value()));
+ continue;
+ }
+
AttributeBooleanPtr aBoolean = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(*anArgIt);
if (aBoolean) {
myFilterArguments.push_back(FiltersAPI_Argument(aBoolean->value()));
FiltersPlugin_RelativeToSolid.h
FiltersPlugin_ExternalFaces.h
FiltersPlugin_Validators.h
+ FiltersPlugin_EdgeSize.h
+ FiltersPlugin_FaceSize.h
+ FiltersPlugin_VolumeSize.h
+ FiltersPlugin_FeatureEdges.h
+ FiltersPlugin_ContinuousFaces.h
)
SET(PROJECT_SOURCES
FiltersPlugin_RelativeToSolid.cpp
FiltersPlugin_ExternalFaces.cpp
FiltersPlugin_Validators.cpp
+ FiltersPlugin_EdgeSize.cpp
+ FiltersPlugin_FaceSize.cpp
+ FiltersPlugin_VolumeSize.cpp
+ FiltersPlugin_FeatureEdges.cpp
+ FiltersPlugin_ContinuousFaces.cpp
)
SET(PROJECT_LIBRARIES
filter-OppositeToEdge.xml
filter-RelativeToSolid.xml
filter-TopoConnectedFaces.xml
+ filter-EdgeSize.xml
+ filter-FaceSize.xml
+ filter-VolumeSize.xml
+ filter-FeatureEdges.xml
+ filter-ContinuousFaces.xml
)
SET(TEXT_RESOURCES
if(${HAVE_SALOME})
enable_testing()
set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/FiltersPlugin")
-
+
install(FILES CTestTestfileInstall.cmake
DESTINATION ${TEST_INSTALL_DIRECTORY}
RENAME CTestTestfile.cmake)
install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
-
+
set(TMP_TESTS_NAMES)
foreach(tfile ${TEST_NAMES})
list(APPEND TMP_TESTS_NAMES "Test/${tfile}")
endforeach(tfile ${TEST_NAMES})
-
+
install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY})
endif(${HAVE_SALOME})
-
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FiltersPlugin_ContinuousFaces.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_Wire.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <map>
+#include <math.h>
+#include <iostream>
+
+typedef std::map<GeomShapePtr, SetOfShapes, GeomAPI_Shape::Comparator> MapShapeAndAncestors;
+
+//=================================================================================================
+static void mapEdgesAndFaces(const GeomShapePtr theShape, MapShapeAndAncestors& theMap)
+{
+ GeomAPI_ShapeExplorer aFExp(theShape, GeomAPI_Shape::FACE);
+ for (; aFExp.more(); aFExp.next()) {
+ GeomShapePtr aFace = aFExp.current();
+ GeomAPI_ShapeExplorer aEExp(aFace, GeomAPI_Shape::EDGE);
+ for (; aEExp.more(); aEExp.next())
+ theMap[aEExp.current()].insert(aFace);
+ }
+}
+
+//=================================================================================================
+// Find all continuous faces for the given.
+static void cacheContinuousFace(const GeomShapePtr theFace,
+ const MapShapeAndAncestors& theEdgeToFaces,
+ SetOfShapes& theCache,
+ const double & theAngle)
+{
+
+ MapShapeAndAncestors::const_iterator aFound;
+ GeomAPI_ShapeExplorer aEExp(theFace, GeomAPI_Shape::EDGE);
+ for (; aEExp.more(); aEExp.next()){
+ aFound = theEdgeToFaces.find(aEExp.current());
+ if (aFound == theEdgeToFaces.end())
+ continue;
+
+ GeomEdgePtr anEdge;
+ anEdge = GeomEdgePtr(new GeomAPI_Edge(aEExp.current()));
+
+ for (SetOfShapes::const_iterator aFIt = aFound->second.begin();
+ aFIt != aFound->second.end(); ++aFIt) {
+ std::string anError = "";
+ if (theCache.find(*aFIt) == theCache.end()) {
+ GeomPointPtr aPoint = anEdge->middlePoint();
+ if (GeomAlgoAPI_ShapeTools::isContinuousFaces(theFace,
+ *aFIt,
+ aPoint,
+ theAngle,
+ anError)) {
+ theCache.insert(*aFIt);
+ cacheContinuousFace(*aFIt, theEdgeToFaces, theCache, theAngle);
+ }
+ }
+ }
+ }
+}
+
+//=================================================================================================
+static void cacheContinuousFaces(const GeomShapePtr theTopLevelShape,
+ const SetOfShapes& theFaces,
+ SetOfShapes& theCache,
+ const double & theAngle)
+{
+ if (!theTopLevelShape || theFaces.empty())
+ return;
+
+ MapShapeAndAncestors anEdgesToFaces;
+ mapEdgesAndFaces(theTopLevelShape, anEdgesToFaces);
+
+ for (SetOfShapes::const_iterator aFIt = theFaces.begin();
+ aFIt != theFaces.end(); ++aFIt) {
+ // keep the original face
+ theCache.insert(*aFIt);
+ // cache continuous face
+ cacheContinuousFace(*aFIt, anEdgesToFaces, theCache,theAngle);
+ }
+}
+
+//=================================================================================================
+static bool updateFaces(const AttributeSelectionListPtr& theList,
+ SetOfShapes& theFaces)
+{
+ bool aNewCache = false;
+ if (theFaces.size() != theList->size()) {
+ aNewCache = true;
+ } else {
+ for (int i = 0; i < theList->size(); i++) {
+ AttributeSelectionPtr aCurAttr = theList->value(i);
+ GeomShapePtr aFace = aCurAttr->value();
+ if (theFaces.empty() || theFaces.find(aFace) == theFaces.end()) {
+ aNewCache = true;
+ break;
+ }
+ }
+ }
+ if (aNewCache) {
+ theFaces.clear();
+ for (int i = 0; i < theList->size(); i++) {
+ AttributeSelectionPtr aCurAttr = theList->value(i);
+ GeomShapePtr aFace = aCurAttr->value();
+ theFaces.insert(aFace);
+ }
+ }
+ return aNewCache;
+}
+
+//=================================================================================================
+bool FiltersPlugin_ContinuousFaces::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::FACE;
+}
+
+//=================================================================================================
+bool FiltersPlugin_ContinuousFaces::isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr aAttr = theArgs.argument("faces");
+ AttributeSelectionListPtr aList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aAttr);
+ if (!aList.get())
+ return false;
+
+ AttributePtr anAttr = theArgs.argument("value");
+ AttributeDoublePtr aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized())
+ return false;
+ double anAngle= aValue->value();
+
+ bool aNewCache = updateFaces(aList,
+ const_cast<FiltersPlugin_ContinuousFaces*>(this)->myFaces);
+
+ if (aNewCache || fabs(myAngle - anAngle) > 1e-10 ) {
+ const_cast<FiltersPlugin_ContinuousFaces*>(this)->myAngle = anAngle;
+ const_cast<FiltersPlugin_ContinuousFaces*>(this)->myCachedShapes.clear();
+ }
+
+ if (myCachedShapes.empty()) {
+ for (size_t i = 0; i < aList->size(); i++)
+ {
+ ResultBodyPtr aBaseResult = ModelAPI_Tools::bodyOwner(aList->value(i)->context(), true);
+ if (!aBaseResult.get()) {
+ aBaseResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aList->value(i)->context());
+ if (!aBaseResult.get())
+ return false;
+ }
+ cacheContinuousFaces(aBaseResult->shape(),
+ const_cast<FiltersPlugin_ContinuousFaces*>(this)->myFaces,
+ const_cast<FiltersPlugin_ContinuousFaces*>(this)->myCachedShapes,anAngle);
+ }
+ }
+ return myCachedShapes.find(theShape) != myCachedShapes.end();
+}
+
+//=================================================================================================
+std::string FiltersPlugin_ContinuousFaces::xmlRepresentation() const
+{
+ return xmlFromFile("filter-ContinuousFaces.xml");
+}
+
+//=================================================================================================
+void FiltersPlugin_ContinuousFaces::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("value", ModelAPI_AttributeDouble::typeId());
+ theArguments.initAttribute("faces", ModelAPI_AttributeSelectionList::typeId());
+}
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FILTERSPLUGIN_CONTINUOUSFACES_H_
+#define FILTERSPLUGIN_CONTINUOUSFACES_H_
+
+#include "FiltersPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Filter.h>
+
+#include <set>
+
+typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShapes;
+
+/**\class FiltersPlugin_ContinuousFaces
+* \ingroup DataModel
+* \brief Filter for face with specific area
+*/
+class FiltersPlugin_ContinuousFaces : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_ContinuousFaces() : ModelAPI_Filter() {
+ myAngle = 0.0;
+ }
+
+ virtual const std::string& name() const {
+ static const std::string kName("Continuous faces");
+ return kName;
+ }
+
+ /// Returns true for face type
+ virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override;
+
+ /// This method should contain the filter logic. It returns true if the given shape
+ /// is accepted by the filter.
+ /// \param theShape the given shape
+ /// \param theArgs arguments of the filter
+ virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+
+ private:
+ /// Original faces selected for filtering
+ SetOfShapes myFaces;
+ /// Shapes applicable for the filter
+ SetOfShapes myCachedShapes;
+ /// Angle tolerance
+ double myAngle;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FiltersPlugin_EdgeSize.h"
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <Precision.hxx>
+
+#include <map>
+#include <cmath>
+
+//=================================================================================================
+bool FiltersPlugin_EdgeSize::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::EDGE;
+}
+
+//=================================================================================================
+bool FiltersPlugin_EdgeSize::isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr anAttr = theArgs.argument("value");
+ AttributeDoublePtr aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized() )
+ return false;
+ double aVal = aValue->value();
+
+ anAttr = theArgs.argument("valueMax");
+ aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized() )
+ return false;
+ double aValMax = aValue->value();
+
+ if (aVal < 0.0)
+ return false;
+
+ GeomEdgePtr anEdge;
+ switch (theShape->shapeType()) {
+ case GeomAPI_Shape::EDGE:
+ anEdge = GeomEdgePtr(new GeomAPI_Edge(theShape));
+ break;
+ case GeomAPI_Shape::WIRE:
+ anEdge = GeomAlgoAPI_ShapeTools::wireToEdge(
+ GeomWirePtr(new GeomAPI_Wire(theShape)));
+ break;
+ default:
+ return false;
+ }
+
+ double aLength = anEdge->length();
+
+ anAttr = theArgs.argument("comparatorType");
+ AttributeStringPtr aCompAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(anAttr);
+ if (!aCompAttr)
+ return false;
+ std::string aCompString = aCompAttr->value();
+
+ bool isOK = false;
+ if (aCompString == "inf")
+ isOK = aLength < aVal - Precision::Confusion();
+ else if (aCompString == "infEq")
+ isOK = aLength < aVal + Precision::Confusion();
+ else if (aCompString == "sup")
+ isOK = aLength > aVal + Precision::Confusion();
+ else if (aCompString == "supEq")
+ isOK = aLength > aVal - Precision::Confusion();
+ else if (aCompString == "isBetween")
+ isOK = aVal <= aValMax
+ && aLength > aVal - Precision::Confusion()
+ && aLength < aValMax + Precision::Confusion();
+ else if (aCompString == "isStrictlyBetween")
+ isOK = aVal <= aValMax
+ && aLength > aVal + Precision::Confusion()
+ && aLength < aValMax - Precision::Confusion();
+ return isOK;
+}
+
+//=================================================================================================
+std::string FiltersPlugin_EdgeSize::xmlRepresentation() const
+{
+ return xmlFromFile("filter-EdgeSize.xml");
+}
+
+//=================================================================================================
+void FiltersPlugin_EdgeSize::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("comparatorType", ModelAPI_AttributeString::typeId());
+ theArguments.initAttribute("value", ModelAPI_AttributeDouble::typeId());
+ theArguments.initAttribute("valueMax", ModelAPI_AttributeDouble::typeId());
+}
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FILTERSPLUGIN_EDGESIZE_H_
+#define FILTERSPLUGIN_EDGESIZE_H_
+
+#include "FiltersPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Filter.h>
+
+/**\class FiltersPlugin_EdgeSize
+* \ingroup DataModel
+* \brief Filter for edges with specific size
+*/
+class FiltersPlugin_EdgeSize : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_EdgeSize() : ModelAPI_Filter() {}
+
+ virtual const std::string& name() const {
+ static const std::string kName("Edge size");
+ return kName;
+ }
+
+ /// Returns true for edge type
+ virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override;
+
+ /// This method should contain the filter logic. It returns true if the given shape
+ /// is accepted by the filter.
+ /// \param theShape the given shape
+ /// \param theArgs arguments of the filter
+ virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FiltersPlugin_FaceSize.h"
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+
+#include <Precision.hxx>
+
+#include <map>
+#include <cmath>
+
+//=================================================================================================
+bool FiltersPlugin_FaceSize::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::FACE;
+}
+
+//=================================================================================================
+bool FiltersPlugin_FaceSize::isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr anAttr = theArgs.argument("value");
+ AttributeDoublePtr aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized() )
+ return false;
+ double aVal = aValue->value();
+
+ anAttr = theArgs.argument("valueMax");
+ aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized() )
+ return false;
+ double aValMax = aValue->value();
+
+ if (aVal < 0.0)
+ return false;
+
+ double aSurfArea = GeomAlgoAPI_ShapeTools::area(theShape);
+
+ anAttr = theArgs.argument("comparatorType");
+ AttributeStringPtr aCompAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(anAttr);
+ if (!aCompAttr)
+ return false;
+ std::string aCompString = aCompAttr->value();
+
+ bool isOK = false;
+ if (aCompString == "inf")
+ isOK = aSurfArea < aVal - Precision::Confusion();
+ else if (aCompString == "infEq")
+ isOK = aSurfArea < aVal + Precision::Confusion();
+ else if (aCompString == "sup")
+ isOK = aSurfArea > aVal + Precision::Confusion();
+ else if (aCompString == "supEq")
+ isOK = aSurfArea > aVal - Precision::Confusion();
+ else if (aCompString == "isBetween")
+ isOK = aVal <= aValMax
+ && aSurfArea > aVal - Precision::Confusion()
+ && aSurfArea < aValMax + Precision::Confusion();
+ else if (aCompString == "isStrictlyBetween")
+ isOK = aVal <= aValMax
+ && aSurfArea > aVal + Precision::Confusion()
+ && aSurfArea < aValMax - Precision::Confusion();
+ return isOK;
+}
+
+//=================================================================================================
+std::string FiltersPlugin_FaceSize::xmlRepresentation() const
+{
+ return xmlFromFile("filter-FaceSize.xml");
+}
+
+//=================================================================================================
+void FiltersPlugin_FaceSize::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("comparatorType", ModelAPI_AttributeString::typeId());
+ theArguments.initAttribute("value", ModelAPI_AttributeDouble::typeId());
+ theArguments.initAttribute("valueMax", ModelAPI_AttributeDouble::typeId());
+}
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FILTERSPLUGIN_FACESIZE_H_
+#define FILTERSPLUGIN_FACESIZE_H_
+
+#include "FiltersPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Filter.h>
+
+
+/**\class FiltersPlugin_FaceSize
+* \ingroup DataModel
+* \brief Filter for face with specific area
+*/
+class FiltersPlugin_FaceSize : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_FaceSize() : ModelAPI_Filter() {}
+
+ virtual const std::string& name() const {
+ static const std::string kName("Face size");
+ return kName;
+ }
+
+ /// Returns true for face type
+ virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override;
+
+ /// This method should contain the filter logic. It returns true if the given shape
+ /// is accepted by the filter.
+ /// \param theShape the given shape
+ /// \param theArgs arguments of the filter
+ virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FiltersPlugin_FeatureEdges.h"
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_Wire.h>
+
+#include <GeomAlgoAPI_ShapeTools.h>
+
+#include <Precision.hxx>
+
+#include <map>
+#include <math.h>
+#include <iostream>
+
+typedef std::map<GeomShapePtr, SetOfShapes, GeomAPI_Shape::Comparator> MapShapeAndAncestors;
+
+//=================================================================================================
+static void mapEdgesAndFaces(const GeomShapePtr theShape, MapShapeAndAncestors& theMap)
+{
+ GeomAPI_ShapeExplorer aFExp(theShape, GeomAPI_Shape::FACE);
+ for (; aFExp.more(); aFExp.next()) {
+ GeomShapePtr aFace = aFExp.current();
+ GeomAPI_ShapeExplorer aEExp(aFace, GeomAPI_Shape::EDGE);
+ for (; aEExp.more(); aEExp.next())
+ theMap[aEExp.current()].insert(aFace);
+ }
+}
+
+//=================================================================================================
+static void cacheFeatureEdge(const GeomShapePtr theTopLevelShape,
+ SetOfShapes& theCache,
+ const double & theAngle)
+{
+ if (!theTopLevelShape)
+ return;
+
+ MapShapeAndAncestors anEdgesToFaces;
+ mapEdgesAndFaces(theTopLevelShape, anEdgesToFaces);
+
+ MapShapeAndAncestors::const_iterator aIt;
+ for (aIt = anEdgesToFaces.begin(); aIt != anEdgesToFaces.end(); ++aIt) {
+ GeomEdgePtr anEdge;
+ anEdge = GeomEdgePtr(new GeomAPI_Edge(aIt->first));
+
+ for (SetOfShapes::const_iterator aFIt = aIt->second.begin();
+ aFIt != aIt->second.end(); ++aFIt) {
+ SetOfShapes::const_iterator aFIt2 = aFIt;
+ ++aFIt2;
+ for (;aFIt2 != aIt->second.end(); ++aFIt2) {
+ std::string anError;
+ if (theCache.find(*aFIt) == theCache.end()) {
+ if (theAngle < Precision::Confusion()
+ || !GeomAlgoAPI_ShapeTools::isContinuousFaces(*aFIt,
+ *aFIt2,
+ anEdge->middlePoint(),
+ theAngle,
+ anError)) {
+ if (anError.empty())
+ theCache.insert(anEdge);
+ }
+ }
+ }
+ }
+ }
+}
+
+//=================================================================================================
+bool FiltersPlugin_FeatureEdges::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::EDGE;
+}
+
+//=================================================================================================
+bool FiltersPlugin_FeatureEdges::isOk(const GeomShapePtr& theShape, const ResultPtr& theResult,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr anAttr = theArgs.argument("value");
+ AttributeDoublePtr aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+
+ if (!aValue.get() || !anAttr->isInitialized())
+ return false;
+ double anAngle = aValue->value();
+
+ // check base result
+ ResultBodyPtr aBaseResult = ModelAPI_Tools::bodyOwner(theResult, true);
+ if (!aBaseResult) {
+ aBaseResult = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (!aBaseResult.get()) {
+ return false;
+ }
+ }
+ if (fabs(myAngle - anAngle) > 1e-10
+ || !myBaseShape
+ || !myBaseShape->isSame(aBaseResult->shape())) {
+ const_cast<FiltersPlugin_FeatureEdges*>(this)->myAngle = anAngle;
+ const_cast<FiltersPlugin_FeatureEdges*>(this)->myBaseShape = aBaseResult->shape();
+ const_cast<FiltersPlugin_FeatureEdges*>(this)->myCachedShapes.clear();
+ }
+
+ if (myCachedShapes.empty()) {
+
+ cacheFeatureEdge(aBaseResult->shape(),
+ const_cast<FiltersPlugin_FeatureEdges*>(this)->myCachedShapes, anAngle);
+ }
+
+ return myCachedShapes.find(theShape) != myCachedShapes.end();
+}
+
+//=================================================================================================
+std::string FiltersPlugin_FeatureEdges::xmlRepresentation() const
+{
+ return xmlFromFile("filter-FeatureEdges.xml");
+}
+
+//=================================================================================================
+void FiltersPlugin_FeatureEdges::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("value", ModelAPI_AttributeDouble::typeId());
+}
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FILTERSPLUGIN_FEATUREEDGES_H_
+#define FILTERSPLUGIN_FEATUREEDGES_H_
+
+#include "FiltersPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Filter.h>
+
+#include <set>
+
+typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShapes;
+
+/**\class FiltersPlugin_FeatureEdges
+* \ingroup DataModel
+* \brief Filter for edges with feature angle
+*/
+class FiltersPlugin_FeatureEdges : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_FeatureEdges() : ModelAPI_Filter() {
+ myAngle = 0.0;
+ }
+
+ virtual const std::string& name() const {
+ static const std::string kName("Feature edges");
+ return kName;
+ }
+
+ /// Returns true for edge type
+ virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override;
+
+ /// This method should contain the filter logic. It returns true if the given shape
+ /// is accepted by the filter.
+ /// \param theShape the given shape
+ /// \param theArgs arguments of the filter
+ virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+
+ private:
+ /// Shapes applicable for the filter
+ SetOfShapes myCachedShapes;
+ /// Angle tolerance
+ double myAngle;
+ /// the base shape
+ GeomShapePtr myBaseShape;
+};
+
+#endif
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include "FiltersPlugin_Plugin.h"
-#include "FiltersPlugin_Selection.h"
-#include "FiltersPlugin_HorizontalFace.h"
-#include "FiltersPlugin_VerticalFace.h"
#include "FiltersPlugin_BelongsTo.h"
-#include "FiltersPlugin_OnPlane.h"
-#include "FiltersPlugin_OnLine.h"
+#include "FiltersPlugin_ContinuousFaces.h"
+#include "FiltersPlugin_EdgeSize.h"
+#include "FiltersPlugin_ExternalFaces.h"
+#include "FiltersPlugin_FaceSize.h"
+#include "FiltersPlugin_FeatureEdges.h"
+#include "FiltersPlugin_HorizontalFace.h"
#include "FiltersPlugin_OnGeometry.h"
+#include "FiltersPlugin_OnLine.h"
+#include "FiltersPlugin_OnPlane.h"
#include "FiltersPlugin_OnPlaneSide.h"
#include "FiltersPlugin_OppositeToEdge.h"
+#include "FiltersPlugin_Plugin.h"
#include "FiltersPlugin_RelativeToSolid.h"
-#include "FiltersPlugin_ExternalFaces.h"
+#include "FiltersPlugin_Selection.h"
#include "FiltersPlugin_Validators.h"
+#include "FiltersPlugin_VerticalFace.h"
+#include "FiltersPlugin_VolumeSize.h"
#include <Config_ModuleReader.h>
aFactory->registerFilter("OppositeToEdge", new FiltersPlugin_OppositeToEdge);
aFactory->registerFilter("RelativeToSolid", new FiltersPlugin_RelativeToSolid);
aFactory->registerFilter("ExternalFaces", new FiltersPlugin_ExternalFaces);
+ aFactory->registerFilter("EdgeSize", new FiltersPlugin_EdgeSize);
+ aFactory->registerFilter("FaceSize", new FiltersPlugin_FaceSize);
+ aFactory->registerFilter("VolumeSize", new FiltersPlugin_VolumeSize);
+ aFactory->registerFilter("FeatureEdges", new FiltersPlugin_FeatureEdges);
+ aFactory->registerFilter("ContinuousFaces", new FiltersPlugin_ContinuousFaces);
Config_ModuleReader::loadScript("FiltersPlugin_TopoConnectedFaces");
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "FiltersPlugin_VolumeSize.h"
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <GeomAlgoAPI_ShapeTools.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+
+#include <Precision.hxx>
+
+#include <map>
+#include <cmath>
+
+//=================================================================================================
+bool FiltersPlugin_VolumeSize::isSupported(GeomAPI_Shape::ShapeType theType) const
+{
+ return theType == GeomAPI_Shape::SOLID;
+}
+
+//=================================================================================================
+bool FiltersPlugin_VolumeSize::isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const
+{
+ AttributePtr anAttr = theArgs.argument("value");
+ AttributeDoublePtr aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized())
+ return false;
+ double aVal = aValue->value();
+
+ anAttr = theArgs.argument("valueMax");
+ aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
+ if (!aValue.get()|| !anAttr->isInitialized())
+ return false;
+ double aValMax = aValue->value();
+
+ if (aVal < 0.0)
+ return false;
+
+ double aVolume = GeomAlgoAPI_ShapeTools::volume(theShape);
+
+ anAttr = theArgs.argument("comparatorType");
+ AttributeStringPtr aCompAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(anAttr);
+ if (!aCompAttr)
+ return false;
+ std::string aCompString = aCompAttr->value();
+
+ bool isOK = false;
+ if (aCompString == "inf")
+ isOK = aVolume < aVal - Precision::Confusion();
+ else if (aCompString == "infEq")
+ isOK = aVolume < aVal + Precision::Confusion();
+ else if (aCompString == "sup")
+ isOK = aVolume > aVal + Precision::Confusion();
+ else if (aCompString == "supEq")
+ isOK = aVolume > aVal - Precision::Confusion();
+ else if (aCompString == "isBetween")
+ isOK = aVal <= aValMax
+ && aVolume > aVal - Precision::Confusion()
+ && aVolume < aValMax + Precision::Confusion();
+ else if (aCompString == "isStrictlyBetween")
+ isOK = aVal <= aValMax
+ && aVolume > aVal + Precision::Confusion()
+ && aVolume < aValMax - Precision::Confusion();
+ return isOK;
+}
+
+//=================================================================================================
+std::string FiltersPlugin_VolumeSize::xmlRepresentation() const
+{
+ return xmlFromFile("filter-VolumeSize.xml");
+}
+
+//=================================================================================================
+void FiltersPlugin_VolumeSize::initAttributes(ModelAPI_FiltersArgs& theArguments)
+{
+ theArguments.initAttribute("comparatorType", ModelAPI_AttributeString::typeId());
+ theArguments.initAttribute("value", ModelAPI_AttributeDouble::typeId());
+ theArguments.initAttribute("valueMax", ModelAPI_AttributeDouble::typeId());
+}
--- /dev/null
+// Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef FILTERSPLUGIN_VOLUMESIZE_H_
+#define FILTERSPLUGIN_VOLUMESIZE_H_
+
+#include "FiltersPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <ModelAPI_Filter.h>
+
+
+/**\class FiltersPlugin_VolumeSize
+* \ingroup DataModel
+* \brief Filter for solid with specific volume
+*/
+class FiltersPlugin_VolumeSize : public ModelAPI_Filter
+{
+public:
+ FiltersPlugin_VolumeSize() : ModelAPI_Filter() {}
+
+ virtual const std::string& name() const {
+ static const std::string kName("Volume size");
+ return kName;
+ }
+
+ /// Returns true for solid type
+ virtual bool isSupported(GeomAPI_Shape::ShapeType theType) const override;
+
+ /// This method should contain the filter logic. It returns true if the given shape
+ /// is accepted by the filter.
+ /// \param theShape the given shape
+ /// \param theArgs arguments of the filter
+ virtual bool isOk(const GeomShapePtr& theShape, const ResultPtr&,
+ const ModelAPI_FiltersArgs& theArgs) const override;
+
+ /// Returns XML string which represents GUI of the filter
+ virtual std::string xmlRepresentation() const override;
+
+ /// Initializes arguments of a filter.
+ virtual void initAttributes(ModelAPI_FiltersArgs& theArguments) override;
+
+};
+
+#endif
<source>Belongs to</source>
<translation>Appartient à</translation>
</message>
+ <message>
+ <source>Edge size</source>
+ <translation>Taille d'arête</translation>
+ </message>
<message>
<source>External faces</source>
<translation>Externe faces</translation>
</message>
+ <message>
+ <source>Continuous faces</source>
+ <translation>Faces continues</translation>
+ </message>
+ <message>
+ <source>Feature edges</source>
+ <translation>Arêtes caractéristiques</translation>
+ </message>
+ <message>
+ <source>Face size</source>
+ <translation>Surface de face</translation>
+ </message>
<message>
<source>Horizontal faces</source>
<translation>Faces horizontales</translation>
<source>Vertical faces</source>
<translation>Faces verticales</translation>
</message>
+ <message>
+ <source>Volume size</source>
+ <translation>volume</translation>
+ </message>
<message>
<source>Attribute "%1" is not initialized.</source>
<translation>Sélectionnez un objet.</translation>
</message>
</context>
+ <!-- Edge size -->
+ <context>
+ <name>EdgeSize</name>
+ <message>
+ <source>Size</source>
+ <translation>Longueur</translation>
+ </message>
+ <message>
+ <source>Min size</source>
+ <translation>Longueur Min</translation>
+ </message>
+ <message>
+ <source>Max size</source>
+ <translation>Longueur Max</translation>
+ </message>
+ <message>
+ <source>is between</source>
+ <translation>est compris entre</translation>
+ </message>
+ <message>
+ <source>is strictly between</source>
+ <translation>est compris strictement entre</translation>
+ </message>
+ </context>
+
+ <!-- Face size -->
+ <context>
+ <name>FaceSize</name>
+ <message>
+ <source>Size</source>
+ <translation>Longueur</translation>
+ </message>
+ <message>
+ <source>Min size</source>
+ <translation>Longueur Min</translation>
+ </message>
+ <message>
+ <source>Max size</source>
+ <translation>Longueur Max</translation>
+ </message>
+ <message>
+ <source>is between</source>
+ <translation>est compris entre</translation>
+ </message>
+ <message>
+ <source>is strictly between</source>
+ <translation>est compris strictement entre</translation>
+ </message>
+ </context>
+
+ <!-- Volume size -->
+ <context>
+ <name>VolumeSize</name>
+ <message>
+ <source>Size</source>
+ <translation>Longueur</translation>
+ </message>
+ <message>
+ <source>Min size</source>
+ <translation>Longueur min</translation>
+ </message>
+ <message>
+ <source>Max size</source>
+ <translation>Longueur max</translation>
+ </message>
+ <message>
+ <source>is between</source>
+ <translation>est compris entre</translation>
+ </message>
+ <message>
+ <source>is strictly between</source>
+ <translation>est compris strictement entre</translation>
+ </message>
+ </context>
+
<!-- OnGeometry -->
<context>
<name>OnGeometry</name>
--- /dev/null
+# Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from SketchAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+
+###===========Test with fillet on solide===========================================================
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Fillet
+Fillet_1_objects_4 = [model.selection("FACE", "Box_1_1/Left"),
+ model.selection("FACE", "Box_1_1/Front"),
+ model.selection("FACE", "Box_1_1/Top"),
+ model.selection("FACE", "Box_1_1/Right"),
+ model.selection("FACE", "Box_1_1/Bottom")]
+Fillet_1 = model.addFillet(Part_1_doc, Fillet_1_objects_4, 2, keepSubResults = True)
+
+model.end()
+
+model.do()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "ContinuousFaces", args = [model.selection("FACE", "Fillet_1_1/MF:Fillet&Box_1_1/Left"), 5.0 ])])
+model.end()
+
+Reference = {}
+ResultFillet_1_1 = Fillet_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultFillet_1_1.shape(), GeomAPI_Shape.FACE)
+while exp.more():
+ Reference[model.selection(ResultFillet_1_1, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+###===========Test with Chamfer by an angle of 43° on solid and filters with angle 50 ===========
+
+### Create Part
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+
+### Create Box
+Box_3 = model.addBox(Part_2_doc, 10, 10, 10)
+
+### Create Chamfer
+Chamfer_1_objects = [model.selection("FACE", "Box_1_1/Left"),
+ model.selection("FACE", "Box_1_1/Front"),
+ model.selection("FACE", "Box_1_1/Top"),
+ model.selection("FACE", "Box_1_1/Right"),
+ model.selection("FACE", "Box_1_1/Bottom")]
+Chamfer_2 = model.addChamfer(Part_2_doc, Chamfer_1_objects, False, 2, 43, keepSubResults = True)
+
+model.end()
+
+model.do()
+Filters = model.filters(Part_2_doc, [model.addFilter(name = "ContinuousFaces", args = [model.selection("FACE", "Chamfer_1_1/MF:Chamfer&Box_1_1/Left"), 50.0 ])])
+model.end()
+
+Reference = {}
+ResultChamfer_2_1 = Chamfer_2.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultChamfer_2_1.shape(), GeomAPI_Shape.FACE)
+while exp.more():
+ Reference[model.selection(ResultChamfer_2_1, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_2_doc, model, Filters, Reference)
--- /dev/null
+# Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from SketchAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 100, 50, 100)
+
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "inf" , 60.0 ])])
+
+model.end()
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "sup" , 60.0 ])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "inf" , 50.0 ])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "infEq" , 50.0 ])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "supEq" , 50.0 ])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "isBetween" , 50.0 , 200.0])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "EdgeSize", args = [ "isStrictlyBetween" , 50.0 , 200.0])])
+model.end()
+
+Reference = {
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"): False,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]"): False,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"): True,
+ model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"): True,
+ model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"): True,
+ model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
--- /dev/null
+# Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from SketchAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 100, 50, 100)
+
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "inf" , 5000.0 ])])
+
+model.end()
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): False,
+ model.selection("FACE", "Box_1_1/Back"): False,
+ model.selection("FACE", "Box_1_1/Front"): False,
+ model.selection("FACE", "Box_1_1/Bottom"): False,
+ model.selection("FACE","Box_1_1/Right"): False,
+ model.selection("FACE","Box_1_1/Left"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "infEq" , 5000.0 ])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): True,
+ model.selection("FACE", "Box_1_1/Back"): True,
+ model.selection("FACE", "Box_1_1/Front"): True,
+ model.selection("FACE", "Box_1_1/Bottom"): True,
+ model.selection("FACE", "Box_1_1/Right"): False,
+ model.selection("FACE", "Box_1_1/Left"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "sup" , 5000.0 ])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): False,
+ model.selection("FACE", "Box_1_1/Back"): False,
+ model.selection("FACE", "Box_1_1/Front"): False,
+ model.selection("FACE", "Box_1_1/Bottom"): False,
+ model.selection("FACE", "Box_1_1/Right"): True,
+ model.selection("FACE", "Box_1_1/Left"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "inf" , 50.0 ])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): False,
+ model.selection("FACE", "Box_1_1/Back"): False,
+ model.selection("FACE", "Box_1_1/Front"): False,
+ model.selection("FACE", "Box_1_1/Bottom"): False,
+ model.selection("FACE", "Box_1_1/Right"): False,
+ model.selection("FACE", "Box_1_1/Left"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "supEq" , 5000.0 ])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): True,
+ model.selection("FACE", "Box_1_1/Back"): True,
+ model.selection("FACE", "Box_1_1/Front"): True,
+ model.selection("FACE", "Box_1_1/Bottom"): True,
+ model.selection("FACE", "Box_1_1/Right"): True,
+ model.selection("FACE", "Box_1_1/Left"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "supEq" , 7000.0 ])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): False,
+ model.selection("FACE", "Box_1_1/Back"): False,
+ model.selection("FACE", "Box_1_1/Front"): False,
+ model.selection("FACE", "Box_1_1/Bottom"): False,
+ model.selection("FACE", "Box_1_1/Right"): True,
+ model.selection("FACE", "Box_1_1/Left"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "isBetween" , 50.0 , 10000.0])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): True,
+ model.selection("FACE", "Box_1_1/Back"): True,
+ model.selection("FACE", "Box_1_1/Front"): True,
+ model.selection("FACE", "Box_1_1/Bottom"): True,
+ model.selection("FACE", "Box_1_1/Right"): True,
+ model.selection("FACE", "Box_1_1/Left"): True}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FaceSize", args = [ "isStrictlyBetween" , 500.0 , 10000.0])])
+model.end()
+
+Reference = {
+ model.selection("FACE", "Box_1_1/Top"): True,
+ model.selection("FACE", "Box_1_1/Back"): True,
+ model.selection("FACE", "Box_1_1/Front"): True,
+ model.selection("FACE", "Box_1_1/Bottom"): True,
+ model.selection("FACE", "Box_1_1/Right"): False,
+ model.selection("FACE", "Box_1_1/Left"): False}
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
--- /dev/null
+# Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from SketchAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+
+###===========Test with chamfer on face=========================================================
+
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+
+### Create Chamfer
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("FACE", "Box_1_1/Left")], True, 2, 2, keepSubResults = True)
+
+model.do()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "FeatureEdges", args = [ 5.0 ])])
+model.end()
+
+Reference = {}
+ResultChamfer_1_1 = Chamfer_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultChamfer_1_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultChamfer_1_1, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.do()
+
+###===========Test with fillet on solide===========================================================
+
+### Create Part
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+
+### Create Box
+Box_2 = model.addBox(Part_2_doc, 10, 10, 10)
+
+### Create Fillet
+Fillet_1_objects_4 = [model.selection("FACE", "Box_1_1/Left"),
+ model.selection("FACE", "Box_1_1/Front"),
+ model.selection("FACE", "Box_1_1/Top"),
+ model.selection("FACE", "Box_1_1/Right"),
+ model.selection("FACE", "Box_1_1/Bottom")]
+Fillet_1 = model.addFillet(Part_2_doc, Fillet_1_objects_4, 2, keepSubResults = True)
+
+model.end()
+
+model.do()
+Filters = model.filters(Part_2_doc, [model.addFilter(name = "FeatureEdges", args = [ 5.0 ])])
+model.end()
+
+
+###===========Test with Chamfer by an angle of 43° and filters with angle 30 and 50 ===========
+Reference = {}
+ResultFillet_1_1 = Fillet_1.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultFillet_1_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultFillet_1_1, exp.current())] = False
+ exp.next()
+model.checkFilter(Part_2_doc, model, Filters, Reference)
+
+### Create Part
+Part_3 = model.addPart(partSet)
+Part_3_doc = Part_3.document()
+
+### Create Box
+Box_3 = model.addBox(Part_3_doc, 10, 10, 10)
+
+### Create Chamfer
+Chamfer_1_objects = [model.selection("FACE", "Box_1_1/Left"),
+ model.selection("FACE", "Box_1_1/Front"),
+ model.selection("FACE", "Box_1_1/Top"),
+ model.selection("FACE", "Box_1_1/Right"),
+ model.selection("FACE", "Box_1_1/Bottom")]
+Chamfer_2 = model.addChamfer(Part_3_doc, Chamfer_1_objects, False, 2, 43, keepSubResults = True)
+
+model.end()
+
+model.do()
+Filters = model.filters(Part_3_doc, [model.addFilter(name = "FeatureEdges", args = [ 30.0 ])])
+model.end()
+
+Reference = {}
+ResultChamfer_2_1 = Chamfer_2.result().resultSubShapePair()[0]
+exp = GeomAPI_ShapeExplorer(ResultChamfer_2_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultChamfer_2_1, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_3_doc, model, Filters, Reference)
+
+model.do()
+Filters = model.filters(Part_3_doc, [model.addFilter(name = "FeatureEdges", args = [ 50.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultChamfer_2_1.shape(), GeomAPI_Shape.EDGE)
+while exp.more():
+ Reference[model.selection(ResultChamfer_2_1, exp.current())] = False
+ exp.next()
+model.checkFilter(Part_3_doc, model, Filters, Reference)
--- /dev/null
+# Copyright (C) 2014-2021 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from SketchAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+### Create Part
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+### Create Box
+Box_1 = model.addBox(Part_1_doc, 100, 50, 100)
+
+### Create Point
+Point_1 = model.addPoint(Part_1_doc, 100, 0, 0)
+
+### Create Point
+Point_2 = model.addPoint(Part_1_doc, 250, 50, 100)
+
+### Create Box
+Box_2 = model.addBox(Part_1_doc, model.selection("VERTEX", "all-in-Point_1"), model.selection("VERTEX", "all-in-Point_2"))
+
+### Create Point
+Point_3 = model.addPoint(Part_1_doc, 100, 50, 250)
+
+### Create Box
+Box_3 = model.addBox(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "Point_3"))
+
+### Create CompSolid
+CompSolid_1_objects = [model.selection("SOLID", "Box_3_1"),
+ model.selection("SOLID", "Box_2_1"),
+ model.selection("SOLID", "Box_1_1")]
+CompSolid_1 = model.addCompSolid(Part_1_doc, CompSolid_1_objects)
+
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "inf" , 500000.0 ])])
+
+model.end()
+
+Reference = {}
+ResultCompSolid_1 = CompSolid_1.result().resultSubShapePair()[0]
+ResultBox_1 = Box_1.result().resultSubShapePair()[0]
+ResultBox_2 = Box_2.result().resultSubShapePair()[0]
+ResultBox_3 = Box_3.result().resultSubShapePair()[0]
+
+exp = GeomAPI_ShapeExplorer(ResultCompSolid_1.shape(), GeomAPI_Shape.SOLID)
+while exp.more():
+ Reference[model.selection(ResultCompSolid_1, exp.current())] = False
+ exp.next()
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "infEq" , 500000.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_1, exp.current())] = True
+exp = GeomAPI_ShapeExplorer(ResultBox_2.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_2, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_3.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_3, exp.current())] = False
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "sup" , 500000.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_1, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_2.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_2, exp.current())] = True
+exp = GeomAPI_ShapeExplorer(ResultBox_3.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_3, exp.current())] = True
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "inf" , 50.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_1, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_2.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_2, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_3.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_3, exp.current())] = False
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "supEq" , 500000.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultCompSolid_1.shape(), GeomAPI_Shape.SOLID)
+while exp.more():
+ Reference[model.selection(ResultCompSolid_1, exp.current())] = True
+ exp.next()
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "supEq" , 800000.0 ])])
+model.end()
+
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultCompSolid_1.shape(), GeomAPI_Shape.SOLID)
+while exp.more():
+ Reference[model.selection(ResultCompSolid_1, exp.current())] = False
+ exp.next()
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "isBetween" , 50.0 , 600000.0])])
+model.end()
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_1, exp.current())] = True
+exp = GeomAPI_ShapeExplorer(ResultBox_2.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_2, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_3.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_3, exp.current())] = False
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
+
+model.begin()
+Filters = model.filters(Part_1_doc, [model.addFilter(name = "VolumeSize", args = [ "isStrictlyBetween" , 500.0 , 750000.0])])
+model.end()
+Reference = {}
+exp = GeomAPI_ShapeExplorer(ResultBox_1.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_1, exp.current())] = True
+exp = GeomAPI_ShapeExplorer(ResultBox_2.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_2, exp.current())] = False
+exp = GeomAPI_ShapeExplorer(ResultBox_3.shape(), GeomAPI_Shape.SOLID)
+Reference[model.selection(ResultBox_3, exp.current())] = False
+
+model.checkFilter(Part_1_doc, model, Filters, Reference)
FILTER_HORIZONTAL_FACES = "HorizontalFaces"
FILTER_VERTICAL_FACES = "VerticalFaces"
FILTER_CONNECTED_FACES = "TopoConnectedFaces"
+FILTER_EDGE_SIZE = "EdgeSize"
+FILTER_FACE_SIZE = "FaceSize"
+FILTER_VOLUME_SIZE = "VolumeSize"
+FILTER_FEATURE_EDGES = "FeatureEdges"
+FILTER_CONTINUOUS_FACES= "ContinuousFaces"
# Reference data (supported filters) for each type of shape
Reference = {
GeomAPI_Shape.VERTEX : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_LINE, FILTER_ON_PLANE_SIDE, FILTER_RELATIVE_TO_SOLID],
- GeomAPI_Shape.EDGE : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_LINE, FILTER_ON_GEOMETRY, FILTER_ON_PLANE_SIDE, FILTER_OPPOSITE_TO_EDGE, FILTER_RELATIVE_TO_SOLID],
+ GeomAPI_Shape.EDGE : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_LINE, FILTER_ON_GEOMETRY, FILTER_ON_PLANE_SIDE, FILTER_OPPOSITE_TO_EDGE, FILTER_RELATIVE_TO_SOLID, FILTER_EDGE_SIZE, FILTER_FEATURE_EDGES],
GeomAPI_Shape.WIRE : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_PLANE_SIDE, FILTER_RELATIVE_TO_SOLID],
- GeomAPI_Shape.FACE : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_GEOMETRY, FILTER_ON_PLANE_SIDE, FILTER_RELATIVE_TO_SOLID, FILTER_EXTERNAL_FACES, FILTER_HORIZONTAL_FACES, FILTER_VERTICAL_FACES, FILTER_CONNECTED_FACES],
+ GeomAPI_Shape.FACE : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_GEOMETRY, FILTER_ON_PLANE_SIDE, FILTER_RELATIVE_TO_SOLID, FILTER_EXTERNAL_FACES, FILTER_HORIZONTAL_FACES, FILTER_VERTICAL_FACES, FILTER_CONNECTED_FACES, FILTER_FACE_SIZE, FILTER_CONTINUOUS_FACES],
GeomAPI_Shape.SHELL : [FILTER_BELONGS_TO, FILTER_ON_PLANE, FILTER_ON_PLANE_SIDE, FILTER_RELATIVE_TO_SOLID],
- GeomAPI_Shape.SOLID : [FILTER_BELONGS_TO, FILTER_ON_PLANE_SIDE],
+ GeomAPI_Shape.SOLID : [FILTER_BELONGS_TO, FILTER_ON_PLANE_SIDE, FILTER_VOLUME_SIZE],
}
model.begin()
- **Argument:** Any result object, multiple OR selection accepted
- **Algorithm:** Returns only shapes that belong to selected results.
+**Edge size**
+
+- **Result type:** Edge
+- **Argument:**
+ - **Comparator:** <, <=, >, >=, is between, is strictly between
+ - **Size** or **Min size** and **Max size**
+- **Algorithm:** Returns all edges whose length respect comparator rules.
+
+**Face size**
+
+- **Result type:** Face
+- **Argument:**
+ - **Comparator:** <, <=, >, >=, is between, is strictly between
+ - **Size** or **Min size** and **Max size**
+- **Algorithm:** Returns all faces whose area respect comparator rules.
+
+**Volume size**
+
+- **Result type:** Solid
+- **Argument:**
+ - **Comparator:** <, <=, >, >=, is between, is strictly between
+ - **Size** or **Min size** and **Max size**
+- **Algorithm:** Returns all solids whose volume respect comparator rules.
+
+**Feature edges**
+
+This algorithm identifies edges between two faces discontinuous with an angular tolerance.
+
+- **Result type:** Edge
+- **Argument:**
+ - **Angle** an angular tolerance used by G1 continuity criterion for comparing the angle between the normals
+- **Algorithm:** Returns all edges between two discontinuous faces.
+
**On a plane**
- **Result type:** Vertex, Edge, Face
- **Argument:** An edge belonging to a quadrangular face
- **Algorithm:** Returns all Edges opposite to the given Edge on all quadrangular faces connected to this Edge. The algorithm is recursive: after an edge is found on one face, it adds edges opposite to this new one.
+**Continuous Faces**
+
+This algorithm identifies continuous faces with an angular tolerance given by topological propagation.
+
+- **Result type:** Face
+- **Argument:**
+ - **Angle:** an angular tolerance used by G1 continuity criterion for comparing the angle between the normals.
+ - **Faces:** Faces to start the propagation.
+- **Algorithm:** Returns continuous faces.
+
**On/In/Out a Solid**
This algorithm reproduces the GetShapesOnShape function of geompy.
--- /dev/null
+<filter id="ContinuousFaces">
+ <doublevalue id="ContinuousFaces__value"
+ label="Angle"
+ min="0"
+ step="0.1"
+ default="5"
+ tooltip="Continuity angle">
+ </doublevalue>
+ <multi_selector id="ContinuousFaces__faces"
+ label="Faces:"
+ tooltip="Select faces"
+ shape_types="faces">
+ <validator id="GeomValidators_ShapeType" parameters="face"/>
+ </multi_selector>
+</filter>
--- /dev/null
+<filter id="EdgeSize">
+ <switch id="EdgeSize__comparatorType">
+ <case id="inf" title="<">
+ <doublevalue id="EdgeSize__value"
+ label="Size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip="< to">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="infEq" title="<=">
+ <doublevalue id="EdgeSize__value"
+ label="Size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip="<= to">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="sup" title=">">
+ <doublevalue id="EdgeSize__value"
+ label="Size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip="> to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="supEq" title=">=">
+ <doublevalue id="EdgeSize__value"
+ label="Size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip=">= to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="isBetween" title="is between">
+ <doublevalue id="EdgeSize__value"
+ label="Min size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="EdgeSize__valueMax"
+ label="Max size"
+ min="0"
+ step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="isStrictlyBetween" title="is strictly between">
+ <doublevalue id="EdgeSize__value"
+ label="Min size"
+ min="0"
+ step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="EdgeSize__valueMax"
+ label="Max size"
+ min="0"
+ step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive" />
+ </doublevalue>
+ </case>
+ </switch>
+</filter>
--- /dev/null
+<filter id="FaceSize">
+ <switch id="FaceSize__comparatorType">
+ <case id="inf" title="<">
+ <doublevalue id="FaceSize__value"
+ label="Size"
+ min="0"
+ default="1"
+ tooltip="< to">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="infEq" title="<=">
+ <doublevalue id="FaceSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="<= to">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="sup" title=">">
+ <doublevalue id="FaceSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="> to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="supEq" title=">=">
+ <doublevalue id="FaceSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip=">= to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="isBetween" title="is between">
+ <doublevalue id="FaceSize__value"
+ label="Min size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="FaceSize__valueMax"
+ label="Max size"
+ min="0" step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="isStrictlyBetween" title="is strictly between">
+ <doublevalue id="FaceSize__value"
+ label="Min size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="FaceSize__valueMax"
+ label="Max size"
+ min="0" step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ </switch>
+</filter>
--- /dev/null
+<filter id="FeatureEdges">
+ <doublevalue id="FeatureEdges__value"
+ label="Angle"
+ min="0"
+ step="0.1"
+ default="5"
+ tooltip="Edge angle">
+ </doublevalue>
+</filter>
--- /dev/null
+<filter id="VolumeSize">
+ <switch id="VolumeSize__comparatorType">
+ <case id="inf" title="<">
+ <doublevalue id="VolumeSize__value"
+ label="Size"
+ min="0"
+ default="1"
+ tooltip="< to">
+ <validator id="GeomValidators_Positive" />
+ </doublevalue>
+ </case>
+ <case id="infEq" title="<=">
+ <doublevalue id="VolumeSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="<= to">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="sup" title=">">
+ <doublevalue id="VolumeSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="> to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="supEq" title=">=">
+ <doublevalue id="VolumeSize__value"
+ label="Size"
+ min="0" step="0.1"
+ default="1"
+ tooltip=">="> to">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ </case>
+ <case id="isBetween" title="is between">
+ <doublevalue id="VolumeSize__value"
+ label="Min size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="VolumeSize__valueMax"
+ label="Max size"
+ min="0" step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ <case id="isStrictlyBetween" title="is strictly between">
+ <doublevalue id="VolumeSize__value"
+ label="Min size"
+ min="0" step="0.1"
+ default="1"
+ tooltip="Min value">
+ <validator id="GeomValidators_Positive" parameters="-1.e-10"/>
+ </doublevalue>
+ <doublevalue id="VolumeSize__valueMax"
+ label="Max size"
+ min="0" step="0.1"
+ default="10"
+ tooltip="Max value">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue>
+ </case>
+ </switch>
+</filter>
Test17924.py
Test17962.py
Test19190.py
+ TestFilter_FaceSize.py
+ TestFilter_EdgeSize.py
+ TestFilter_FeatureEdges.py
+ TestFilter_ContinuousFaces.py
+ TestFilter_VolumeSize.py
)
#include <NCollection_Vector.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
+
//==================================================================================================
static GProp_GProps props(const TopoDS_Shape& theShape)
{
double GeomAlgoAPI_ShapeTools::length(const std::shared_ptr<GeomAPI_Shape> theShape)
{
GProp_GProps aGProps;
- if(!theShape.get()) {
+ if (!theShape.get()) {
return 0.0;
}
const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
- if(aShape.IsNull()) {
+ if (aShape.IsNull()) {
return 0.0;
}
//==================================================================================================
double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
{
- if(!theShape.get()) {
+ if (!theShape.get()) {
return 0.0;
}
const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
- if(aShape.IsNull()) {
+ if (aShape.IsNull()) {
return 0.0;
}
const Standard_Real anEps = 1.e-6;
double GeomAlgoAPI_ShapeTools::area (const std::shared_ptr<GeomAPI_Shape> theShape)
{
GProp_GProps aGProps;
- if(!theShape.get()) {
+ if (!theShape.get()) {
return 0.0;
}
const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
- if(aShape.IsNull()) {
+ if (aShape.IsNull()) {
return 0.0;
}
const Standard_Real anEps = 1.e-6;
return aGProps.Mass();
}
+//==================================================================================================
+bool GeomAlgoAPI_ShapeTools::isContinuousFaces(const GeomShapePtr& theFace1,
+ const GeomShapePtr& theFace2,
+ const GeomPointPtr& thePoint,
+ const double & theAngle,
+ std::string& theError)
+{
+
+ #ifdef _DEBUG
+ std::cout << "isContinuousFaces " << std::endl;
+ #endif
+
+ if (!thePoint.get()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+ const gp_Pnt& aPoint = thePoint->impl<gp_Pnt>();
+
+ // Getting base shape.
+ if (!theFace1.get()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ TopoDS_Shape aShape1 = theFace1->impl<TopoDS_Shape>();
+
+ if (aShape1.IsNull()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ // Getting base shape.
+ if (!theFace2.get()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ TopoDS_Shape aShape2 = theFace2->impl<TopoDS_Shape>();
+
+ if (aShape2.IsNull()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ TopoDS_Face aFace1 = TopoDS::Face(aShape1);
+ if (aFace1.IsNull()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(aFace1);
+ if (aSurf1.IsNull()) {
+ theError = "isContinuousFaces : An invalid surface";
+ return false;
+ }
+
+ ShapeAnalysis_Surface aSAS1(aSurf1);
+ gp_Pnt2d aPointOnFace1 = aSAS1.ValueOfUV(aPoint, Precision::Confusion());
+
+ TopoDS_Face aFace2 = TopoDS::Face(aShape2);
+ if (aFace2.IsNull()) {
+ theError = "isContinuousFaces : An invalid argument";
+ return false;
+ }
+
+ Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(aFace2);
+ if (aSurf2.IsNull()) {
+ theError = "isContinuousFaces : An invalid surface";
+ return false;
+ }
+
+ ShapeAnalysis_Surface aSAS2(aSurf2);
+ gp_Pnt2d aPointOnFace2= aSAS2.ValueOfUV(aPoint, Precision::Confusion());
+
+ bool aRes = false;
+ try {
+ OCC_CATCH_SIGNALS;
+ LocalAnalysis_SurfaceContinuity aLocAnal(aSurf1,
+ aPointOnFace1.X(),
+ aPointOnFace1.Y(),
+ aSurf2,
+ aPointOnFace2.X(),
+ aPointOnFace2.Y(),
+ GeomAbs_Shape::GeomAbs_G1, // Order
+ 0.001, // EpsNul
+ 0.001, // EpsC0
+ 0.001, // EpsC1
+ 0.001, // EpsC2
+ theAngle * M_PI / 180.0); //EpsG1
+ aRes = aLocAnal.IsG1();
+ }
+ catch (Standard_Failure const& anException) {
+ theError = "LocalAnalysis_SurfaceContinuity error :";
+ theError += anException.GetMessageString();
+ }
+
+ return aRes;
+}
+
//==================================================================================================
std::shared_ptr<GeomAPI_Pnt>
GeomAlgoAPI_ShapeTools::centreOfMass(const std::shared_ptr<GeomAPI_Shape> theShape)
{
GProp_GProps aGProps;
- if(!theShape) {
+ if (!theShape) {
return std::shared_ptr<GeomAPI_Pnt>();
}
const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
- if(aShape.IsNull()) {
+ if (aShape.IsNull()) {
return std::shared_ptr<GeomAPI_Pnt>();
}
gp_Pnt aCentre;
- if(aShape.ShapeType() == TopAbs_VERTEX) {
+ if (aShape.ShapeType() == TopAbs_VERTEX) {
aCentre = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
} else {
aGProps = props(aShape);
GeomShapePtr aResult = theCompound;
- if(!theCompound.get()) {
+ if (!theCompound.get()) {
return aResult;
}
- if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
+ if (theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) {
return aResult;
}
TopAbs_ShapeEnum aTS = TopAbs_EDGE;
TopAbs_ShapeEnum aTA = TopAbs_FACE;
- if(theType == GeomAPI_Shape::COMPSOLID) {
+ if (theType == GeomAPI_Shape::COMPSOLID) {
aTS = TopAbs_FACE;
aTA = TopAbs_SOLID;
}
// Get free shapes.
int anOrder = 0;
const TopoDS_Shape& aShapesComp = theCompound->impl<TopoDS_Shape>();
- for(TopoDS_Iterator anIter(aShapesComp); anIter.More(); anIter.Next(), anOrder++) {
+ for (TopoDS_Iterator anIter(aShapesComp); anIter.More(); anIter.Next(), anOrder++) {
const TopoDS_Shape& aShape = anIter.Value();
- if(aShape.ShapeType() > aTA) {
+ if (aShape.ShapeType() > aTA) {
std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
aResFreeShapes.push_back(aGeomShape);
anInputOrder[aGeomShape] = anOrder;
} else {
- for(TopExp_Explorer anExp(aShape, aTA); anExp.More(); anExp.Next()) {
+ for (TopExp_Explorer anExp(aShape, aTA); anExp.More(); anExp.Next()) {
anAncestorsOrder.Bind(anExp.Current(), anOrder);
}
}
// Map sub-shapes and shapes.
TopTools_IndexedDataMapOfShapeListOfShape aMapSA;
TopExp::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapSA);
- if(aMapSA.IsEmpty()) {
+ if (aMapSA.IsEmpty()) {
return aResult;
}
theResuts.clear();
// Get all shapes with common sub-shapes and free shapes.
NCollection_Map<TopoDS_Shape> aFreeShapes;
NCollection_Vector<NCollection_Map<TopoDS_Shape>> aShapesWithCommonSubshapes;
- for(TopTools_IndexedDataMapOfShapeListOfShape::Iterator
+ for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator
anIter(aMapSA); anIter.More(); anIter.Next()) {
TopTools_ListOfShape& aListOfShape = anIter.ChangeValue();
- if(aListOfShape.IsEmpty()) {
+ if (aListOfShape.IsEmpty()) {
continue;
}
- else if(aListOfShape.Size() == 1) {
+ else if (aListOfShape.Size() == 1) {
const TopoDS_Shape& aF = aListOfShape.First();
aFreeShapes.Add(aF);
aListOfShape.Clear();
aFreeShapes.Remove(aListIt.Value());
}
aListOfShape.Clear();
- for(NCollection_List<TopoDS_Shape>::Iterator
+ for (NCollection_List<TopoDS_Shape>::Iterator
aTempIter(aTempList); aTempIter.More(); aTempIter.Next()) {
const TopoDS_Shape& aTempShape = aTempIter.Value();
- for(TopTools_IndexedDataMapOfShapeListOfShape::Iterator
+ for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator
anIter2(aMapSA); anIter2.More(); anIter2.Next()) {
TopTools_ListOfShape& aTempListOfShape = anIter2.ChangeValue();
- if(aTempListOfShape.IsEmpty()) {
+ if (aTempListOfShape.IsEmpty()) {
continue;
- } else if(aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) {
+ } else if (aTempListOfShape.Size() == 1 && aTempListOfShape.First() == aTempShape) {
aTempListOfShape.Clear();
- } else if(aTempListOfShape.Size() > 1) {
+ } else if (aTempListOfShape.Size() > 1) {
TopTools_ListOfShape::Iterator anIt1(aTempListOfShape);
for (; anIt1.More(); anIt1.Next()) {
if (anIt1.Value() == aTempShape) {
}
// Combine shapes with common sub-shapes.
- for(NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator
+ for (NCollection_Vector<NCollection_Map<TopoDS_Shape>>::Iterator
anIter(aShapesWithCommonSubshapes); anIter.More(); anIter.Next()) {
TopoDS_Shell aShell;
TopoDS_CompSolid aCSolid;
theType ==
GeomAPI_Shape::COMPSOLID ? aBuilder.MakeCompSolid(aCSolid) : aBuilder.MakeShell(aShell);
NCollection_Map<TopoDS_Shape>& aShapesMap = anIter.ChangeValue();
- for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
+ for (TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
const TopoDS_Shape& aShape = anExp.Current();
- if(aShapesMap.Contains(aShape)) {
+ if (aShapesMap.Contains(aShape)) {
theType ==
GeomAPI_Shape::COMPSOLID ? aBuilder.Add(aCSolid, aShape) : aBuilder.Add(aShell, aShape);
aShapesMap.Remove(aShape);
}
// Adding free shapes.
- for(TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
+ for (TopExp_Explorer anExp(aShapesComp, aTA); anExp.More(); anExp.Next()) {
const TopoDS_Shape& aShape = anExp.Current();
- if(aFreeShapes.Contains(aShape)) {
+ if (aFreeShapes.Contains(aShape)) {
std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
aGeomShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
aResFreeShapes.push_back(aGeomShape);
}
}
- if(aResCombinedShapes.size() == 1 && aResFreeShapes.size() == 0) {
+ if (aResCombinedShapes.size() == 1 && aResFreeShapes.size() == 0) {
aResult = aResCombinedShapes.front();
theResuts.push_back(aResult);
- } else if(aResCombinedShapes.size() == 0 && aResFreeShapes.size() == 1) {
+ } else if (aResCombinedShapes.size() == 0 && aResFreeShapes.size() == 1) {
aResult = aResFreeShapes.front();
theResuts.push_back(aResult);
} else {
// put to result compound and result list in accordance to the order numbers
std::map<GeomShapePtr, int>::iterator anInputIter = anInputOrder.begin();
std::map<int, GeomShapePtr> aNums;
- for(; anInputIter != anInputOrder.end(); anInputIter++)
+ for (; anInputIter != anInputOrder.end(); anInputIter++)
aNums[anInputIter->second] = anInputIter->first;
std::map<int, GeomShapePtr>::iterator aNumsIter = aNums.begin();
- for(; aNumsIter != aNums.end(); aNumsIter++) {
+ for (; aNumsIter != aNums.end(); aNumsIter++) {
aBuilder.Add(aResultComp, (aNumsIter->second)->impl<TopoDS_Shape>());
theResuts.push_back(aNumsIter->second);
}
static void addSimpleShapeToList(const TopoDS_Shape& theShape,
NCollection_List<TopoDS_Shape>& theList)
{
- if(theShape.IsNull()) {
+ if (theShape.IsNull()) {
return;
}
- if(theShape.ShapeType() == TopAbs_COMPOUND) {
- for(TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
+ if (theShape.ShapeType() == TopAbs_COMPOUND) {
+ for (TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next()) {
addSimpleShapeToList(anIt.Value(), theList);
}
} else {
BRep_Builder aBuilder;
aBuilder.MakeCompound(aCompound);
- for(NCollection_List<TopoDS_Shape>::Iterator anIt(theShapes); anIt.More(); anIt.Next()) {
+ for (NCollection_List<TopoDS_Shape>::Iterator anIt(theShapes); anIt.More(); anIt.Next()) {
aBuilder.Add(aCompound, anIt.Value());
}
for (NCollection_Vector<TopTools_MapOfShape>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) {
const TopTools_MapOfShape& aGroup = anIt.ChangeValue();
GeomShapePtr aGeomShape(new GeomAPI_Shape());
- if(aGroup.Size() == 1) {
+ if (aGroup.Size() == 1) {
TopTools_MapOfShape::Iterator aOneShapeIter(aGroup);
aGeomShape->setImpl(new TopoDS_Shape(aOneShapeIter.Value()));
} else {
aBuilder.Add(aCompound, aGeomShape->impl<TopoDS_Shape>());
}
- if(!aCompound.IsNull()) {
+ if (!aCompound.IsNull()) {
aResult->setImpl(new TopoDS_Shape(aCompound));
}
BRepBndLib::Add(aShape, aBndBox);
}
- if(theEnlarge != 0.0) {
+ if (theEnlarge != 0.0) {
// We enlarge bounding box just to be sure that plane will be large enough to cut all objects.
aBndBox.Enlarge(theEnlarge);
}
Standard_Real aYArr[2] = {aBndBox.CornerMin().Y(), aBndBox.CornerMax().Y()};
Standard_Real aZArr[2] = {aBndBox.CornerMin().Z(), aBndBox.CornerMax().Z()};
std::list<std::shared_ptr<GeomAPI_Pnt> > aResultPoints;
- for(int i = 0; i < 2; i++) {
- for(int j = 0; j < 2; j++) {
- for(int k = 0; k < 2; k++) {
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 2; j++) {
+ for (int k = 0; k < 2; k++) {
std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(aXArr[i], aYArr[j], aZArr[k]));
aResultPoints.push_back(aPnt);
}
{
std::shared_ptr<GeomAPI_Face> aResultFace;
- if(!thePlane.get()) {
+ if (!thePlane.get()) {
return aResultFace;
}
const TopoDS_Shape& aShape = thePlane->impl<TopoDS_Shape>();
- if(aShape.ShapeType() != TopAbs_FACE) {
+ if (aShape.ShapeType() != TopAbs_FACE) {
return aResultFace;
}
TopoDS_Face aFace = TopoDS::Face(aShape);
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
- if(aSurf.IsNull()) {
+ if (aSurf.IsNull()) {
return aResultFace;
}
GeomLib_IsPlanarSurface isPlanar(aSurf);
- if(!isPlanar.IsPlanar()) {
+ if (!isPlanar.IsPlanar()) {
return aResultFace;
}
- if(thePoints.size() != 8) {
+ if (thePoints.size() != 8) {
return aResultFace;
}
const gp_Pnt& aPntOnFace = anIntAna.Point(1);
Standard_Real aPntU(0), aPntV(0);
GeomLib_Tool::Parameters(aFacePlane, aPntOnFace, Precision::Confusion(), aPntU, aPntV);
- if(aPntU < UMin) UMin = aPntU;
- if(aPntU > UMax) UMax = aPntU;
- if(aPntV < VMin) VMin = aPntV;
- if(aPntV > VMax) VMax = aPntV;
+ if (aPntU < UMin) UMin = aPntU;
+ if (aPntU > UMax) UMax = aPntU;
+ if (aPntV < VMin) VMin = aPntV;
+ if (aPntV > VMax) VMax = aPntV;
}
aResultFace.reset(new GeomAPI_Face());
aResultFace->setImpl(new TopoDS_Face(BRepLib_MakeFace(aFacePln, UMin, UMax, VMin, VMax).Face()));
BRepAlgo_FaceRestrictor aFRestrictor;
aFRestrictor.Init(aFace, Standard_False, Standard_True);
- for(ListOfShape::const_iterator anIt = theWires.cbegin();
+ for (ListOfShape::const_iterator anIt = theWires.cbegin();
anIt != theWires.cend();
++anIt) {
TopoDS_Wire aWire = TopoDS::Wire((*anIt)->impl<TopoDS_Shape>());
aFRestrictor.Perform();
- if(!aFRestrictor.IsDone()) {
+ if (!aFRestrictor.IsDone()) {
return;
}
- for(; aFRestrictor.More(); aFRestrictor.Next()) {
+ for (; aFRestrictor.More(); aFRestrictor.Next()) {
GeomShapePtr aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aFRestrictor.Current()));
theFaces.push_back(aShape);
BRep_Builder aBuilder;
aBuilder.MakeCompound(aCompound);
- for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
+ for (ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
aBuilder.Add(aCompound, (*anIt)->impl<TopoDS_Shape>());
}
BRepBuilderAPI_FindPlane aFindPlane(aCompound);
- if(aFindPlane.Found() != Standard_True) {
+ if (aFindPlane.Found() != Standard_True) {
return std::shared_ptr<GeomAPI_Pln>();
}
const std::shared_ptr<GeomAPI_Shape> theSubShape,
const std::shared_ptr<GeomAPI_Shape> theBaseShape)
{
- if(!theSubShape.get() || !theBaseShape.get()) {
+ if (!theSubShape.get() || !theBaseShape.get()) {
return false;
}
const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
const TopoDS_Shape& aBaseShape = theBaseShape->impl<TopoDS_Shape>();
- if(aSubShape.ShapeType() == TopAbs_VERTEX) {
+ if (aSubShape.ShapeType() == TopAbs_VERTEX) {
// If sub-shape is a vertex check distance to shape. If it is <= Precision::Confusion() then OK.
BRepExtrema_DistShapeShape aDist(aBaseShape, aSubShape);
aDist.Perform();
- if(!aDist.IsDone() || aDist.Value() > Precision::Confusion()) {
+ if (!aDist.IsDone() || aDist.Value() > Precision::Confusion()) {
return false;
}
} else if (aSubShape.ShapeType() == TopAbs_EDGE) {
- if(aBaseShape.ShapeType() == TopAbs_FACE) {
+ if (aBaseShape.ShapeType() == TopAbs_FACE) {
// Check that edge is on face surface.
TopoDS_Face aFace = TopoDS::Face(aBaseShape);
TopoDS_Edge anEdge = TopoDS::Edge(aSubShape);
BRepLib_CheckCurveOnSurface aCheck(anEdge, aFace);
aCheck.Perform();
- if(!aCheck.IsDone() || aCheck.MaxDistance() > Precision::Confusion()) {
+ if (!aCheck.IsDone() || aCheck.MaxDistance() > Precision::Confusion()) {
return false;
}
ShapeAnalysis::FindBounds(anEdge, aV1, aV2);
gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
- for(TopExp_Explorer anExp(aBaseShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+ for (TopExp_Explorer anExp(aBaseShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
const TopoDS_Shape& anEdgeOnFace = anExp.Current();
BRepExtrema_DistShapeShape aDist(anEdgeOnFace, anEdge);
aDist.Perform();
- if(aDist.IsDone() && aDist.Value() <= Precision::Confusion()) {
+ if (aDist.IsDone() && aDist.Value() <= Precision::Confusion()) {
// Edge intersect face bound. Check that it is not on edge begin or end.
- for(Standard_Integer anIndex = 1; anIndex <= aDist.NbSolution(); ++anIndex) {
+ for (Standard_Integer anIndex = 1; anIndex <= aDist.NbSolution(); ++anIndex) {
gp_Pnt aPntOnSubShape = aDist.PointOnShape2(anIndex);
- if(aPntOnSubShape.Distance(aPnt1) > Precision::Confusion()
+ if (aPntOnSubShape.Distance(aPnt1) > Precision::Confusion()
&& aPntOnSubShape.Distance(aPnt2) > Precision::Confusion()) {
return false;
}
ShapeAnalysis_Surface aSAS(aSurface);
gp_Pnt2d aPointOnFace = aSAS.ValueOfUV(aPointToCheck, Precision::Confusion());
BRepTopAdaptor_FClass2d aFClass2d(aFace, Precision::Confusion());
- if(aFClass2d.Perform(aPointOnFace) == TopAbs_OUT) {
+ if (aFClass2d.Perform(aPointOnFace) == TopAbs_OUT) {
return false;
}
//==================================================================================================
bool GeomAlgoAPI_ShapeTools::isShapeValid(const std::shared_ptr<GeomAPI_Shape> theShape)
{
- if(!theShape.get()) {
+ if (!theShape.get()) {
return false;
}
{
GeomShapePtr anOuterWire;
- if(!theFace.get() || !theFace->isFace()) {
+ if (!theFace.get() || !theFace->isFace()) {
return anOuterWire;
}
bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr<GeomAPI_Edge> theEdge,
const std::shared_ptr<GeomAPI_Face> theFace)
{
- if(!theEdge.get() || !theFace.get()) {
+ if (!theEdge.get() || !theFace.get()) {
return false;
}
const std::shared_ptr<GeomAPI_Edge> theEdge, const std::shared_ptr<GeomAPI_Face> theFace)
{
std::list<std::shared_ptr<GeomAPI_Vertex> > aResult;
- if(!theEdge.get() || !theFace.get()) {
+ if (!theEdge.get() || !theFace.get()) {
return aResult;
}
if (!anIntAlgo.IsDone())
return aResult;
// searching for points-intersection
- for(int anIntNum = 1; anIntNum <= anIntAlgo.NbPoints() + anIntAlgo.NbSegments(); anIntNum++) {
+ for (int anIntNum = 1; anIntNum <= anIntAlgo.NbPoints() + anIntAlgo.NbSegments(); anIntNum++) {
gp_Pnt anInt;
if (anIntNum <= anIntAlgo.NbPoints()) {
anInt = anIntAlgo.Point(anIntNum);
TopExp_Explorer anExp(aBaseShape, TopAbs_FACE);
const TopoDS_Shape& aFace = anExp.Current();
Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFace));
- if(aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+ if (aSurface->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Handle(Geom_RectangularTrimmedSurface) aTrimSurface =
Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface);
aSurface = aTrimSurface->BasisSurface();
}
- if(aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
+ if (aSurface->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
return;
}
aPlane = Handle(Geom_Plane)::DownCast(aSurface);
#include <GeomAPI_Shape.h>
#include <GeomAPI_Vertex.h>
+#include <GeomAPI_Pnt.h>
#include <map>
#include <set>
#ifdef WIN32
/// \return the total area of the faces of the current shape or 0.0 if it can be computed.
GEOMALGOAPI_EXPORT static double area(const std::shared_ptr<GeomAPI_Shape> theShape);
+ /// indicate if two faces are continuous
+ /// with an angular tolerance used for G1 continuity to compare the angle between the normals
+ /// \param theFace1 the first face
+ /// \param theFace2 the second face
+ /// \param thePoint the point for the normal
+ /// \param theAngle the angular tolerance
+ /// \param theError error
+ GEOMALGOAPI_EXPORT static bool isContinuousFaces(const GeomShapePtr& theFace1,
+ const GeomShapePtr& theFace2,
+ const GeomPointPtr& thePoint,
+ const double & theAngle,
+ std::string& theError);
+
/// \return the center of mass of the current face.
/// The coordinates returned for the center of mass
/// are expressed in the absolute Cartesian coordinate system.
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
{
- double aMinValue = 1.e-5;
- if(theArguments.size() == 1) {
+ double aMinValue = 1.e-12;
+ if (theArguments.size() == 1) {
std::list<std::string>::const_iterator anIt = theArguments.begin();
double aValue = Config_PropManager::stringToDouble((*anIt).c_str());
- if(aValue != 0) {
+ if (aValue != 0) {
// very probably ok
aMinValue = aValue;
}
return false;
}
}
-
return true;
}
INCLUDE(Common)
INCLUDE(UnitTest)
+IF(NOT Boost_INCLUDE_DIR)
+ FILE(TO_CMAKE_PATH "$ENV{BOOST_ROOT_DIR}" BOOST_ROOT)
+ FIND_PACKAGE(Boost REQUIRED)
+ENDIF()
+
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${Boost_INCLUDE_DIR}
Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel)
: myRef(theLabel),
+ myTmpCenterType(NOT_CENTER),
+ myParent(NULL),
myIsGeometricalSelection(false)
{
myIsInitialized = myRef.isInitialized();
- myParent = NULL;
}
void Model_AttributeSelection::setID(const std::string theID)
#include <OSD_Protection.hxx>
#ifdef TINSPECTOR
-#include <CDF_Session.hxx>
#include <CDF_Directory.hxx>
#endif
myIsSetCurrentFeature(false)
{
#ifdef TINSPECTOR
- CDF_Session::CurrentSession()->Directory()->Add(myDoc);
+ ModelAPI_Session::get()->application()->NewDocument("BinOcaf", myDoc);
#endif
myObjs = new Model_Objects(myDoc->Main());
myDoc->SetUndoLimit(UNDO_LIMIT);
#include <Events_Listener.h>
#include <map>
+#ifdef TINSPECTOR
+#include "Model_Application.h"
+#endif
+
class Model_Document;
/**\class Model_Session
/// Set state of the auto-update of features result in the application
MODEL_EXPORT virtual void blockAutoUpdate(const bool theBlock);
+#ifdef TINSPECTOR
+ MODEL_EXPORT virtual Handle(TDocStd_Application) application() {
+ return Model_Application::getApplication();
+ }
+#endif
+
protected:
/// Loads (if not done yet) the information about the features and plugins
void LoadPluginsInfo();
SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473)
ADD_DEFINITIONS(-DMODELAPI_EXPORTS)
+IF(TKTInspector)
+ ADD_DEFINITIONS(-DTINSPECTOR)
+ENDIF()
+
ADD_LIBRARY(ModelAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
SET_TARGET_PROPERTIES(ModelAPI PROPERTIES LINKER_LANGUAGE CXX)
TARGET_LINK_LIBRARIES(ModelAPI ${PROJECT_LIBRARIES})
${PROJECT_SOURCE_DIR}/src/GeomAPI
${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
${PROJECT_SOURCE_DIR}/src/Locale
+ ${OpenCASCADE_INCLUDE_DIR}
)
#include <list>
#include <memory>
+#ifdef TINSPECTOR
+#include <Standard_Handle.hxx>
+#include <TDocStd_Application.hxx>
+#endif
+
class ModelAPI_Feature;
class ModelAPI_Plugin;
class ModelAPI_Document;
/// Set state of the auto-update of features result in the application
virtual void blockAutoUpdate(const bool theBlock) = 0;
+#ifdef TINSPECTOR
+ virtual Handle(TDocStd_Application) application() = 0;
+#endif
+
protected:
/// Sets the session interface implementation (once per application launch)
static void setSession(std::shared_ptr<ModelAPI_Session> theManager);
${SUIT_INCLUDE}
)
-IF(${HAVE_SALOME})
- INCLUDE_DIRECTORIES(${SALOME_KERNEL_INCLUDE})
-ENDIF(${HAVE_SALOME})
-
ADD_DEFINITIONS(-DMODULEBASE_EXPORTS ${OpenCASCADE_DEFINITIONS})
ADD_LIBRARY(ModuleBase SHARED
${PROJECT_SOURCES}
connect(aWidget, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*)),
theParent, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*)));
connect(aWidget, SIGNAL(objectUpdated()), theParent, SLOT(onObjectUpdated()));
+ aWidget->enableFocusProcessing();
}
aLayout->addWidget(aParamsWgt);
}
${SUIT_INCLUDE}
)
-IF(${HAVE_SALOME})
- INCLUDE_DIRECTORIES(${SALOME_KERNEL_INCLUDE})
-ELSE(${HAVE_SALOME})
+IF(NOT ${HAVE_SALOME})
INCLUDE_DIRECTORIES(${APPELEMENTS_INCLUDE_DIR})
-ENDIF(${HAVE_SALOME})
+ENDIF()
ADD_DEFINITIONS(-DPARTSET_EXPORTS ${OpenCASCADE_DEFINITIONS})
ADD_LIBRARY(PartSet SHARED
#include <SelectMgr_ListIteratorOfListOfFilter.hxx>
#include <Graphic3d_Texture2Dmanual.hxx>
-#include <OCCViewer_Utilities.h>
+#ifdef HAVE_SALOME
+#include <OCCViewer_Utilities.h>
+#endif
#define FEATURE_ITEM_COLOR "0,0,225"
//******************************************************
void PartSet_Module::setTexture(const std::string & theTextureFile, const AISObjectPtr& thePrs)
{
+#ifdef HAVE_SALOME
Handle(AIS_InteractiveObject) anAIS = thePrs->impl<Handle(AIS_InteractiveObject)>();
if (!anAIS.IsNull())
{
anAISShape->SetDisplayMode(AIS_Shaded);
}
}
+#endif
}
//******************************************************
#
INSTALL(DIRECTORY geom model examples DESTINATION ${SHAPER_INSTALL_PYTHON_API})
-INSTALL(FILES __init__.py DESTINATION ${SHAPER_INSTALL_PYTHON_API})
-#INSTALL(FILES __init__.py DESTINATION ${_pydir}/salome)
INSTALL(FILES initConfig.py DESTINATION ${SHAPER_INSTALL_PYTHON_API})
+SALOME_CONFIGURE_FILE(__init__.py __init__.py INSTALL ${SHAPER_INSTALL_PYTHON_API})
# --------- Unit tests -----------
INCLUDE(UnitTest)
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
+__version__ = "@SHAPER_GIT_SHA1@"
${PROJECT_SOURCE_DIR}/src/GeomAPI
${PROJECT_SOURCE_DIR}/src/Config
${PROJECT_SOURCE_DIR}/src/ExchangePlugin
- ${SALOME_GUI_INCLUDE}
- ${SALOME_KERNEL_INCLUDE}
+ ${SUIT_INCLUDE}
${OpenCASCADE_INCLUDE_DIR}
)
-IF(${HAVE_SALOME})
- INCLUDE_DIRECTORIES(${SALOME_KERNEL_INCLUDE})
-ENDIF(${HAVE_SALOME})
-
ADD_LIBRARY(SHAPER SHARED
${PROJECT_SOURCES}
${PROJECT_HEADERS}
${OpenCASCADE_INCLUDE_DIR}
${SUIT_INCLUDE})
-IF(${HAVE_SALOME})
- INCLUDE_DIRECTORIES(${SALOME_KERNEL_INCLUDE})
-ENDIF(${HAVE_SALOME})
-
IF(NOT ${HAVE_SALOME})
SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${APPELEMENTS_INCLUDE_DIR})
ENDIF(NOT ${HAVE_SALOME})
if (aCircle) {
addStartEndPoints = aStartPnt->distance(aEndPnt) >= Precision::Confusion();
if (addStartEndPoints)
- myTypeLbl->setText("Arc of circle");
+ myTypeLbl->setText(tr("Arc of circle"));
else
- myTypeLbl->setText("Circle");
+ myTypeLbl->setText(tr("Circle"));
appendPointToParameters(tr("Center"), aCircle->center(), aParams);
appendDirToParameters(tr("Normal"), aCircle->normal(), aParams);
if (anEllipse) {
addStartEndPoints = aStartPnt->distance(aEndPnt) >= Precision::Confusion();
if (addStartEndPoints)
- myTypeLbl->setText("Arc of ellipse");
+ myTypeLbl->setText(tr("Arc of ellipse"));
else
- myTypeLbl->setText("Ellipse");
+ myTypeLbl->setText(tr("Ellipse"));
appendPointToParameters(tr("Center"), anEllipse->center(), aParams);
appendDirToParameters(tr("Normal"), anEllipse->normal(), aParams);
if (anEdge->isCircle() || anEdge->isEllipse()) {
fillEdge(anEdge);
isCommonCase = false;
+ myTypeLbl->setText(tr("Disk"));
}
}
else {
#include <iterator>
#ifdef TINSPECTOR
-#include <CDF_Session.hxx>
-#include <CDF_Application.hxx>
+#include <TDocStd_Application.hxx>
#include <inspector/TInspector_Communicator.hxx>
#include <inspector/VInspector_CallBack.hxx>
static TInspector_Communicator* MyTCommunicator;
static Handle(VInspector_CallBack) MyVCallBack;
-
#endif
#ifdef _DEBUG
#endif
QString aFileName = aDocDir + aSep + thePage;
if (QFile::exists(aFileName)) {
+#ifdef HAVE_SALOME
SUIT_Application* app = SUIT_Session::session()->activeApplication();
if (app)
app->onHelpContextModule("SHAPER", aFileName);
QUrl aUrl = QUrl::fromLocalFile(aFileName);
QDesktopServices::openUrl(aUrl);
}
+#else
+ QUrl aUrl = QUrl::fromLocalFile(aFileName);
+ QDesktopServices::openUrl(aUrl);
+#endif
}
}
}
}
#ifdef TINSPECTOR
else if (theId == "TINSPECTOR_VIEW") {
- Handle(CDF_Application) anApplication = CDF_Session::CurrentSession()->CurrentApplication();
+ Handle(TDocStd_Application) anApplication = ModelAPI_Session::get()->application();
if (!anApplication.IsNull())
{
if (!MyTCommunicator)
<source>Line segment</source>
<translation>Segment de ligne</translation>
</message>
+ <message>
+ <source>Arc of circle</source>
+ <translation>Arc de cercle</translation>
+ </message>
+ <message>
+ <source>Circle</source>
+ <translation>Cercle</translation>
+ </message>
+ <message>
+ <source>Disk</source>
+ <translation>Disque</translation>
+ </message>
<message>
<source>Center</source>
<translation>Centre</translation>
<source>Radius</source>
<translation>Rayon</translation>
</message>
+ <message>
+ <source>Arc of ellipse</source>
+ <translation>Arc d'ellipse</translation>
+ </message>
<message>
<source>Major radius</source>
<translation>Rayon principal</translation>
DESTINATION ${TEST_INSTALL_DIRECTORY}
RENAME CTestTestfile.cmake)
install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
- message(${TEST_NAMES})
install(FILES ${TEST_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY})
endif(${HAVE_SALOME})