Refactor the Fillet and the Chamfer features.
%include "std_shared_ptr.i"
// functions with named parameters
+%feature("kwargs") addChamfer;
%feature("kwargs") addCommon;
%feature("kwargs") addCut;
+%feature("kwargs") addFillet;
%feature("kwargs") addFuse;
%feature("kwargs") addIntersection;
%feature("kwargs") addMultiRotation;
theDumper << ", False, " << anAttrD << ", " << anAttrAngle;
}
+ if (!aBase->data()->version().empty())
+ theDumper << ", keepSubResults = True";
+
theDumper << ")" << std::endl;
}
const std::list<ModelHighAPI_Selection>& theBaseObjects,
const bool performDistances,
const ModelHighAPI_Double& theVal1,
- const ModelHighAPI_Double& theVal2)
+ const ModelHighAPI_Double& theVal2,
+ const bool keepSubResults)
{
std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Chamfer::ID());
+ if (!keepSubResults)
+ aFeature->data()->setVersion("");
return ChamferPtr(new FeaturesAPI_Chamfer(aFeature, theBaseObjects, performDistances,
theVal1, theVal2));
}
const std::list<ModelHighAPI_Selection>& theBaseObjects,
const bool performDistances,
const ModelHighAPI_Double& theVal1,
- const ModelHighAPI_Double& theVal2);
+ const ModelHighAPI_Double& theVal2,
+ const bool keepSubResults = false);
#endif // FeaturesAPI_Chamfer_H_
theDumper << ", " << anAttrRadius1 << ", " << anAttrRadius2;
}
+ if (!aBase->data()->version().empty())
+ theDumper << ", keepSubResults = True";
+
theDumper << ")" << std::endl;
}
//==================================================================================================
-FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
- const std::list<ModelHighAPI_Selection>& theBaseObjects,
- const ModelHighAPI_Double& theRadius)
-{
- std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
- return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius));
-}
-
FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
const std::list<ModelHighAPI_Selection>& theBaseObjects,
const ModelHighAPI_Double& theRadius1,
- const ModelHighAPI_Double& theRadius2)
+ const ModelHighAPI_Double& theRadius2,
+ const bool keepSubResults)
{
std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Fillet::ID());
- return FilletPtr(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius1, theRadius2));
+ if (!keepSubResults)
+ aFeature->data()->setVersion("");
+
+ FilletPtr aFillet;
+ if (theRadius2.value() < 0.0)
+ aFillet.reset(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius1));
+ else
+ aFillet.reset(new FeaturesAPI_Fillet(aFeature, theBaseObjects, theRadius1, theRadius2));
+ return aFillet;
}
#include <FeaturesPlugin_Fillet.h>
+#include <ModelHighAPI_Double.h>
#include <ModelHighAPI_Interface.h>
#include <ModelHighAPI_Macro.h>
-class ModelHighAPI_Double;
class ModelHighAPI_Selection;
/// \class FeaturesAPI_Fillet
/// Pointer on Fillet object.
typedef std::shared_ptr<FeaturesAPI_Fillet> FilletPtr;
-/// \ingroup CPPHighAPI
-/// \brief Create Fillet feature.
-FEATURESAPI_EXPORT
-FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
- const std::list<ModelHighAPI_Selection>& theBaseObjects,
- const ModelHighAPI_Double& theRadius);
-
/// \ingroup CPPHighAPI
/// \brief Create Fillet feature.
FEATURESAPI_EXPORT
FilletPtr addFillet(const std::shared_ptr<ModelAPI_Document>& thePart,
const std::list<ModelHighAPI_Selection>& theBaseObjects,
const ModelHighAPI_Double& theRadius1,
- const ModelHighAPI_Double& theRadius2);
+ const ModelHighAPI_Double& theRadius2 = ModelHighAPI_Double(-1.0),
+ const bool keepSubResults = false);
#endif // FeaturesAPI_Fillet_H_
FeaturesPlugin_Copy.h
FeaturesPlugin_ImportResult.h
FeaturesPlugin_Defeaturing.h
+ FeaturesPlugin_VersionedChFi.h
)
SET(PROJECT_SOURCES
FeaturesPlugin_Copy.cpp
FeaturesPlugin_ImportResult.cpp
FeaturesPlugin_Defeaturing.cpp
+ FeaturesPlugin_VersionedChFi.cpp
)
SET(XML_RESOURCES
TestIntersection_MultiLevelCompound_v0_2.py
TestIntersection_MultiLevelCompound_v95_1.py
TestIntersection_MultiLevelCompound_v95_2.py
+ TestFillet_MultiLevelCompound_v0_1.py
+ TestFillet_MultiLevelCompound_v0_2.py
+ TestFillet_MultiLevelCompound_v0_3.py
+ TestFillet_MultiLevelCompound_v0_4.py
+ TestFillet_MultiLevelCompound_v95_1.py
+ TestFillet_MultiLevelCompound_v95_2.py
+ TestFillet_MultiLevelCompound_v95_3.py
+ TestFillet_MultiLevelCompound_v95_4.py
+ TestChamfer_MultiLevelCompound_v0_1.py
+ TestChamfer_MultiLevelCompound_v0_2.py
+ TestChamfer_MultiLevelCompound_v0_3.py
+ TestChamfer_MultiLevelCompound_v0_4.py
+ TestChamfer_MultiLevelCompound_v95_1.py
+ TestChamfer_MultiLevelCompound_v95_2.py
+ TestChamfer_MultiLevelCompound_v95_3.py
+ TestChamfer_MultiLevelCompound_v95_4.py
)
//
#include "FeaturesPlugin_Chamfer.h"
-#include "FeaturesPlugin_Tools.h"
-
-#include <ModelAPI_Data.h>
+////#include "FeaturesPlugin_Tools.h"
+////
+////#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Tools.h>
-#include <ModelAPI_Validator.h>
-
-#include <GeomAlgoAPI_CompoundBuilder.h>
+////#include <ModelAPI_ResultBody.h>
+////#include <ModelAPI_Session.h>
+////#include <ModelAPI_Tools.h>
+////#include <ModelAPI_Validator.h>
+////
+////#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_Chamfer.h>
-#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_MakeShape.h>
#include <GeomAlgoAPI_Tools.h>
-
-#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
+////
+////#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
#include <GeomAPI_ShapeExplorer.h>
-#include <GeomAPI_ShapeIterator.h>
-
-// Obtain all sub-shapes from the shape and append them to the list
-static void collectSubs(const GeomShapePtr& theShape,
- ListOfShape& theSubs,
- const GeomAPI_Shape::ShapeType theShapeType)
-{
- GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
- for (; anExp.more(); anExp.next()) {
- GeomShapePtr aShape = anExp.current();
- // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
- aShape->setOrientation(GeomAPI_Shape::FORWARD);
- theSubs.push_back(aShape);
- }
-}
+////#include <GeomAPI_ShapeIterator.h>
+////
+////// Obtain all sub-shapes from the shape and append them to the list
+////static void collectSubs(const GeomShapePtr& theShape,
+//// ListOfShape& theSubs,
+//// const GeomAPI_Shape::ShapeType theShapeType)
+////{
+//// GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
+//// for (; anExp.more(); anExp.next()) {
+//// GeomShapePtr aShape = anExp.current();
+//// // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
+//// aShape->setOrientation(GeomAPI_Shape::FORWARD);
+//// theSubs.push_back(aShape);
+//// }
+////}
// Extract edges from the list
-static ListOfShape selectEdges(const ListOfShape& theShapes)
+static void extractEdgesAndFaces(const ListOfShape& theShapes,
+ ListOfShape& theEdges,
+ std::map<GeomShapePtr, GeomShapePtr>& theMapEdgeFace)
{
- ListOfShape anEdges;
for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
if ((*anIt)->isEdge())
- anEdges.push_back(*anIt);
- return anEdges;
-}
-
-// If theShape is a compound of a single sub-shape, return this sub-shape
-static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
-{
- GeomShapePtr aShape = theShape;
- if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
- int aSubResultsNb = 0;
- GeomAPI_ShapeIterator anIt(aShape);
- for(; anIt.more(); anIt.next())
- ++aSubResultsNb;
-
- if(aSubResultsNb == 1) {
- anIt.init(aShape);
- aShape = anIt.current();
+ theEdges.push_back(*anIt);
+ else {
+ for (GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
+ GeomShapePtr aCurrent = anExp.current();
+ theEdges.push_back(aCurrent);
+ theMapEdgeFace[aCurrent] = *anIt;
+ }
}
- }
- return aShape;
}
{
data()->addAttribute(FeaturesPlugin_Chamfer::CREATION_METHOD(),
ModelAPI_AttributeString::typeId());
- data()->addAttribute(FeaturesPlugin_Chamfer::OBJECT_LIST_ID(),
+ AttributePtr aSelectionList = data()->addAttribute(FeaturesPlugin_Chamfer::OBJECT_LIST_ID(),
ModelAPI_AttributeSelectionList::typeId());
data()->addAttribute(FeaturesPlugin_Chamfer::D1_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(FeaturesPlugin_Chamfer::D2_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(FeaturesPlugin_Chamfer::D_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(FeaturesPlugin_Chamfer::ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
-}
+ initVersion(aSelectionList);
+}
-void FeaturesPlugin_Chamfer::execute()
+AttributePtr FeaturesPlugin_Chamfer::objectsAttribute()
{
- AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
- if (!aCreationMethod)
- return;
-
- std::list<std::pair<GeomShapePtr, ListOfShape> > aSolidsAndSubs;
- std::map<GeomShapePtr, GeomShapePtr> aMapEdgeFace;
-
- // getting objects and sort them according to parent solids
- AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
- for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
- AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
- GeomShapePtr anObject = anObjectAttr->value();
- if (!anObject)
- return;
-
- ResultPtr aContext = anObjectAttr->context();
- GeomShapePtr aParent;
- if (aContext.get()) {
- ResultBodyPtr aCtxOwner = ModelAPI_Tools::bodyOwner(aContext);
- aParent = aCtxOwner ? aCtxOwner->shape() : aContext->shape();
- } else { // get it from a feature
- FeaturePtr aFeature = anObjectAttr->contextFeature();
- if (aFeature.get()) {
- aParent = aFeature->firstResult()->shape();
- }
- }
- if (!aParent)
- return;
-
- // searching this parent is already in the list aSolidsAndSubs
- std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator aSearch = aSolidsAndSubs.begin();
- ListOfShape* aFound;
- for(; aSearch != aSolidsAndSubs.end(); aSearch++) {
- if (aSearch->first->isSame(aParent)) {
- aFound = &(aSearch->second);
- break;
- }
- }
- if (aSearch == aSolidsAndSubs.end()) { // not found, so, add a new one
- aSolidsAndSubs.push_back(std::pair<GeomShapePtr, ListOfShape>(aParent, ListOfShape()));
- aFound = &(aSolidsAndSubs.back().second);
- }
-
- ListOfShape anEdgesAndVertices;
- collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
- collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
- for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
- aEIt != anEdgesAndVertices.end(); ++aEIt)
- aFound->push_back(*aEIt);
-
- if (anObject->isFace()) {
- for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
- aEIt != anEdgesAndVertices.end(); ++aEIt) {
- if ((*aEIt)->isEdge()) {
- aMapEdgeFace[(*aEIt)] = anObject;
- }
- }
- }
- }
-
- //bool isOption1 = true;
- double aD1 = 0.0, aD2 = 0.0, aD = 0.0, anAngle = 0.0;
- if (aCreationMethod->value() == CREATION_METHOD_DISTANCE_DISTANCE()) {
- aD1 = real(FeaturesPlugin_Chamfer::D1_ID())->value();
- aD2 = real(FeaturesPlugin_Chamfer::D2_ID())->value();
- } else {
- aD = real(FeaturesPlugin_Chamfer::D_ID())->value();
- anAngle = real(FeaturesPlugin_Chamfer::ANGLE_ID())->value();
- }
-
- // Perform chamfer operation
- GeomAlgoAPI_MakeShapeList aMakeShapeList;
- std::shared_ptr<GeomAlgoAPI_Chamfer> aChamferBuilder;
- int aResultIndex = 0;
- std::string anError;
-
-
- std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
- ListOfShape anOriginalShapesList, aResultShapesList;
-
- std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator anIt = aSolidsAndSubs.begin();
- for (; anIt != aSolidsAndSubs.end(); ++anIt) {
- GeomShapePtr aSolid = anIt->first;
- ListOfShape aFilletEdgesAndVertices = anIt->second;
-
- ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
- if (aCreationMethod->value() == CREATION_METHOD_DISTANCE_DISTANCE()) {
- aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(
- aSolid, aFilletEdges, aMapEdgeFace, true, aD1, aD2));
- } else {
- aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(
- aSolid, aFilletEdges, aMapEdgeFace, false, aD, anAngle));
- }
-
- if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aChamferBuilder, getKind(), anError)) {
- setError(anError);
- return;
- }
+ return attribute(OBJECT_LIST_ID());
+}
- GeomShapePtr aResult = unwrapCompound(aChamferBuilder->shape());
- std::shared_ptr<ModelAPI_ResultBody> aResultBody =
- document()->createBody(data(), aResultIndex);
+const std::string& FeaturesPlugin_Chamfer::modifiedShapePrefix() const
+{
+ static const std::string& THE_PREFIX("Chamfer");
+ return THE_PREFIX;
+}
- ListOfShape aBaseShapes;
- aBaseShapes.push_back(aSolid);
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
- aChamferBuilder, aResult, "Chamfer");
+GeomMakeShapePtr FeaturesPlugin_Chamfer::performOperation(const GeomShapePtr& theSolid,
+ const ListOfShape& theEdges)
+{
+ AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
+ if (!aCreationMethod)
+ return GeomMakeShapePtr();
+
+ bool isDistDist = aCreationMethod->value() == CREATION_METHOD_DISTANCE_DISTANCE();
+ double aD1 = 0.0, aD2 = 0.0, aD = 0.0, anAngle = 0.0;
+ if (isDistDist) {
+ aD1 = real(FeaturesPlugin_Chamfer::D1_ID())->value();
+ aD2 = real(FeaturesPlugin_Chamfer::D2_ID())->value();
+ }
+ else {
+ aD = real(FeaturesPlugin_Chamfer::D_ID())->value();
+ anAngle = real(FeaturesPlugin_Chamfer::ANGLE_ID())->value();
+ }
- setResult(aResultBody, aResultIndex);
- aResultIndex++;
+ // Perform chamfer operation
+ std::shared_ptr<GeomAlgoAPI_Chamfer> aChamferBuilder;
+ std::string anError;
- FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
- aRBA.resultBody = aResultBody;
- aRBA.baseShape = aSolid;
- aRBA.makeShape = aChamferBuilder;
- aResultBaseAlgoList.push_back(aRBA);
- aResultShapesList.push_back(aResult);
- anOriginalShapesList.push_back(aSolid);
+ ListOfShape aChamferEdges;
+ std::map<GeomShapePtr, GeomShapePtr> aMapEdgeFace;
+ extractEdgesAndFaces(theEdges, aChamferEdges, aMapEdgeFace);
- const std::string aFilletFaceName = "Chamfer";
- ListOfShape::iterator aSelectedBase = aFilletEdges.begin();
- for(; aSelectedBase != aFilletEdges.end(); aSelectedBase++) {
- GeomShapePtr aBase = *aSelectedBase;
- // Store new faces generated from edges and vertices
- aResultBody->loadGeneratedShapes(
- aChamferBuilder, aBase, GeomAPI_Shape::EDGE, aFilletFaceName, true);
- }
+ if (isDistDist) {
+ aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(
+ theSolid, aChamferEdges, aMapEdgeFace, true, aD1, aD2));
+ }
+ else {
+ aChamferBuilder.reset(new GeomAlgoAPI_Chamfer(
+ theSolid, aChamferEdges, aMapEdgeFace, false, aD, anAngle));
}
- // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
- // result shape has been deleted, but in another it was modified or stayed.
- GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
- FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
- anOriginalShapesList, aResultShapesCompound);
-
- removeResults(aResultIndex);
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aChamferBuilder, getKind(), anError)) {
+ setError(anError);
+ return GeomMakeShapePtr();
+ }
+ return aChamferBuilder;
}
#ifndef FeaturesPlugin_Chamfer_H_
#define FeaturesPlugin_Chamfer_H_
-#include "FeaturesPlugin.h"
-
-#include <GeomAPI_Shape.h>
-
-#include <ModelAPI_Feature.h>
-
-class GeomAlgoAPI_MakeShape;
-class GeomAPI_DataMapOfShapeMapOfShapes;
+#include "FeaturesPlugin_VersionedChFi.h"
/// \class FeaturesPlugin_Chamfer
/// \ingroup Plugins
/// \brief Feature for applying the Chamfer operations on Solids.
/// Supports two distances chamfer and distance-angle chamfer.
-class FeaturesPlugin_Chamfer : public ModelAPI_Feature
+class FeaturesPlugin_Chamfer : public FeaturesPlugin_VersionedChFi
{
public:
/// Feature kind.
return MY_ANGLE_ID;
}
- /// Performs the algorithm and stores results it in the data structure.
- FEATURESPLUGIN_EXPORT virtual void execute();
-
/// Request for initialization of data model of the feature: adding all attributes.
FEATURESPLUGIN_EXPORT virtual void initAttributes();
FeaturesPlugin_Chamfer();
private:
- /// Load Naming data structure of the feature to the document
- void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- const std::shared_ptr<GeomAPI_Shape> theBaseShape,
- const std::shared_ptr<GeomAPI_Shape> theResultShape,
- const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+ /// Return attribute storing the selected objects of the operation.
+ virtual std::shared_ptr<ModelAPI_Attribute> objectsAttribute();
+
+ /// Return name of modified shape prefix name
+ virtual const std::string& modifiedShapePrefix() const;
+
+ /// Run chamfer/fillet operation and returns the modification algorithm if succeed.
+ virtual std::shared_ptr<GeomAlgoAPI_MakeShape>
+ performOperation(const GeomShapePtr& theSolid, const ListOfShape& theEdges);
};
#endif
//
#include "FeaturesPlugin_Fillet.h"
-#include "FeaturesPlugin_Tools.h"
-#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeString.h>
-#include <ModelAPI_ResultBody.h>
#include <ModelAPI_Session.h>
-#include <ModelAPI_Tools.h>
#include <ModelAPI_Validator.h>
-#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_Fillet.h>
-#include <GeomAlgoAPI_MakeShapeList.h>
+#include <GeomAlgoAPI_MakeShape.h>
#include <GeomAlgoAPI_Tools.h>
-#include <GeomAPI_DataMapOfShapeMapOfShapes.h>
#include <GeomAPI_ShapeExplorer.h>
-#include <GeomAPI_ShapeIterator.h>
-
-
-// Obtain all sub-shapes from the shape and append them to the list
-static void collectSubs(const GeomShapePtr& theShape,
- ListOfShape& theSubs,
- const GeomAPI_Shape::ShapeType theShapeType)
-{
- GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
- for (; anExp.more(); anExp.next()) {
- GeomShapePtr aShape = anExp.current();
- // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
- aShape->setOrientation(GeomAPI_Shape::FORWARD);
- theSubs.push_back(aShape);
- }
-}
// Extract edges from the list
-static ListOfShape selectEdges(const ListOfShape& theShapes)
+static ListOfShape extractEdges(const ListOfShape& theShapes)
{
ListOfShape anEdges;
for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
- if ((*anIt)->isEdge())
- anEdges.push_back(*anIt);
+ for (GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::EDGE); anExp.more(); anExp.next())
+ anEdges.push_back(anExp.current());
return anEdges;
}
-// If theShape is a compound of a single sub-shape, return this sub-shape
-static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
-{
- GeomShapePtr aShape = theShape;
- if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
- int aSubResultsNb = 0;
- GeomAPI_ShapeIterator anIt(aShape);
- for(; anIt.more(); anIt.next())
- ++aSubResultsNb;
-
- if(aSubResultsNb == 1) {
- anIt.init(aShape);
- aShape = anIt.current();
- }
- }
- return aShape;
-}
-
FeaturesPlugin_Fillet::FeaturesPlugin_Fillet()
{
void FeaturesPlugin_Fillet::initAttributes()
{
data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
- data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+ AttributePtr aSelectionList =
+ data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
data()->addAttribute(START_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
data()->addAttribute(END_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), END_RADIUS_ID());
+
+ initVersion(aSelectionList);
}
+AttributePtr FeaturesPlugin_Fillet::objectsAttribute()
+{
+ return attribute(OBJECT_LIST_ID());
+}
+
+const std::string& FeaturesPlugin_Fillet::modifiedShapePrefix() const
+{
+ static const std::string& THE_PREFIX("Fillet");
+ return THE_PREFIX;
+}
-void FeaturesPlugin_Fillet::execute()
+GeomMakeShapePtr FeaturesPlugin_Fillet::performOperation(const GeomShapePtr& theSolid,
+ const ListOfShape& theEdges)
{
AttributeStringPtr aCreationMethod = string(CREATION_METHOD());
if (!aCreationMethod)
- return;
-
- std::list<std::pair<GeomShapePtr, ListOfShape> > aSolidsAndSubs;
-
- // getting objects and sort them according to parent solids
- AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
- for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
- AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
- GeomShapePtr anObject = anObjectAttr->value();
- if (!anObject)
- return;
-
- ResultPtr aContext = anObjectAttr->context();
- GeomShapePtr aParent;
- if (aContext.get()) {
- ResultBodyPtr aCtxOwner = ModelAPI_Tools::bodyOwner(aContext);
- aParent = aCtxOwner ? aCtxOwner->shape() : aContext->shape();
- } else { // get it from a feature
- FeaturePtr aFeature = anObjectAttr->contextFeature();
- if (aFeature.get()) {
- aParent = aFeature->firstResult()->shape();
- }
- }
- if (!aParent)
- return;
-
- // searching this parent is already in the list aSolidsAndSubs
- std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator aSearch = aSolidsAndSubs.begin();
- ListOfShape* aFound;
- for(; aSearch != aSolidsAndSubs.end(); aSearch++) {
- if (aSearch->first->isSame(aParent)) {
- aFound = &(aSearch->second);
- break;
- }
- }
- if (aSearch == aSolidsAndSubs.end()) { // not found, so, add a new one
- aSolidsAndSubs.push_back(std::pair<GeomShapePtr, ListOfShape>(aParent, ListOfShape()));
- aFound = &(aSolidsAndSubs.back().second);
- }
-
- ListOfShape anEdgesAndVertices;
- collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
- collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
- for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
- aEIt != anEdgesAndVertices.end(); ++aEIt)
- aFound->push_back(*aEIt);
- }
+ return GeomMakeShapePtr();
- bool isFixedRadius = true;
+ bool isFixedRadius = aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS();
double aRadius1 = 0.0, aRadius2 = 0.0;
- if (aCreationMethod->value() == CREATION_METHOD_SINGLE_RADIUS())
+ if (isFixedRadius)
aRadius1 = real(RADIUS_ID())->value();
else {
aRadius1 = real(START_RADIUS_ID())->value();
aRadius2 = real(END_RADIUS_ID())->value();
- isFixedRadius = false;
}
// Perform fillet operation
- GeomAlgoAPI_MakeShapeList aMakeShapeList;
std::shared_ptr<GeomAlgoAPI_Fillet> aFilletBuilder;
- int aResultIndex = 0;
std::string anError;
- std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
- ListOfShape anOriginalShapesList, aResultShapesList;
-
- std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator anIt = aSolidsAndSubs.begin();
- for (; anIt != aSolidsAndSubs.end(); ++anIt) {
- GeomShapePtr aSolid = anIt->first;
- ListOfShape aFilletEdgesAndVertices = anIt->second;
-
- ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
- if (isFixedRadius)
- aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1));
- else
- aFilletBuilder.reset(new GeomAlgoAPI_Fillet(aSolid, aFilletEdges, aRadius1, aRadius2));
-
- if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFilletBuilder, getKind(), anError)) {
- setError(anError);
- return;
- }
-
- GeomShapePtr aResult = unwrapCompound(aFilletBuilder->shape());
- std::shared_ptr<ModelAPI_ResultBody> aResultBody =
- document()->createBody(data(), aResultIndex);
-
- ListOfShape aBaseShapes;
- aBaseShapes.push_back(aSolid);
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
- aFilletBuilder, aResult, "Fillet");
-
- setResult(aResultBody, aResultIndex);
- aResultIndex++;
-
- FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
- aRBA.resultBody = aResultBody;
- aRBA.baseShape = aSolid;
- aRBA.makeShape = aFilletBuilder;
- aResultBaseAlgoList.push_back(aRBA);
- aResultShapesList.push_back(aResult);
- anOriginalShapesList.push_back(aSolid);
-
- const std::string aFilletFaceName = "Fillet";
- ListOfShape::iterator aSelectedBase = aFilletEdges.begin();
- for(; aSelectedBase != aFilletEdges.end(); aSelectedBase++) {
- GeomShapePtr aBase = *aSelectedBase;
- // Store new faces generated from edges and vertices
- aResultBody->loadGeneratedShapes(
- aFilletBuilder, aBase, GeomAPI_Shape::EDGE, aFilletFaceName, true);
- }
- }
-
- // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
- // result shape has been deleted, but in another it was modified or stayed.
- GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
- FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
- anOriginalShapesList, aResultShapesCompound);
+ ListOfShape aFilletEdges = extractEdges(theEdges);
+ if (isFixedRadius)
+ aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1));
+ else
+ aFilletBuilder.reset(new GeomAlgoAPI_Fillet(theSolid, aFilletEdges, aRadius1, aRadius2));
- removeResults(aResultIndex);
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aFilletBuilder, getKind(), anError)) {
+ setError(anError);
+ return GeomMakeShapePtr();
+ }
+ return aFilletBuilder;
}
#ifndef FeaturesPlugin_Fillet_H_
#define FeaturesPlugin_Fillet_H_
-#include "FeaturesPlugin.h"
-
-#include <GeomAPI_Shape.h>
-
-#include <ModelAPI_Feature.h>
-
-class GeomAlgoAPI_MakeShape;
-class GeomAPI_DataMapOfShapeMapOfShapes;
+#include "FeaturesPlugin_VersionedChFi.h"
/// \class FeaturesPlugin_Fillet
/// \ingroup Plugins
/// \brief Feature for applying the Fillet operations on Solids.
/// Supports fixed radius fillet and varying 2-radius fillet.
-class FeaturesPlugin_Fillet : public ModelAPI_Feature
+class FeaturesPlugin_Fillet : public FeaturesPlugin_VersionedChFi
{
public:
/// Feature kind.
return START_RADIUS_ID();
}
- /// Performs the fillet algorithm and stores it in the data structure.
- FEATURESPLUGIN_EXPORT virtual void execute();
-
/// Request for initialization of data model of the feature: adding all attributes.
FEATURESPLUGIN_EXPORT virtual void initAttributes();
FeaturesPlugin_Fillet();
private:
- /// Load Naming data structure of the feature to the document
- void loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- const std::shared_ptr<GeomAPI_Shape> theBaseShape,
- const std::shared_ptr<GeomAPI_Shape> theResultShape,
- const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape);
+ /// Return attribute storing the selected objects of the operation.
+ virtual std::shared_ptr<ModelAPI_Attribute> objectsAttribute();
+
+ /// Return name of modified shape prefix name
+ virtual const std::string& modifiedShapePrefix() const;
+
+ /// Run chamfer/fillet operation and returns the modification algorithm if succeed.
+ virtual std::shared_ptr<GeomAlgoAPI_MakeShape>
+ performOperation(const GeomShapePtr& theSolid, const ListOfShape& theEdges);
};
#endif
}
}
- ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
- GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
+ ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true);
+ GeomShapePtr anOwner = aContext->shape();
+ GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner;
if (!anOwner) {
theError = "Error: wrong feature is selected.";
}
if (!aBaseSolid)
- aBaseSolid = anOwner;
- else if (!aBaseSolid->isEqual(anOwner)) {
+ aBaseSolid = aTopLevelOwner;
+ else if (!aBaseSolid->isEqual(aTopLevelOwner)) {
theError = "Error: Sub-shapes of different solids have been selected.";
return false;
}
--- /dev/null
+// Copyright (C) 2017-2019 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 "FeaturesPlugin_VersionedChFi.h"
+#include "FeaturesPlugin_Tools.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomAlgoAPI_MakeShapeList.h>
+
+#include <GeomAPI_ShapeExplorer.h>
+
+
+static const std::string CHAMFERFILLET_VERSION_1("v9.5");
+
+
+// Obtain all sub-shapes from the shape and append them to the list
+static void collectSubs(const GeomShapePtr& theShape,
+ ListOfShape& theSubs,
+ const GeomAPI_Shape::ShapeType theShapeType)
+{
+ GeomAPI_ShapeExplorer anExp(theShape, theShapeType);
+ for (; anExp.more(); anExp.next()) {
+ GeomShapePtr aShape = anExp.current();
+ // Store all shapes with FORWARD orientation to avoid duplication of shared edges/vertices
+ aShape->setOrientation(GeomAPI_Shape::FORWARD);
+ theSubs.push_back(aShape);
+ }
+}
+
+
+void FeaturesPlugin_VersionedChFi::initVersion(const AttributePtr& theObjectsAttr)
+{
+ if (!theObjectsAttr->isInitialized()) {
+ // new feature, not read from file
+ data()->setVersion(CHAMFERFILLET_VERSION_1);
+ }
+}
+
+void FeaturesPlugin_VersionedChFi::execute()
+{
+ GeomAPI_ShapeHierarchy anObjectHierarchy;
+ if (!processAttribute(objectsAttribute(), anObjectHierarchy))
+ return;
+
+ // Perform the operation
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+ int aResultIndex = 0;
+ std::string anError;
+
+ ListOfShape anEdges;
+ ListOfShape anOriginalSolids;
+ for (GeomAPI_ShapeHierarchy::iterator anIt = anObjectHierarchy.begin();
+ anIt != anObjectHierarchy.end(); ++anIt) {
+ GeomShapePtr aSolid = anObjectHierarchy.parent(*anIt);
+ const ListOfShape& aSubs = anObjectHierarchy.objects(aSolid);
+
+ std::shared_ptr<GeomAlgoAPI_MakeShape> anAlgo = performOperation(aSolid, aSubs);
+ if (!anAlgo)
+ return; // something gone wrong
+
+ anObjectHierarchy.markModified(aSolid, anAlgo->shape());
+ aMakeShapeList->appendAlgo(anAlgo);
+
+ anOriginalSolids.push_back(aSolid);
+ anEdges.insert(anEdges.end(), aSubs.begin(), aSubs.end());
+ }
+
+ // Build results of the operaion.
+ const std::string& aPrefix = modifiedShapePrefix();
+ ListOfShape aTopLevel;
+ anObjectHierarchy.topLevelObjects(aTopLevel);
+ for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) {
+ ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalSolids, ListOfShape(),
+ aMakeShapeList, *anIt, aPrefix);
+ setResult(aResultBody, aResultIndex++);
+
+ for (ListOfShape::iterator anIt = anEdges.begin(); anIt != anEdges.end(); ++anIt) {
+ GeomShapePtr aBase = *anIt;
+ // Store new faces generated from edges and vertices
+ aResultBody->loadGeneratedShapes(aMakeShapeList, aBase, GeomAPI_Shape::EDGE, aPrefix, true);
+ }
+
+ FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, GeomShapePtr(), anOriginalSolids,
+ aMakeShapeList, *anIt);
+ }
+
+ removeResults(aResultIndex);
+}
+
+
+bool FeaturesPlugin_VersionedChFi::processAttribute(const AttributePtr& theAttribute,
+ GeomAPI_ShapeHierarchy& theObjects)
+{
+ bool isStoreFullHierarchy = data()->version() == CHAMFERFILLET_VERSION_1;
+
+ AttributeSelectionListPtr anObjectsSelList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
+ AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
+ GeomShapePtr anObject = anObjectAttr->value();
+ if (!anObject)
+ return false;
+
+ ResultPtr aContext = anObjectAttr->context();
+ GeomShapePtr aParent;
+ if (aContext.get()) {
+ ResultBodyPtr aCtxOwner = ModelAPI_Tools::bodyOwner(aContext);
+ if (aCtxOwner && aCtxOwner->shape()->shapeType() == GeomAPI_Shape::COMPSOLID)
+ aContext = aCtxOwner;
+ aParent = aContext->shape();
+ if (!aParent)
+ return false;
+
+ // store full shape hierarchy for the corresponding version only
+ theObjects.addObject(anObject);
+ theObjects.addParent(anObject, aParent);
+ if (isStoreFullHierarchy)
+ ModelAPI_Tools::fillShapeHierarchy(aParent, aContext, theObjects);
+ } else { // get it from a feature
+ FeaturePtr aFeature = anObjectAttr->contextFeature();
+ if (aFeature.get()) {
+ aParent = aFeature->firstResult()->shape();
+ if (!aParent)
+ return false;
+
+ ListOfShape anEdges;
+ collectSubs(aParent, anEdges, GeomAPI_Shape::EDGE);
+ for (ListOfShape::iterator anIt = anEdges.begin(); anIt != anEdges.end(); ++anIt) {
+ theObjects.addObject(*anIt);
+ theObjects.addParent(*anIt, aParent);
+ }
+ }
+ }
+ }
+ return true;
+}
--- /dev/null
+// Copyright (C) 2017-2019 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 FeaturesPlugin_VersionedChFi_H_
+#define FeaturesPlugin_VersionedChFi_H_
+
+#include "FeaturesPlugin.h"
+
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_ShapeHierarchy.h>
+
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+
+/// \class FeaturesPlugin_VersionedChFi
+/// \ingroup Plugins
+/// \brief Base feature for the Fillet and the Chamfer operations
+/// which supports versioning.
+class FeaturesPlugin_VersionedChFi : public ModelAPI_Feature
+{
+public:
+ /// Performs the fillet algorithm and stores it in the data structure.
+ FEATURESPLUGIN_EXPORT virtual void execute();
+
+protected:
+ FeaturesPlugin_VersionedChFi() {}
+
+ /// Intialize the version for the newly created feature.
+ void initVersion(const std::shared_ptr<ModelAPI_Attribute>& theObjectsAttr);
+
+ /// Process SelectionList attribute and fill the objects hierarchy.
+ bool processAttribute(const std::shared_ptr<ModelAPI_Attribute>& theAttribute,
+ GeomAPI_ShapeHierarchy& theObjects);
+
+ /// Return attribute storing the selected objects of the operation.
+ virtual std::shared_ptr<ModelAPI_Attribute> objectsAttribute() = 0;
+
+ /// Return name of modified shape prefix name
+ virtual const std::string& modifiedShapePrefix() const = 0;
+
+ /// Run chamfer/fillet operation and returns the modification algorithm if succeed.
+ virtual std::shared_ptr<GeomAlgoAPI_MakeShape>
+ performOperation(const GeomShapePtr& theSolid, const ListOfShape& theEdges) = 0;
+};
+
+#endif
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE_1 = 2
+DISTANCE_2 = 1
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [50])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [100])
+model.testResultsVolumes(Chamfer_5, [955.8333333])
+refPoint = GeomAPI_Pnt(54.9539378, 4.833682, 4.95710549)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1545.0486226])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_7, 2)
+model.testNbSubResults(Chamfer_7, [0, 0])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Chamfer_7, [990, 965.33333333])
+model.end()
+
+model.begin()
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1/MF:Chamfer&Box_1_1/Top][Chamfer_1_1/MF:Chamfer&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE_1 = 2
+DISTANCE_2 = 1
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], True, DISTANCE_1, DISTANCE_2)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [11])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [46])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [92])
+model.testResultsVolumes(Chamfer_5, [955.333333333])
+refPoint = GeomAPI_Pnt(55.1200279, 5, 4.954640614)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_1 = model.addRecover(Part_1_doc, Chamfer_5, [Compound_1.result()], True)
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Recover_1_1_7_2/Modified_Face&Box_2_1/Top][Recover_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Recover_1_1_7_2/Modified_Face&Box_2_1/Right")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1545.0486226])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_2 = model.addRecover(Part_1_doc, Chamfer_6, [Compound_1.result()], True)
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Recover_2_1_8_1/Modified_Face&Box_3_1/Back][Recover_2_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Recover_2_1_8_2/Modified_Face&Box_3_1/Left")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_7, 2)
+model.testNbSubResults(Chamfer_7, [0, 0])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Chamfer_7, [990, 965.33333333])
+
+Recover_3 = model.addRecover(Part_1_doc, Chamfer_7, [Compound_1.result()], True)
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Recover_3_1_6/Modified_Edge&Chamfer_1_1/ChamferSelected_1"), model.selection("EDGE", "[Recover_3_1_8_2/Modified_Face&Box_3_1/Left][Recover_3_1_8_2/Modified_Face&Box_3_1/Top]")], True, DISTANCE_1, DISTANCE_2)
+model.testNbResults(Chamfer_8, 2)
+model.testNbSubResults(Chamfer_8, [0, 0])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.FACE, [7, 7])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.EDGE, [30, 30])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.VERTEX, [60, 60])
+model.testResultsVolumes(Chamfer_8, [990, 990])
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE = 2
+ANGLE = 30
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [48])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [96])
+model.testResultsVolumes(Chamfer_5, [949.312264841])
+refPoint = GeomAPI_Pnt(54.9483743992, 4.810295773, 4.951504868)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1538.36088744])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_7, 2)
+model.testNbSubResults(Chamfer_7, [0, 0])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Chamfer_7, [988.4529946162, 959.970381336])
+model.end()
+
+model.begin()
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1/MF:Chamfer&Box_1_1/Top][Chamfer_1_1/MF:Chamfer&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE = 2
+ANGLE = 30
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], False, DISTANCE, ANGLE)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [11])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [46])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [92])
+model.testResultsVolumes(Chamfer_5, [948.423375952])
+refPoint = GeomAPI_Pnt(55.13797373, 5, 4.94724189)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_1 = model.addRecover(Part_1_doc, Chamfer_5, [Compound_1.result()], True)
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Recover_1_1_7_2/Modified_Face&Box_2_1/Top][Recover_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Recover_1_1_7_2/Modified_Face&Box_2_1/Right")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1538.36088744])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_2 = model.addRecover(Part_1_doc, Chamfer_6, [Compound_1.result()], True)
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Recover_2_1_8_1/Modified_Face&Box_3_1/Back][Recover_2_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Recover_2_1_8_2/Modified_Face&Box_3_1/Left")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_7, 2)
+model.testNbSubResults(Chamfer_7, [0, 0])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Chamfer_7, [988.4529946162, 959.970381336])
+
+Recover_3 = model.addRecover(Part_1_doc, Chamfer_7, [Compound_1.result()], True)
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Recover_3_1_6/Modified_Edge&Chamfer_1_1/ChamferSelected_1"), model.selection("EDGE", "[Recover_3_1_8_2/Modified_Face&Box_3_1/Left][Recover_3_1_8_2/Modified_Face&Box_3_1/Top]")], False, DISTANCE, ANGLE)
+model.testNbResults(Chamfer_8, 2)
+model.testNbSubResults(Chamfer_8, [0, 0])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.FACE, [7, 7])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.EDGE, [30, 30])
+model.testNbSubShapes(Chamfer_8, GeomAPI_Shape.VERTEX, [60, 60])
+model.testResultsVolumes(Chamfer_8, [988.4529946162, 988.4529946162])
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE_1 = 2
+DISTANCE_2 = 1
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [50])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [100])
+model.testResultsVolumes(Chamfer_5, [955.8333333])
+refPoint = GeomAPI_Pnt(54.9539378, 4.833682, 4.95710549)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1545.0486226])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.testNbResults(Chamfer_7, 1)
+model.testNbSubResults(Chamfer_7, [3])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [94])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [188])
+model.testResultsVolumes(Chamfer_7, [2955.33333333])
+refPoint = GeomAPI_Pnt(-20.9807621135, 42.5, 5)
+midPoint = Chamfer_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+model.end()
+
+model.begin()
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1/MF:Chamfer&Box_1_1/Top][Chamfer_1_1/MF:Chamfer&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE_1 = 2
+DISTANCE_2 = 1
+
+NB_SOLIDS = 7
+NB_FACES = 44
+NB_EDGES = 177
+NB_VERTICES = 355
+VOLUME = 5589.0486226
+
+# collect reference data
+REFERENCE = []
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ REFERENCE.append(p)
+
+def assertResult(theFeature):
+ model.testNbResults(theFeature, 1)
+ model.testNbSubResults(theFeature, [8])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, [NB_SOLIDS])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, [NB_FACES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, [NB_EDGES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, [NB_VERTICES])
+ model.testResultsVolumes(theFeature, [VOLUME])
+
+ for ind in range(0, theFeature.result().numberOfSubs()):
+ ref = REFERENCE[ind]
+ midPoint = theFeature.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE), "Sub-result {}; actual ({}, {}, {}) != expected ({}, {}, {})".format(ind, midPoint.x(), midPoint.y(), midPoint.z(), ref.x(), ref.y(), ref.z())
+
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+REFERENCE[5] = GeomAPI_Pnt(55.1200279, 5, 4.954640614)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5544.3819559356
+assertResult(Chamfer_5)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_7_2/Modified_Face&Box_2_1/Top][Compound_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Compound_1_1_7_2/Modified_Face&Box_2_1/Right")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+NB_FACES += 6
+NB_EDGES += 24
+NB_VERTICES += 48
+VOLUME = 5500.3819559367
+assertResult(Chamfer_6)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_8_1/Modified_Face&Box_3_1/Back][Compound_1_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Compound_1_1_8_2/Modified_Face&Box_3_1/Left")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5455.71528927
+assertResult(Chamfer_7)
+
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1_6/MF:Chamfer&Box_1_1/Bottom][Chamfer_1_1_6/MF:Chamfer&Box_1_1/Front]"), model.selection("EDGE", "[Compound_1_1_8_3/Modified_Face&Box_3_1/Left][Compound_1_1_8_3/Modified_Face&Box_3_1/Top]")], True, DISTANCE_1, DISTANCE_2, keepSubResults = True)
+NB_FACES += 2
+NB_EDGES += 12
+NB_VERTICES += 24
+VOLUME = 5435.71528927
+REFERENCE[5] = GeomAPI_Pnt(55.07545839, 5, 5.003526)
+assertResult(Chamfer_8)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE = 2
+ANGLE = 30
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.testNbResults(Chamfer_5, 1)
+model.testNbSubResults(Chamfer_5, [0])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.EDGE, [48])
+model.testNbSubShapes(Chamfer_5, GeomAPI_Shape.VERTEX, [96])
+model.testResultsVolumes(Chamfer_5, [949.312264841])
+refPoint = GeomAPI_Pnt(54.9483743992, 4.810295773, 4.951504868)
+midPoint = Chamfer_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.testNbResults(Chamfer_6, 1)
+model.testNbSubResults(Chamfer_6, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.EDGE, [90])
+model.testNbSubShapes(Chamfer_6, GeomAPI_Shape.VERTEX, [180])
+model.testResultsVolumes(Chamfer_6, [1538.36088744])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Chamfer_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.testNbResults(Chamfer_7, 1)
+model.testNbSubResults(Chamfer_7, [3])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.EDGE, [94])
+model.testNbSubShapes(Chamfer_7, GeomAPI_Shape.VERTEX, [188])
+model.testResultsVolumes(Chamfer_7, [2948.42337595])
+refPoint = GeomAPI_Pnt(-20.9807621135, 42.5, 5)
+midPoint = Chamfer_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+model.end()
+
+model.begin()
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1/MF:Chamfer&Box_1_1/Top][Chamfer_1_1/MF:Chamfer&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+DISTANCE = 2
+ANGLE = 30
+
+NB_SOLIDS = 7
+NB_FACES = 44
+NB_EDGES = 177
+NB_VERTICES = 355
+VOLUME = 5589.0486226
+
+# collect reference data
+REFERENCE = []
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ REFERENCE.append(p)
+
+def assertResult(theFeature):
+ model.testNbResults(theFeature, 1)
+ model.testNbSubResults(theFeature, [8])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, [NB_SOLIDS])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, [NB_FACES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, [NB_EDGES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, [NB_VERTICES])
+ model.testResultsVolumes(theFeature, [VOLUME])
+
+ for ind in range(0, theFeature.result().numberOfSubs()):
+ ref = REFERENCE[ind]
+ midPoint = theFeature.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE), "Sub-result {}; actual ({}, {}, {}) != expected ({}, {}, {})".format(ind, midPoint.x(), midPoint.y(), midPoint.z(), ref.x(), ref.y(), ref.z())
+
+
+model.begin()
+Chamfer_1 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_2 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_3 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_4 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], False, DISTANCE, ANGLE, keepSubResults = True)
+model.end()
+assert(Chamfer_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Chamfer_5 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], False, DISTANCE, ANGLE, keepSubResults = True)
+REFERENCE[5] = GeomAPI_Pnt(55.13797373, 5, 4.94724189)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5537.4719985546
+assertResult(Chamfer_5)
+
+Chamfer_6 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_7_2/Modified_Face&Box_2_1/Top][Compound_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Compound_1_1_7_2/Modified_Face&Box_2_1/Right")], False, DISTANCE, ANGLE, keepSubResults = True)
+REFERENCE[6] = GeomAPI_Pnt(2.5, 2.5, 5)
+NB_FACES += 6
+NB_EDGES += 24
+NB_VERTICES += 48
+VOLUME = 5486.784263397
+assertResult(Chamfer_6)
+
+Chamfer_7 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_8_1/Modified_Face&Box_3_1/Back][Compound_1_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Compound_1_1_8_2/Modified_Face&Box_3_1/Left")], False, DISTANCE, ANGLE, keepSubResults = True)
+REFERENCE[7] = GeomAPI_Pnt(-20.9807621135, 42.5, 5)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5435.2076393494
+assertResult(Chamfer_7)
+
+Chamfer_8 = model.addChamfer(Part_1_doc, [model.selection("EDGE", "[Chamfer_1_1_6/MF:Chamfer&Box_1_1/Bottom][Chamfer_1_1_6/MF:Chamfer&Box_1_1/Front]"), model.selection("EDGE", "[Compound_1_1_8_3/Modified_Face&Box_3_1/Left][Compound_1_1_8_3/Modified_Face&Box_3_1/Top]")], False, DISTANCE, ANGLE, keepSubResults = True)
+NB_FACES += 2
+NB_EDGES += 12
+NB_VERTICES += 24
+VOLUME = 5412.11362858
+REFERENCE[5] = GeomAPI_Pnt(55.0862659, 5, 5.00347277)
+assertResult(Chamfer_8)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS = 2
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], RADIUS)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], RADIUS)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [49])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [98])
+model.testResultsVolumes(Fillet_5, [960.71975512471])
+refPoint = GeomAPI_Pnt(54.962243976, 4.8550769, 4.9622439887)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], RADIUS)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [91])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [182])
+model.testResultsVolumes(Fillet_6, [1549.768377728])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], RADIUS)
+model.testNbResults(Fillet_7, 2)
+model.testNbSubResults(Fillet_7, [0, 0])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Fillet_7, [991.415926537164, 968.731557])
+model.end()
+
+model.begin()
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/MF:Fillet&Box_1_1/Top][Fillet_1_1/MF:Fillet&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], RADIUS)
+model.end()
+assert(Fillet_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS = 2
+
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], RADIUS)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], RADIUS)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [11])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [46])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [92])
+model.testResultsVolumes(Fillet_5, [960.147483562])
+refPoint = GeomAPI_Pnt(55.106983719, 5, 4.95929198)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_1 = model.addRecover(Part_1_doc, Fillet_5, [Compound_1.result()], True)
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Recover_1_1_7_2/Modified_Face&Box_2_1/Top][Recover_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Recover_1_1_7_2/Modified_Face&Box_2_1/Right")], RADIUS)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [91])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [182])
+model.testResultsVolumes(Fillet_6, [1549.768377728])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_2 = model.addRecover(Part_1_doc, Fillet_6, [Compound_1.result()], True)
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Recover_2_1_8_1/Modified_Face&Box_3_1/Back][Recover_2_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Recover_2_1_8_2/Modified_Face&Box_3_1/Left")], RADIUS)
+model.testNbResults(Fillet_7, 2)
+model.testNbSubResults(Fillet_7, [0, 0])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [30, 40])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [60, 80])
+model.testResultsVolumes(Fillet_7, [991.415926537164, 968.731557])
+
+Recover_3 = model.addRecover(Part_1_doc, Fillet_7, [Compound_1.result()], True)
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Recover_3_1_6/Modified_Edge&Fillet_1_1/FilletSelected_1"), model.selection("EDGE", "[Recover_3_1_8_2/Modified_Face&Box_3_1/Left][Recover_3_1_8_2/Modified_Face&Box_3_1/Top]")], RADIUS)
+model.testNbResults(Fillet_8, 2)
+model.testNbSubResults(Fillet_8, [0, 0])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.FACE, [7, 7])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.EDGE, [30, 30])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.VERTEX, [60, 60])
+model.testResultsVolumes(Fillet_8, [991.415926537164, 991.415926537164])
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS_1 = 2
+RADIUS_2 = 1
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [53])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [106])
+model.testResultsVolumes(Fillet_5, [976.519471836586])
+refPoint = GeomAPI_Pnt(54.98720346, 4.918055722, 4.987203302)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [95])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [190])
+model.testResultsVolumes(Fillet_6, [1565.568094166])
+refPoint = GeomAPI_Pnt(2.7448, 2.7448, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_7, 2)
+model.testNbSubResults(Fillet_7, [0, 0])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [30, 44])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [60, 88])
+model.testResultsVolumes(Fillet_7, [994.948408157, 981.120160322])
+model.end()
+
+model.begin()
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/MF:Fillet&Box_1_1/Top][Fillet_1_1/MF:Fillet&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS_1 = 2
+RADIUS_2 = 1
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS_1, RADIUS_2)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [11])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [50])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [100])
+model.testResultsVolumes(Fillet_5, [976.068565925934])
+refPoint = GeomAPI_Pnt(55.0654360945, 5.015632459, 4.985518188)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_1 = model.addRecover(Part_1_doc, Fillet_5, [Compound_1.result()], True)
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Recover_1_1_7_2/Modified_Face&Box_2_1/Top][Recover_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Recover_1_1_7_2/Modified_Face&Box_2_1/Right")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [95])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [190])
+model.testResultsVolumes(Fillet_6, [1565.568094166])
+refPoint = GeomAPI_Pnt(2.7448, 2.7448, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Recover_2 = model.addRecover(Part_1_doc, Fillet_6, [Compound_1.result()], True)
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Recover_2_1_8_1/Modified_Face&Box_3_1/Back][Recover_2_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Recover_2_1_8_2/Modified_Face&Box_3_1/Left")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_7, 2)
+model.testNbSubResults(Fillet_7, [0, 0])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [7, 10])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [30, 44])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [60, 88])
+model.testResultsVolumes(Fillet_7, [994.948408157, 981.12016032])
+
+Recover_3 = model.addRecover(Part_1_doc, Fillet_7, [Compound_1.result()], True)
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Recover_3_1_6/Modified_Edge&Fillet_1_1/FilletSelected_1"), model.selection("EDGE", "[Recover_3_1_8_2/Modified_Face&Box_3_1/Left][Recover_3_1_8_2/Modified_Face&Box_3_1/Top]")], RADIUS_1, RADIUS_2)
+model.testNbResults(Fillet_8, 2)
+model.testNbSubResults(Fillet_8, [0, 0])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.FACE, [7, 7])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.EDGE, [30, 30])
+model.testNbSubShapes(Fillet_8, GeomAPI_Shape.VERTEX, [60, 60])
+model.testResultsVolumes(Fillet_8, [994.948408157, 994.948408157])
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS = 2
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], RADIUS, keepSubResults = True)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [49])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [98])
+model.testResultsVolumes(Fillet_5, [960.71975512471])
+refPoint = GeomAPI_Pnt(54.962243976, 4.8550769, 4.9622439887)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], RADIUS, keepSubResults = True)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [91])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [182])
+model.testResultsVolumes(Fillet_6, [1549.768377728])
+refPoint = GeomAPI_Pnt(2.5, 2.5, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], RADIUS, keepSubResults = True)
+model.testNbResults(Fillet_7, 1)
+model.testNbSubResults(Fillet_7, [3])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [94])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [188])
+model.testResultsVolumes(Fillet_7, [2960.14748356])
+refPoint = GeomAPI_Pnt(-20.9807621135, 42.5, 5)
+midPoint = Fillet_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+model.end()
+
+model.begin()
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/MF:Fillet&Box_1_1/Top][Fillet_1_1/MF:Fillet&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS = 2
+
+NB_SOLIDS = 7
+NB_FACES = 44
+NB_EDGES = 177
+NB_VERTICES = 355
+VOLUME = 5589.0486226
+
+# collect reference data
+REFERENCE = []
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ REFERENCE.append(p)
+
+def assertResult(theFeature):
+ model.testNbResults(theFeature, 1)
+ model.testNbSubResults(theFeature, [8])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, [NB_SOLIDS])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, [NB_FACES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, [NB_EDGES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, [NB_VERTICES])
+ model.testResultsVolumes(theFeature, [VOLUME])
+
+ for ind in range(0, theFeature.result().numberOfSubs()):
+ ref = REFERENCE[ind]
+ midPoint = theFeature.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE), "Sub-result {}; actual ({}, {}, {}) != expected ({}, {}, {})".format(ind, midPoint.x(), midPoint.y(), midPoint.z(), ref.x(), ref.y(), ref.z())
+
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS, keepSubResults = True)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], RADIUS, keepSubResults = True)
+REFERENCE[5] = GeomAPI_Pnt(55.1069837186, 5, 4.959291982496)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5549.19610616474
+assertResult(Fillet_5)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_7_2/Modified_Face&Box_2_1/Top][Compound_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Compound_1_1_7_2/Modified_Face&Box_2_1/Right")], RADIUS, keepSubResults = True)
+NB_FACES += 6
+NB_EDGES += 25
+NB_VERTICES += 50
+VOLUME = 5509.91586129
+assertResult(Fillet_6)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_8_1/Modified_Face&Box_3_1/Back][Compound_1_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Compound_1_1_8_2/Modified_Face&Box_3_1/Left")], RADIUS, keepSubResults = True)
+NB_FACES += 5
+NB_EDGES += 22
+NB_VERTICES += 44
+VOLUME = 5470.063344851
+assertResult(Fillet_7)
+
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1_6/MF:Fillet&Box_1_1/Bottom][Fillet_1_1_6/MF:Fillet&Box_1_1/Front]"), model.selection("EDGE", "[Compound_1_1_8_3/Modified_Face&Box_3_1/Left][Compound_1_1_8_3/Modified_Face&Box_3_1/Top]")], RADIUS, keepSubResults = True)
+NB_FACES += 2
+NB_EDGES += 12
+NB_VERTICES += 24
+VOLUME = 5452.8951979263
+REFERENCE[5] = GeomAPI_Pnt(55.0668735866, 5, 5)
+assertResult(Fillet_8)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS_1 = 2
+RADIUS_2 = 1
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Wire_1_1/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Face_1_1/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Shell_1_1/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Translation_1_1/MF:Translated&Box_1_1/Front][Translation_1_1/MF:Translated&Box_1_1/Top]"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Right")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.testNbResults(Fillet_5, 1)
+model.testNbSubResults(Fillet_5, [0])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.EDGE, [53])
+model.testNbSubShapes(Fillet_5, GeomAPI_Shape.VERTEX, [106])
+model.testResultsVolumes(Fillet_5, [976.519471836586])
+refPoint = GeomAPI_Pnt(54.98720346, 4.918055722, 4.987203302)
+midPoint = Fillet_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_2_1/Top][Box_2_1/Front]"), model.selection("FACE", "Box_2_1/Right")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.testNbResults(Fillet_6, 1)
+model.testNbSubResults(Fillet_6, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.EDGE, [95])
+model.testNbSubShapes(Fillet_6, GeomAPI_Shape.VERTEX, [190])
+model.testResultsVolumes(Fillet_6, [1565.568094166])
+refPoint = GeomAPI_Pnt(2.7448, 2.7448, 5)
+midPoint = Fillet_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[AngularCopy_1_1_1/MF:Rotated&Box_3_1/Back][AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top]"), model.selection("FACE", "AngularCopy_1_1_2/MF:Rotated&Box_3_1/Left")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.testNbResults(Fillet_7, 1)
+model.testNbSubResults(Fillet_7, [3])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.FACE, [23])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.EDGE, [98])
+model.testNbSubShapes(Fillet_7, GeomAPI_Shape.VERTEX, [196])
+model.testResultsVolumes(Fillet_7, [2976.0685684791988])
+refPoint = GeomAPI_Pnt(-20.9807621135, 42.806, 5)
+midPoint = Fillet_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+model.end()
+
+model.begin()
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/MF:Fillet&Box_1_1/Top][Fillet_1_1/MF:Fillet&Box_1_1/Left]"), model.selection("EDGE", "[AngularCopy_1_1_3/MF:Rotated&Box_3_1/Left][AngularCopy_1_1_3/MF:Rotated&Box_3_1/Top]")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_8.feature().error() != "")
+model.undo()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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 GeomAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+TOLERANCE = 1.e-7
+RADIUS_1 = 2
+RADIUS_2 = 1
+
+NB_SOLIDS = 7
+NB_FACES = 44
+NB_EDGES = 177
+NB_VERTICES = 355
+VOLUME = 5589.0486226
+
+# collect reference data
+REFERENCE = []
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ REFERENCE.append(p)
+
+def assertResult(theFeature):
+ model.testNbResults(theFeature, 1)
+ model.testNbSubResults(theFeature, [8])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, [NB_SOLIDS])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, [NB_FACES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, [NB_EDGES])
+ model.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, [NB_VERTICES])
+ model.testResultsVolumes(theFeature, [VOLUME])
+
+ for ind in range(0, theFeature.result().numberOfSubs()):
+ ref = REFERENCE[ind]
+ midPoint = theFeature.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE), "Sub-result {}; actual ({}, {}, {}) != expected ({}, {}, {})".format(ind, midPoint.x(), midPoint.y(), midPoint.z(), ref.x(), ref.y(), ref.z())
+
+
+model.begin()
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_2")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_1.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_3/Modified_Edge&Sketch_1/SketchLine_1")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_2.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_4/Modified_Edge&Sketch_1/SketchLine_3")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_3.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_4 = model.addFillet(Part_1_doc, [model.selection("EDGE", "Compound_1_1_5/Modified_Edge&Sketch_1/SketchLine_10")], RADIUS_1, RADIUS_2, keepSubResults = True)
+model.end()
+assert(Fillet_4.feature().error() != "")
+model.undo()
+
+model.begin()
+Fillet_5 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_6/Modified_Face&Box_1_1/Front][Compound_1_1_6/Modified_Face&Box_1_1/Top]"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Back")], RADIUS_1, RADIUS_2, keepSubResults = True)
+REFERENCE[5] = GeomAPI_Pnt(55.0654360945, 5.015632459, 4.985518188)
+NB_FACES += 5
+NB_EDGES += 26
+NB_VERTICES += 52
+VOLUME = 5565.117188528191
+assertResult(Fillet_5)
+
+Fillet_6 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_7_2/Modified_Face&Box_2_1/Top][Compound_1_1_7_2/Modified_Face&Box_2_1/Front]"), model.selection("FACE", "Compound_1_1_7_2/Modified_Face&Box_2_1/Right")], RADIUS_1, RADIUS_2, keepSubResults = True)
+REFERENCE[6] = GeomAPI_Pnt(2.7448, 2.7448, 5)
+NB_FACES += 6
+NB_EDGES += 29
+NB_VERTICES += 58
+VOLUME = 5541.63666
+assertResult(Fillet_6)
+
+Fillet_7 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Compound_1_1_8_1/Modified_Face&Box_3_1/Back][Compound_1_1_8_1/Modified_Face&Box_3_1/Top]"), model.selection("FACE", "Compound_1_1_8_2/Modified_Face&Box_3_1/Left")], RADIUS_1, RADIUS_2, keepSubResults = True)
+REFERENCE[7] = GeomAPI_Pnt(-20.9807621135, 42.806, 5)
+NB_FACES += 5
+NB_EDGES += 26
+NB_VERTICES += 52
+VOLUME = 5517.70522857
+assertResult(Fillet_7)
+
+Fillet_8 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1_6/MF:Fillet&Box_1_1/Bottom][Fillet_1_1_6/MF:Fillet&Box_1_1/Front]"), model.selection("EDGE", "[Compound_1_1_8_3/Modified_Face&Box_3_1/Left][Compound_1_1_8_3/Modified_Face&Box_3_1/Top]")], RADIUS_1, RADIUS_2, keepSubResults = True)
+NB_FACES += 2
+NB_EDGES += 12
+NB_VERTICES += 24
+VOLUME = 5507.602043482
+REFERENCE[5] = GeomAPI_Pnt(55.041662114, 5.021870383, 5.009557179275)
+REFERENCE[7] = GeomAPI_Pnt(-20.9807621135, 42.5409962, 5)
+assertResult(Fillet_8)
+
+model.end()
+
+assert(model.checkPythonDump())
return aParent;
}
+GeomShapePtr GeomAPI_ShapeHierarchy::root(const GeomShapePtr& theShape,
+ bool theMarkProcessed)
+{
+ GeomShapePtr aParent = parent(theShape, theMarkProcessed);
+ GeomShapePtr aRoot = aParent;
+ while (aParent) {
+ aParent = parent(aRoot, theMarkProcessed);
+ if (aParent)
+ aRoot = aParent;
+ }
+ return aRoot;
+}
+
void GeomAPI_ShapeHierarchy::markProcessed(const GeomShapePtr& theShape)
{
myProcessedObjects.insert(theShape);
myModifiedObjects[theSource] = theModified;
}
+const ListOfShape& GeomAPI_ShapeHierarchy::objects(GeomShapePtr theParent) const
+{
+ MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(theParent);
+ if (aFoundIndex == myParentIndices.end()) {
+ static const ListOfShape THE_DUMMY = ListOfShape();
+ return THE_DUMMY; // no such shape
+ }
+
+ return mySubshapes[aFoundIndex->second].second;
+}
+
void GeomAPI_ShapeHierarchy::objectsByType(
ListOfShape& theShapesByType,
ListOfShape& theOtherShapes,
iterator anIt = aThis->begin(), aEnd = aThis->end();
for (; anIt != aEnd; ++anIt) {
GeomShapePtr aShape = *anIt;
- GeomShapePtr aParent = aThis->parent(aShape);
- GeomShapePtr aRoot = aParent;
- while (aParent) {
- aParent = aThis->parent(aRoot);
- if (aParent)
- aRoot = aParent;
- }
-
+ GeomShapePtr aRoot = aThis->root(aShape);
if (aRoot) {
- // compose a compund with the modified shapes
- aShape = collectSubs(aRoot, SetOfShape(), myModifiedObjects);
+ // check the current shape was modified
+ MapShapeToShape::const_iterator aFound = myModifiedObjects.find(aRoot);
+ if (aFound != myModifiedObjects.end())
+ aShape = aFound->second;
+ else {
+ // compose a compund with the modified shapes
+ aShape = collectSubs(aRoot, SetOfShape(), myModifiedObjects);
+ }
}
else {
// check the current shape was modified
/// Return parent shape for the given, or empty if it is a high-level shape.
/// By default, the parent and all its subshapes are marked as processed for further skip.
GEOMAPI_EXPORT GeomShapePtr parent(const GeomShapePtr& theShape, bool theMarkProcessed = true);
+ /// Get root shape for the specified sub-shape.
+ /// By default, the parent and all its subshapes are marked as processed for further skip.
+ GEOMAPI_EXPORT GeomShapePtr root(const GeomShapePtr& theShape, bool theMarkProcessed = true);
/// Mark the shape as already processed
GEOMAPI_EXPORT void markProcessed(const GeomShapePtr& theShape);
/// Return list of objects
const ListOfShape& objects() const { return myObjects; }
+ /// Return list of low-level objects for the parent shape
+ GEOMAPI_EXPORT const ListOfShape& objects(GeomShapePtr theParent) const;
/// Separate objects of the given range of types and all other objects
GEOMAPI_EXPORT void objectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes,
const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND,
//
#include "GeomAlgoAPI_Chamfer.h"
+#include "GeomAlgoAPI_DFLoader.h"
#include <BRep_Tool.hxx>
#include <BRepFilletAPI_MakeChamfer.hxx>
aChamferBuilder->Build();
if (!aChamferBuilder->IsDone())
return;
- const TopoDS_Shape& aResult = aChamferBuilder->Shape();
+ TopoDS_Shape aResult = GeomAlgoAPI_DFLoader::refineResult(aChamferBuilder->Shape());
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aResult));
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include "GeomAlgoAPI_Fillet.h"
+#include <GeomAlgoAPI_Fillet.h>
+#include <GeomAlgoAPI_DFLoader.h>
#include <BRepFilletAPI_MakeFillet.hxx>
aFilletBuilder->Build();
if (!aFilletBuilder->IsDone())
return;
- const TopoDS_Shape& aResult = aFilletBuilder->Shape();
+ TopoDS_Shape aResult = GeomAlgoAPI_DFLoader::refineResult(aFilletBuilder->Shape());
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aResult));