<plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
<plugin script="addons_Features" configuration="addons_Features.xml"/>
<plugin library="SketchPlugin" configuration="plugin-SketchDrawer.xml"/>
+ <plugin library="SketchPlugin" configuration="plugin-SketchCopy.xml"/>
<plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="GEOM"/>
<plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
@DEFAULT_SOLVER@
// std::list -> []
%template(StringList) std::list<std::string>;
+%template(AttributeList) std::list<std::shared_ptr<ModelAPI_Attribute> >;
%template(ObjectList) std::list<std::shared_ptr<ModelAPI_Object> >;
%template(FeatureList) std::list<std::shared_ptr<ModelAPI_Feature> >;
%template(ResultList) std::list<std::shared_ptr<ModelAPI_Result> >;
std::list<FeaturePtr> aFeatures = aDoc1->allFeatures();
if (aDoc1 != aDoc2) {
+ // Find the position of the part, where its features should be inserted.
+ // It will avoid checking of appropriate elements in partSet after the current part.
+ std::list<FeaturePtr>::iterator aFIt = aFeatures.begin();
+ for (; aFIt != aFeatures.end(); ++aFIt) {
+ ResultPartPtr aPartRes =
+ std::dynamic_pointer_cast<ModelAPI_ResultPart>((*aFIt)->lastResult());
+ if (aPartRes && aPartRes->partDoc() == aDoc2)
+ break;
+ }
+
std::list<FeaturePtr> anAdditionalFeatures = aDoc2->allFeatures();
- aFeatures.insert(aFeatures.end(), anAdditionalFeatures.begin(), anAdditionalFeatures.end());
+ aFeatures.insert(aFIt, anAdditionalFeatures.begin(), anAdditionalFeatures.end());
}
CompositeFeaturePtr aLastCompositeFeature;
"""Package for Sketch plugin for the Parametric Geometry API of the Modeler.
"""
-from SketchAPI import addSketch
+from SketchAPI import addSketch, copySketch
from .tools import *
from .tests import *
errorValue = theSketch.solverError().value()
assert(errorValue != "")
assert(errorValue.find("degenerated") >= 0)
+
+
+def compareSketches(theReference, theSketch, TOLERANCE = 1.e-5):
+ """ Compare sketches for the sequence of features
+ """
+ errors = ""
+
+ # compare sketches degree of freedom
+ if tools.dof(theReference) != tools.dof(theSketch):
+ errors += "\nError in DoF (actual = {}, expected = {})".format(tools.dof(theSketch), tools.dof(theReference))
+
+ # compare sketch solver error
+ if theReference.solverError().value() != theSketch.solverError().value():
+ errors += "\nError in solver message (actual = '{}', expected = '{}')".format(theSketch.solverError().value(), theReference.solverError().value())
+
+ aRefSketch = featureToCompositeFeature(theReference.feature())
+ anActualSketch = featureToCompositeFeature(theSketch.feature())
+
+ # compare number of subs
+ aRefNbSubs = aRefSketch.numberOfSubs()
+ anActualNbSubs = anActualSketch.numberOfSubs()
+ if aRefNbSubs != anActualNbSubs:
+ errors += "\nError in number of sub-features (actual = {}, expected = {})".format(anActualNbSubs, aRefNbSubs)
+
+ for index in range(min(aRefNbSubs, anActualNbSubs)):
+ aRefFeature = aRefSketch.subFeature(index)
+ aFeature = anActualSketch.subFeature(index)
+ # compare types of subs
+ if aFeature.getKind() != aRefFeature.getKind():
+ errors += "\nWrong sketch feature (actual = '{}', expected = '{}')".format(aFeature.name(), aRefFeature.name())
+ continue
+ # compare attributes
+ aRefAttrs = aRefFeature.data().attributes("")
+ anAttrs = aFeature.data().attributes("")
+ for ref, attr in zip(aRefAttrs, anAttrs):
+ if ref.attributeType() != attr.attributeType():
+ errors += "\nWrong sequence of attributes (feature = '{}', reference = '{}')".format(aFeature.name(), aRefFeature.name())
+ elif not attr.isInitialized() or not ref.isInitialized():
+ if attr.isInitialized() != ref.isInitialized():
+ errors += "\nAttribute '{}' initialization is different (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), aFeature.name(), aRefFeature.name(), attr.isInitialized(), ref.isInitialized())
+ elif ref.attributeType() == GeomDataAPI_Point2D.typeId():
+ aRefPoint = geomDataAPI_Point2D(ref)
+ aPoint = geomDataAPI_Point2D(attr)
+ if tools.distancePointPoint(aPoint, aRefPoint) > TOLERANCE:
+ errors += "\nWrong coordinates '{}' (feature = '{}', reference = '{}'): actual = ({}, {}), expected = ({}, {})".format(attr.id(), aFeature.name(), aRefFeature.name(), aPoint.x(), aPoint.y(), aRefPoint.x(), aRefPoint.y())
+ elif ref.attributeType() == GeomDataAPI_Point2DArray.typeId():
+ aRefPoints = geomDataAPI_Point2DArray(ref)
+ aPoints = geomDataAPI_Point2DArray(attr)
+ for pInd in range(aRefPoints.size()):
+ aRefPoint = aRefPoints.pnt(pInd)
+ aPoint = aPoints.pnt(pInd)
+ if tools.distancePointPoint(aPoint, aRefPoint) > TOLERANCE:
+ errors += "\nWrong coordinates '{}', index {} (feature = '{}', reference = '{}'): actual = ({}, {}), expected = ({}, {})".format(attr.id(), pInd, aFeature.name(), aRefFeature.name(), aPoint.x(), aPoint.y(), aRefPoint.x(), aRefPoint.y())
+ elif ref.attributeType() == ModelAPI_AttributeBoolean.typeId():
+ aRefVal = modelAPI_AttributeBoolean(ref).value()
+ aVal = modelAPI_AttributeBoolean(attr).value()
+ if aVal != aRefVal:
+ errors += "\nWrong boolean value '{}' (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), aFeature.name(), aRefFeature.name(), aVal, aRefVal)
+ elif ref.attributeType() == ModelAPI_AttributeDouble.typeId():
+ aRefVal = modelAPI_AttributeDouble(ref).value()
+ aVal = modelAPI_AttributeDouble(attr).value()
+ if math.fabs(aVal - aRefVal) > TOLERANCE:
+ errors += "\nWrong real value '{}' (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), aFeature.name(), aRefFeature.name(), aVal, aRefVal)
+ elif ref.attributeType() == ModelAPI_AttributeDoubleArray.typeId():
+ aRefArray = modelAPI_AttributeDoubleArray(ref)
+ anArray = modelAPI_AttributeDoubleArray(attr)
+ for vInd in range(aRefArray.size()):
+ aRefVal = aRefArray.value(vInd)
+ aVal = anArray.value(vInd)
+ if math.fabs(aVal - aRefVal) > TOLERANCE:
+ errors += "\nWrong real value '{}' index {} (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), vInd, aFeature.name(), aRefFeature.name(), aVal, aRefVal)
+ elif ref.attributeType() == ModelAPI_AttributeInteger.typeId():
+ aRefVal = modelAPI_AttributeInteger(ref).value()
+ aVal = modelAPI_AttributeInteger(attr).value()
+ if aVal != aRefVal:
+ errors += "\nWrong integer value '{}' (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), aFeature.name(), aRefFeature.name(), aVal, aRefVal)
+ elif ref.attributeType() == ModelAPI_AttributeIntArray.typeId():
+ aRefArray = modelAPI_AttributeIntArray(ref)
+ anArray = modelAPI_AttributeIntArray(attr)
+ for vInd in range(aRefArray.size()):
+ aRefVal = aRefArray.value(vInd)
+ aVal = anArray.value(vInd)
+ if aVal != aRefVal:
+ errors += "\nWrong integer value '{}' index {} (feature = '{}', reference = '{}'): actual = {}, expected = {}".format(attr.id(), vInd, aFeature.name(), aRefFeature.name(), aVal, aRefVal)
+
+ return errors
#include <SketchPlugin_ConstraintTangent.h>
#include <SketchPlugin_ConstraintVertical.h>
#include <SketchPlugin_MacroBSpline.h>
+#include <SketchPlugin_SketchCopy.h>
#include <SketcherPrs_Tools.h>
//--------------------------------------------------------------------------------------
#include <ModelAPI_Events.h>
return SketchPtr(new SketchAPI_Sketch(aFeature, thePlaneObject));
}
+//--------------------------------------------------------------------------------------
+SketchPtr copySketch(const std::shared_ptr<ModelAPI_Document> & thePart,
+ const SketchPtr & theSketch)
+{
+ FeaturePtr aCopyer = thePart->addFeature(SketchPlugin_SketchCopy::ID());
+ aCopyer->reference(SketchPlugin_SketchCopy::BASE_ID())->setValue(theSketch->feature());
+ aCopyer->execute();
+
+ FeaturePtr aNewSketch = thePart->nextFeature(aCopyer);
+
+ // perform removing the macro-feature
+ thePart->removeFeature(aCopyer);
+ apply();
+
+ return SketchPtr(new SketchAPI_Sketch(aNewSketch));
+}
+
//--------------------------------------------------------------------------------------
std::list< std::shared_ptr<SketchAPI_Point> > SketchAPI_Sketch::getFreePoints()
//! Pointer on Sketch object
typedef std::shared_ptr<SketchAPI_Sketch> SketchPtr;
+//--------------------------------------------------------------------------------------
+
/**\ingroup CPPHighAPI
* \brief Create Sketch feature
*/
std::shared_ptr<ModelAPI_Object> thePlaneObject);
//--------------------------------------------------------------------------------------
+
+/** \ingroup CPPHighAPI
+ * \brief Copy sketch with all its sub-features
+ */
+SKETCHAPI_EXPORT
+SketchPtr copySketch(const std::shared_ptr<ModelAPI_Document> & thePart,
+ const SketchPtr & theSketch);
+
//--------------------------------------------------------------------------------------
#endif /* SRC_SKETCHAPI_SKETCHAPI_SKETCH_H_ */
SketchPlugin_Point.h
SketchPlugin_Projection.h
SketchPlugin_Sketch.h
+ SketchPlugin_SketchCopy.h
SketchPlugin_SketchDrawer.h
SketchPlugin_SketchEntity.h
SketchPlugin_Split.h
SketchPlugin_Point.cpp
SketchPlugin_Projection.cpp
SketchPlugin_Sketch.cpp
+ SketchPlugin_SketchCopy.cpp
SketchPlugin_SketchDrawer.cpp
SketchPlugin_SketchEntity.cpp
SketchPlugin_Split.cpp
SET(XML_RESOURCES
plugin-Sketch.xml
+ plugin-SketchCopy.xml
plugin-SketchDrawer.xml
)
TestRemoveSketch.py
TestSignedDistancePointLine.py
TestSignedDistancePointPoint.py
+ TestSketchCopy01.py
+ TestSketchCopy02.py
+ TestSketchCopy03.py
+ TestSketchCopy04.py
+ TestSketchCopy05.py
+ TestSketchCopy06.py
+ TestSketchCopy07.py
+ TestSketchCopy08.py
+ TestSketchCopy09.py
+ TestSketchCopy10.py
+ TestSketchCopy11.py
+ TestSketchCopy12.py
+ TestSketchCopy13.py
+ TestSketchCopy14.py
TestSketchDrawer.py
TestSketchPointLine.py
TestSnowflake.py
#include <SketchPlugin_EllipticArc.h>
#include <SketchPlugin_MacroEllipticArc.h>
#include <SketchPlugin_SketchDrawer.h>
+#include <SketchPlugin_SketchCopy.h>
#include <SketcherPrs_Tools.h>
return FeaturePtr(new SketchPlugin_MacroEllipticArc);
} else if (theFeatureID == SketchPlugin_SketchDrawer::ID()) {
return FeaturePtr(new SketchPlugin_SketchDrawer);
+ } else if (theFeatureID == SketchPlugin_SketchCopy::ID()) {
+ return FeaturePtr(new SketchPlugin_SketchCopy);
}
// feature of such kind is not found
return FeaturePtr();
if (!isRebuild && aResult && aResult->shape() && theID == EXTERNAL_FEATURE_ID()) {
aResult->setShape(std::shared_ptr<GeomAPI_Edge>());
if (aProjection)
- aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
+ aProjection->selection(EXTERNAL_ID())->setValue(ResultPtr(), GeomShapePtr());
}
keepCurrentFeature();
--- /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
+//
+
+#include <SketchPlugin_SketchCopy.h>
+#include <SketchPlugin_Sketch.h>
+#include <SketchPlugin_SketchEntity.h>
+#include <SketchPlugin_Tools.h>
+
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefAttrList.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <GeomAlgoAPI_Copy.h>
+
+#include <list>
+#include <map>
+#include <string>
+#include <sstream>
+
+class MapEntities;
+static void copyAttribute(AttributePtr theOld, AttributePtr theNew, MapEntities& theMapOldNew);
+
+/// Internal structure to keep relation between sub-elements of old and new sketch.
+class MapEntities
+{
+public:
+ void bind(FeaturePtr theOld, FeaturePtr theNew)
+ {
+ myObjects[theOld] = theNew;
+ checkPostponed(theOld);
+
+ std::list<ResultPtr> anOldResults = theOld->results();
+ std::list<ResultPtr> aNewResults = theNew->results();
+ for (std::list<ResultPtr>::iterator it1 = anOldResults.begin(), it2 = aNewResults.begin();
+ it1 != anOldResults.end() && it2 != aNewResults.end(); ++it1, ++it2) {
+ myObjects[*it1] = *it2;
+ checkPostponed(*it1);
+ }
+ }
+
+ void postpone(ObjectPtr theOldObject, AttributePtr theOldAttr, AttributePtr theNewAttr)
+ {
+ if (theOldObject)
+ myPostponed[theOldObject][theOldAttr] = theNewAttr;
+ }
+
+ ObjectPtr find(ObjectPtr theOld)
+ {
+ auto aFound = myObjects.find(theOld);
+ return aFound == myObjects.end() ? ObjectPtr() : aFound->second;
+ }
+
+ AttributePtr find(AttributePtr theOld)
+ {
+ FeaturePtr anOldOwner = ModelAPI_Feature::feature(theOld->owner());
+ FeaturePtr aNewOwner = ModelAPI_Feature::feature(find(anOldOwner));
+ return aNewOwner ? aNewOwner->attribute(theOld->id()) : AttributePtr();
+ }
+
+protected:
+ void checkPostponed(ObjectPtr theOld)
+ {
+ auto aFound = myPostponed.find(theOld);
+ if (aFound == myPostponed.end())
+ return;
+ for (auto it = aFound->second.begin(); it != aFound->second.end(); ++it)
+ copyAttribute(it->first, it->second, *this);
+ myPostponed.erase(aFound);
+ }
+
+private:
+ std::map<ObjectPtr, ObjectPtr> myObjects;
+ std::map<ObjectPtr, std::map<AttributePtr, AttributePtr> > myPostponed;
+};
+
+
+SketchPlugin_SketchCopy::SketchPlugin_SketchCopy() : ModelAPI_Feature()
+{}
+
+void SketchPlugin_SketchCopy::initAttributes()
+{
+ data()->addAttribute(BASE_ID(), ModelAPI_AttributeReference::typeId());
+}
+
+static void copyRefAttr(AttributeRefAttrPtr theOld,
+ AttributeRefAttrPtr theNew,
+ MapEntities& theMapOldNew)
+{
+ if (theOld->isObject()) {
+ ObjectPtr aNew = theMapOldNew.find(theOld->object());
+ if (aNew)
+ theNew->setObject(aNew);
+ else
+ theMapOldNew.postpone(theOld->object(), theOld, theNew);
+ }
+ else {
+ AttributePtr aNewAttr = theMapOldNew.find(theOld->attr());
+ if (aNewAttr)
+ theNew->setAttr(aNewAttr);
+ else
+ theMapOldNew.postpone(theOld->attr()->owner(), theOld, theNew);
+ }
+}
+
+static void copyRefAttrList(AttributeRefAttrListPtr theOld,
+ AttributeRefAttrListPtr theNew,
+ MapEntities& theMapOldNew)
+{
+ // copy only if all referred objects/attribute are already transfered
+ std::list<std::pair<ObjectPtr, AttributePtr> > aRefs = theOld->list();
+ for (std::list<std::pair<ObjectPtr, AttributePtr> >::iterator anIt = aRefs.begin();
+ anIt != aRefs.end(); ++anIt) {
+ ObjectPtr aNewObj = anIt->first ? theMapOldNew.find(anIt->first) : ObjectPtr();
+ AttributePtr aNewAttr = anIt->second ? theMapOldNew.find(anIt->second) : AttributePtr();
+ if (aNewObj || aNewAttr)
+ *anIt = std::pair<ObjectPtr, AttributePtr>(aNewObj, aNewAttr);
+ else {
+ if (anIt->first)
+ theMapOldNew.postpone(anIt->first, theOld, theNew);
+ else
+ theMapOldNew.postpone(anIt->second->owner(), theOld, theNew);
+ return;
+ }
+ }
+ // update the RefAttrList
+ theNew->clear();
+ for (std::list<std::pair<ObjectPtr, AttributePtr> >::iterator anIt = aRefs.begin();
+ anIt != aRefs.end(); ++anIt) {
+ if (anIt->first)
+ theNew->append(anIt->first);
+ else
+ theNew->append(anIt->second);
+ }
+}
+
+static void copyReference(AttributeReferencePtr theOld,
+ AttributeReferencePtr theNew,
+ MapEntities& theMapOldNew)
+{
+ ObjectPtr aNew = theMapOldNew.find(theOld->value());
+ if (aNew)
+ theNew->setValue(aNew);
+ else
+ theMapOldNew.postpone(theOld->value(), theOld, theNew);
+}
+
+static void copyRefList(AttributeRefListPtr theOld,
+ AttributeRefListPtr theNew,
+ MapEntities& theMapOldNew)
+{
+ // copy only if all referred objects are already transfered
+ std::list<ObjectPtr> aRefs = theOld->list();
+ for (std::list<ObjectPtr>::iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt) {
+ ObjectPtr aNew = theMapOldNew.find(*anIt);
+ if (aNew)
+ *anIt = aNew;
+ else {
+ theMapOldNew.postpone(*anIt, theOld, theNew);
+ return;
+ }
+ }
+ // update theRefList
+ theNew->clear();
+ for (std::list<ObjectPtr>::iterator anIt = aRefs.begin(); anIt != aRefs.end(); ++anIt)
+ theNew->append(*anIt);
+}
+
+static void copySelection(AttributeSelectionPtr theOld,
+ AttributeSelectionPtr theNew,
+ MapEntities& theMapOldNew)
+{
+ theNew->selectValue(theOld);
+}
+
+void copyAttribute(AttributePtr theOld, AttributePtr theNew, MapEntities& theMapOldNew)
+{
+ if (theNew->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
+ copyRefAttr(std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theOld),
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theNew),
+ theMapOldNew);
+ }
+ else if (theNew->attributeType() == ModelAPI_AttributeReference::typeId()) {
+ copyReference(std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theOld),
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theNew),
+ theMapOldNew);
+ }
+ else if (theNew->attributeType() == ModelAPI_AttributeRefAttrList::typeId()) {
+ copyRefAttrList(std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theOld),
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theNew),
+ theMapOldNew);
+ }
+ else if (theNew->attributeType() == ModelAPI_AttributeRefList::typeId()) {
+ copyRefList(std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theOld),
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theNew),
+ theMapOldNew);
+ }
+ else if (theNew->attributeType() == ModelAPI_AttributeSelection::typeId()) {
+ copySelection(std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theOld),
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theNew),
+ theMapOldNew);
+ }
+}
+
+static void renameByParent(FeaturePtr theOld, FeaturePtr theNew)
+{
+ AttributeReferencePtr anOldParentRef = theOld->reference(SketchPlugin_SketchEntity::PARENT_ID());
+ if (!anOldParentRef || !anOldParentRef->isInitialized())
+ return;
+
+ AttributeReferencePtr aNewParentRef = theNew->reference(SketchPlugin_SketchEntity::PARENT_ID());
+
+ std::string anOldName = anOldParentRef->value()->data()->name();
+ std::string aNewName = aNewParentRef->value()->data()->name();
+
+ // substitute name of old parent by the new one
+ theNew->data()->setName(theOld->name());
+ SketchPlugin_Tools::replaceInName(theNew, anOldName, aNewName);
+
+ const std::list<ResultPtr>& anOldResults = theOld->results();
+ const std::list<ResultPtr>& aNewResults = theNew->results();
+ for (std::list<ResultPtr>::const_iterator it0 = anOldResults.begin(), it1 = aNewResults.begin();
+ it0 != anOldResults.end() && it1 != aNewResults.end(); ++it0, ++it1) {
+ (*it1)->data()->setName((*it0)->data()->name());
+ SketchPlugin_Tools::replaceInName(*it1, anOldName, aNewName);
+ }
+}
+
+static void copyFeature(const FeaturePtr theFeature,
+ std::shared_ptr<SketchPlugin_Sketch> theSketch,
+ MapEntities& theMapOldNew)
+{
+ if (!theFeature)
+ return;
+
+ // copy feature and its results
+ FeaturePtr aNewFeature = theSketch->addFeature(theFeature->getKind());
+ theFeature->data()->copyTo(aNewFeature->data());
+ int aResultIndex = 0;
+ for (std::list<ResultPtr>::const_iterator aRIt = theFeature->results().begin();
+ aRIt != theFeature->results().end(); ++aRIt) {
+ ResultConstructionPtr aResult =
+ theSketch->document()->createConstruction(aNewFeature->data(), aResultIndex);
+
+ GeomAlgoAPI_Copy aCopyAlgo((*aRIt)->shape());
+
+ aResult->setShape(aCopyAlgo.shape());
+ aResult->setIsInHistory((*aRIt)->isInHistory());
+ aNewFeature->setResult(aResult, aResultIndex++);
+ }
+ theMapOldNew.bind(theFeature, aNewFeature);
+
+ // update referred features and attributes
+ bool aWasBlocked = aNewFeature->data()->blockSendAttributeUpdated(true, false);
+ std::list<AttributePtr> anAttrs =
+ aNewFeature->data()->attributes(std::string());
+ for (std::list<AttributePtr>::iterator anIt = anAttrs.begin(); anIt != anAttrs.end(); ++anIt) {
+ AttributePtr anOldAttr = theFeature->attribute((*anIt)->id());
+ copyAttribute(anOldAttr, *anIt, theMapOldNew);
+ }
+ aNewFeature->data()->blockSendAttributeUpdated(aWasBlocked, false);
+
+ // rename feature according to parent
+ renameByParent(theFeature, aNewFeature);
+}
+
+static int index(const std::string& theName, const std::string& thePrefix)
+{
+ int anIndex = -1;
+ if (theName.find(thePrefix) == 0) {
+ anIndex = 0;
+ if (theName[thePrefix.size()] == '_') {
+ std::string anIndexStr = theName.substr(thePrefix.size() + 1);
+ anIndex = std::atoi(anIndexStr.c_str());
+ }
+ }
+ return anIndex;
+}
+
+
+void SketchPlugin_SketchCopy::execute()
+{
+ FeaturePtr aBaseSketchFeature = ModelAPI_Feature::feature(reference(BASE_ID())->value());
+ CompositeFeaturePtr aBaseSketch =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aBaseSketchFeature);
+ if (!aBaseSketch) {
+ setError("Error: a base feature is not a sketch.");
+ return; // invalid case
+ }
+
+ FeaturePtr aNewSketchFeature = document()->addFeature(aBaseSketch->getKind());
+ std::shared_ptr<SketchPlugin_Sketch> aNewSketch =
+ std::dynamic_pointer_cast<SketchPlugin_Sketch>(aNewSketchFeature);
+ // copy all attributes of sketch, then clear sub-features to be able to copy then one by one
+ aBaseSketch->data()->copyTo(aNewSketch->data());
+ aNewSketch->reflist(SketchPlugin_Sketch::FEATURES_ID())->clear();
+
+ MapEntities aMapOldNew;
+
+ std::list<ObjectPtr> aBaseFeatures =
+ aBaseSketch->reflist(SketchPlugin_Sketch::FEATURES_ID())->list();
+ for (std::list<ObjectPtr>::const_iterator aFIt = aBaseFeatures.begin();
+ aFIt != aBaseFeatures.end(); ++aFIt) {
+ FeaturePtr aCurFeature = ModelAPI_Feature::feature(*aFIt);
+ copyFeature(aCurFeature, aNewSketch, aMapOldNew);
+ }
+
+ aNewSketch->execute();
+
+ // check number of copies of the selected sketch before name the new sketch
+ static const std::string SKETCH_NAME_SUFFIX("_Copy");
+ std::string aSketchName = aBaseSketch->name() + SKETCH_NAME_SUFFIX;
+ int aNewSketchIndex = 0;
+ std::list<FeaturePtr> aFeatures = document()->allFeatures();
+ for (std::list<FeaturePtr>::iterator aFIt = aFeatures.begin(); aFIt != aFeatures.end(); ++aFIt) {
+ if ((*aFIt)->getKind() != SketchPlugin_Sketch::ID())
+ continue;
+ int anIndex = index((*aFIt)->name(), aSketchName);
+ if (anIndex >= aNewSketchIndex)
+ aNewSketchIndex = anIndex + 1;
+ anIndex = index((*aFIt)->lastResult()->data()->name(), aSketchName);
+ if (anIndex >= aNewSketchIndex)
+ aNewSketchIndex = anIndex + 1;
+ }
+ std::ostringstream aNameStream;
+ aNameStream << aSketchName;
+ if (aNewSketchIndex > 0)
+ aNameStream << '_' << aNewSketchIndex;
+ aNewSketch->data()->setName(aNameStream.str());
+ aNewSketch->lastResult()->data()->setName(aNameStream.str());
+}
--- /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
+//
+
+#ifndef SketchPlugin_SketchCopy_H_
+#define SketchPlugin_SketchCopy_H_
+
+#include "SketchPlugin.h"
+#include <ModelAPI_Feature.h>
+
+/// \class SketchPlugin_SketchCopy
+/// \ingroup Plugins
+/// \brief Feature for copy of a sketch and all its sub-features to the same plane.
+class SketchPlugin_SketchCopy : public ModelAPI_Feature
+{
+public:
+ /// A constructor
+ SketchPlugin_SketchCopy();
+
+ /// Feature kind.
+ inline static const std::string& ID()
+ {
+ static const std::string MY_FEATURE_ID("SketchCopy");
+ return MY_FEATURE_ID;
+ }
+
+ /// Attribute name of the base sketch selected.
+ inline static const std::string& BASE_ID()
+ {
+ static const std::string ID("base_sketch");
+ return ID;
+ }
+
+ /// \return the kind of a feature.
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = SketchPlugin_SketchCopy::ID();
+ return MY_KIND;
+ }
+
+ /// Creates a new sketch.
+ SKETCHPLUGIN_EXPORT virtual void execute();
+
+ /// Request for initialization of data model of the feature: adding all attributes.
+ SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Means that feature is removed on apply.
+ SKETCHPLUGIN_EXPORT virtual bool isMacro() const {return true;}
+
+ /// No preview is generated until it is applied.
+ SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const {return false;}
+};
+
+#endif
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
{
- if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) {
+ if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId() &&
+ theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
theError = "The attribute with the %1 type is not processed";
theError.arg(theAttribute->attributeType());
return false;
}
// check the attribute refers to a sketch feature
+ bool isSketchFeature = false;
AttributeRefAttrPtr aRefAttr =
std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
- bool isSketchFeature = aRefAttr->isObject();
- if (isSketchFeature) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
- isSketchFeature = aFeature.get() != NULL;
+ if (aRefAttr) {
+ isSketchFeature = aRefAttr->isObject();
if (isSketchFeature) {
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- isSketchFeature = aSketchFeature.get() != NULL;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
+ isSketchFeature = aFeature.get() != NULL;
+ if (isSketchFeature) {
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ isSketchFeature = aSketchFeature.get() != NULL;
+ }
+ }
+ }
+ else {
+ AttributeReferencePtr aReference =
+ std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+ if (aReference) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aReference->value());
+ isSketchFeature = aFeature.get() && aFeature->getKind() == SketchPlugin_Sketch::ID();
}
}
- if (isSketchFeature)
- return true;
-
- theError = "The object selected is not a sketch feature";
- return false;
+ if (!isSketchFeature)
+ theError = "The object selected is not a sketch feature";
+ return isSketchFeature;
}
bool SketchPlugin_MultiRotationAngleValidator::isValid(const AttributePtr& theAttribute,
<source>Sketch</source>
<translation>Esquisse</translation>
</message>
+ <message>
+ <source>Sketch copy</source>
+ <translation>Copie d'esquisse</translation>
+ </message>
<message>
<source>Sketch drawer</source>
<translation>Créer une esquisse à partir d'un contour</translation>
</message>
</context>
+ <!-- SketchCopy -->
+ <context>
+ <name>SketchCopy</name>
+ <message>
+ <source>Sketch copy</source>
+ <translation>Copie s'esquisse</translation>
+ </message>
+ <message>
+ <source>Copy sketch and all its elements to the same plane</source>
+ <translation>Copiez l'esquisse et tous ses éléments dans le même plan</translation>
+ </message>
+ <message>
+ <source>Error: a base feature is not a sketch.</source>
+ <translation>Erreur: une fonction de base n'est pas une esquisse.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchCopy:Model_FeatureValidator</name>
+ <message>
+ <source>Attribute "base_sketch" is not initialized.</source>
+ <translation>Sélectionnez une esquisse à copier.</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchCopy:base_sketch</name>
+ <message>
+ <source>Attribute "%1" is not initialized.</source>
+ <translation>Sélectionnez une esquisse à copier.</translation>
+ </message>
+ <message>
+ <source>Select a sketch to copy.</source>
+ <translation>Sélectionnez une esquisse à copier.</translation>
+ </message>
+ <message>
+ <source>Sketch:</source>
+ <translation>Esquisse:</translation>
+ </message>
+ </context>
+ <context>
+ <name>SketchCopy:base_sketch:SketchPlugin_SketchFeatureValidator</name>
+ <message>
+ <source>The object selected is not a sketch feature</source>
+ <translation>L'objet sélectionné n'est pas une fonction d'esquisse</translation>
+ </message>
+ </context>
+
<!-- SketchDrawer -->
<context>
<name>SketchDrawer</name>
--- /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 SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Sketch_1_Copy = model.copySketch(partSet, Sketch_1)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+assert(partSet.size("Features") == 2)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 10, 0)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [5])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_1, [213109.1306148178])
+
+assert(partSet.size("Features") == 2)
+assert(Part_1_doc.size("Features") == 2)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 0, 10)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+model.testNbResults(Extrusion_2, 1)
+model.testNbSubResults(Extrusion_2, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_2, [213109.1306148178])
+
+assert(partSet.size("Features") == 2)
+assert(Part_1_doc.size("Features") == 3)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+
+# copy sketch to the partSet after the part
+Sketch_1_Copy = model.copySketch(partSet, Sketch_1)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+assert(partSet.size("Features") == 3)
+assert(Part_1_doc.size("Features") == 1)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 10, 0)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [5])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_1, [213109.1306148178])
+
+assert(partSet.size("Features") == 1)
+assert(Part_1_doc.size("Features") == 3)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 0, 10)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+model.testNbResults(Extrusion_2, 1)
+model.testNbSubResults(Extrusion_2, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_2, [213109.1306148178])
+
+assert(partSet.size("Features") == 1)
+assert(Part_1_doc.size("Features") == 4)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+
+Sketch_1_Copy = model.copySketch(partSet, Sketch_1)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+assert(partSet.size("Features") == 2)
+assert(Part_1_doc.size("Features") == 2)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Sketch_1_Copy = model.copySketch(Part_2_doc, Sketch_1)
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 0, 10)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+model.testNbResults(Extrusion_2, 1)
+model.testNbSubResults(Extrusion_2, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_2, [213109.1306148178])
+
+assert(partSet.size("Features") == 2)
+assert(Part_1_doc.size("Features") == 2)
+assert(Part_2_doc.size("Features") == 2)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, -72, 0, -72)
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.result())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_3 = SketchProjection_2.createdFeature()
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, -72, 72, 0, False)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.result(), SketchArc_1.endPoint())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 40)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 72)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_1.endPoint())
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(25, 0, 25, 74.98833242578475, 72, 0, 25, 88.5, False)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.result(), SketchEllipticArc_1.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchEllipticArc_1.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchEllipticArc_1.endPoint(), SketchAPI_Line(SketchLine_4).endPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_6 = Sketch_1.addLine(7.834161075251729, 88.5, 25, 88.5)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchEllipticArc_1.majorAxisPositive(), SketchLine_6.endPoint())
+SketchArc_2 = Sketch_1.addArc(-40, -8.616197183098587, -40, -72, -94.21171510314713, 24.22579430808612, True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(-60, 3.5, -94.21171510314713, 24.22579430808612, -60, 43.5, True)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_3.results()[1], 40)
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_4.result(), SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchAPI_Point(SketchPoint_1).coordinates(), 25, True)
+SketchLine_7 = Sketch_1.addLine(-40, -72, -40, -8.616197183098587)
+SketchLine_7.setAuxiliary(True)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_7.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_7.result(), 90, type = "Direct")
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchArc_3.endPoint(), SketchAPI_Line(SketchLine_2).startPoint(), 60)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchArc_3.endPoint(), SketchLine_6.startPoint(), 45)
+SketchLine_8 = Sketch_1.addLine(-60, 3.5, -60, 43.5)
+SketchLine_8.setAuxiliary(True)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_3.center(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_8.endPoint())
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_7.result(), SketchLine_8.result())
+SketchCircle_1 = Sketch_1.addCircle(-60, 66, 22.5)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_8.result(), SketchCircle_1.center())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_6.result(), SketchCircle_1.results()[1])
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_3.result(), 66, True)
+SketchBSpline_1 = Sketch_1.addSpline(poles = [(-60, 43.5), (-40, 43.5), (-11.56553854601814, 88.5), (8.434461453981855, 88.5)], weights = [1, 3, 3, 1])
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11] = SketchBSpline_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_9, SketchLine_10, SketchLine_11] = SketchBSpline_1.controlPolygon(auxiliary = [0, 1, 2])
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_11).coordinates(), SketchLine_6.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_8).coordinates(), SketchArc_3.endPoint())
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_10).endPoint(), SketchLine_6.result())
+SketchLine_12 = Sketch_1.addLine(-19.07878402833891, -6, -23.3, -6)
+SketchLine_13 = Sketch_1.addLine(-23.3, -6, -23.3, 6)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchLine_14 = Sketch_1.addLine(-23.3, 6, -19.07878402833891, 6)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_14.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_13.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchArc_4 = Sketch_1.addArc(0, 0, -19.07878402833891, -6, -19.07878402833891, 6, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_2).startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchArc_4.endPoint())
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_12.startPoint(), SketchArc_4.startPoint())
+SketchPoint_12 = Sketch_1.addPoint(-23.3, 0)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchPoint_12.coordinates(), SketchLine_3.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchPoint_12.coordinates(), SketchLine_13.result())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchArc_4.results()[1], 20)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_13.result(), 12)
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchPoint_12.coordinates(), SketchAPI_Line(SketchLine_2).startPoint(), 23.3, True)
+SketchBSplinePeriodic_1 = Sketch_1.addSpline(poles = [(-80, -23), (-80, 0), (-50, 0), (-50, -23)], periodic = True)
+[SketchPoint_13, SketchPoint_14, SketchPoint_15, SketchPoint_16] = SketchBSplinePeriodic_1.controlPoles(auxiliary = [0, 1, 2, 3])
+[SketchLine_15, SketchLine_16, SketchLine_17, SketchLine_18] = SketchBSplinePeriodic_1.controlPolygon(auxiliary = [0, 1, 2, 3])
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_16.result(), SketchLine_5.result())
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_18.result(), SketchLine_16.result())
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_15.result(), SketchLine_17.result())
+SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchLine_18.result(), SketchLine_15.result())
+SketchEllipse_1 = Sketch_1.addEllipse(35, 45, 35, 67.91287847483518, 10)
+[SketchPoint_17, SketchPoint_18, SketchPoint_19, SketchPoint_20, SketchPoint_21, SketchPoint_22, SketchPoint_23, SketchLine_19, SketchLine_20] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_4.result(), SketchLine_19.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_16.result(), 30)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_15.result(), 23)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_19.result(), 50)
+SketchConstraintLength_6 = Sketch_1.setLength(SketchLine_20.result(), 20)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_17).startPoint(), SketchArc_4.center(), 50, True)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_23).coordinates(), SketchLine_4.result())
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchAPI_Point(SketchPoint_17).coordinates(), SketchLine_3.result(), 45, True)
+SketchCircle_2 = Sketch_1.addCircle(0, 66, 12)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_2.result(), SketchCircle_2.center())
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], 12)
+SketchLine_21 = Sketch_1.addLine(-60, 66, 0, 66)
+SketchLine_21.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_21.startPoint())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_21.result())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchCircle_2.center())
+model.do()
+
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchArc_1_2f-SketchEllipticArc_1f-SketchLine_6r-SketchBSpline_1r-SketchArc_3_2f-SketchArc_2_2f-SketchLine_12f-SketchLine_13f-SketchLine_14f-SketchArc_4_2r-SketchBSplinePeriodic_1f-SketchEllipse_1r-SketchCircle_2_2r")], model.selection(), 10, 0)
+
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Point_1 = model.addPoint(Part_2_doc, 10, 10, 10)
+Sketch_1_Copy = model.copySketch(Part_2_doc, Sketch_1)
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("FACE", Sketch_1_Copy.name())], model.selection(), 0, 10)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+model.testNbResults(Extrusion_1, 1)
+model.testNbSubResults(Extrusion_1, [0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [16])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [84])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [168])
+model.testResultsVolumes(Extrusion_1, [183140.3921289446])
+
+model.testNbResults(Extrusion_2, 1)
+model.testNbSubResults(Extrusion_2, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [5])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [31])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [126])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [252])
+model.testResultsVolumes(Extrusion_2, [213109.1306148178])
+
+assert(partSet.size("Features") == 2)
+assert(Part_1_doc.size("Features") == 2)
+assert(Part_2_doc.size("Features") == 3)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOZ"))
+SketchIntersectionPoint_1 = Sketch_1.addIntersectionPoint(model.selection("EDGE", "[Cylinder_1_1/Face_1][Cylinder_1_1/Face_2]"), True)
+[SketchPoint_1, SketchPoint_2] = SketchIntersectionPoint_1.intersectionPoints()
+SketchCircle_1 = Sketch_1.addCircle(5, 10, 3)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 3)
+SketchMultiTranslation_1 = Sketch_1.addTranslation([SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_2).coordinates(), SketchAPI_Point(SketchPoint_1).coordinates(), 3)
+[SketchCircle_2, SketchCircle_3] = SketchMultiTranslation_1.translated()
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_2).coordinates(), 360, 5, True)
+[SketchCircle_4, SketchCircle_5, SketchCircle_6, SketchCircle_7] = SketchMultiRotation_1.rotated()
+SketchLine_1 = Sketch_1.addLine(2.5, 1, 12.5, 5)
+SketchLine_1.setAuxiliary(True)
+SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.result())
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_1.result(), [SketchCircle_1.results()[1]])
+[SketchCircle_8] = SketchConstraintMirror_1.mirrored()
+model.do()
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", Sketch_1_Copy.name())], model.selection(), 10, 0)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+VOL = 282.743338823
+
+model.testNbResults(Extrusion_1, 8)
+model.testNbSubResults(Extrusion_1, [0, 0, 0, 0, 0, 0, 0, 0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1, 1, 1, 1, 1, 1, 1, 1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [3, 3, 3, 3, 3, 3, 3, 3])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [6, 6, 6, 6, 6, 6, 6, 6])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [12, 12, 12, 12, 12, 12, 12, 12])
+model.testResultsVolumes(Extrusion_1, [VOL, VOL, VOL, VOL, VOL, VOL, VOL, VOL])
+
+assert(Part_1_doc.size("Features") == 4)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOZ"))
+SketchIntersectionPoint_1 = Sketch_1.addIntersectionPoint(model.selection("EDGE", "[Cylinder_1_1/Face_1][Cylinder_1_1/Face_2]"), True)
+[SketchPoint_1, SketchPoint_2] = SketchIntersectionPoint_1.intersectionPoints()
+SketchCircle_1 = Sketch_1.addCircle(5, 10, 3)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_1).coordinates(), SketchCircle_1.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 3)
+SketchMultiTranslation_1 = Sketch_1.addTranslation([SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_2).coordinates(), SketchAPI_Point(SketchPoint_1).coordinates(), 3)
+[SketchCircle_2, SketchCircle_3] = SketchMultiTranslation_1.translated()
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_2).coordinates(), 360, 5, True)
+[SketchCircle_4, SketchCircle_5, SketchCircle_6, SketchCircle_7] = SketchMultiRotation_1.rotated()
+SketchLine_1 = Sketch_1.addLine(2.699367028097859, 1.399671792347037, 12.16381438587305, 5.532036131657337)
+SketchLine_1.setAuxiliary(True)
+SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.result())
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_1.result(), [SketchCircle_1.results()[1]])
+[SketchCircle_8] = SketchConstraintMirror_1.mirrored()
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", Sketch_1_Copy.name())], model.selection(), 0, 10)
+
+model.end()
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+VOL = 282.743338823
+
+model.testNbResults(Extrusion_1, 8)
+model.testNbSubResults(Extrusion_1, [0, 0, 0, 0, 0, 0, 0, 0])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1, 1, 1, 1, 1, 1, 1, 1])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [3, 3, 3, 3, 3, 3, 3, 3])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [6, 6, 6, 6, 6, 6, 6, 6])
+model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [12, 12, 12, 12, 12, 12, 12, 12])
+model.testResultsVolumes(Extrusion_1, [VOL, VOL, VOL, VOL, VOL, VOL, VOL, VOL])
+
+model.testNbResults(Extrusion_2, 8)
+model.testNbSubResults(Extrusion_2, [0, 0, 0, 0, 0, 0, 0, 0])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [1, 1, 1, 1, 1, 1, 1, 1])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [3, 3, 3, 3, 3, 3, 3, 3])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [6, 6, 6, 6, 6, 6, 6, 6])
+model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [12, 12, 12, 12, 12, 12, 12, 12])
+model.testResultsVolumes(Extrusion_2, [VOL, VOL, VOL, VOL, VOL, VOL, VOL, VOL])
+
+assert(Part_1_doc.size("Features") == 5)
+
+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 GeomAPI import *
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Top"))
+SketchCircle_1 = Sketch_1.addCircle(2, 2, 1)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_1.result(), 2, True)
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_2.result(), 2, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 1)
+model.do()
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 0, 10, [model.selection("SOLID", "Box_1_1")])
+
+Distance = model.lastSubFeature(Sketch_1_Copy, "SketchConstraintDistance")
+SketchAPI_Constraint(Distance).setValue(6)
+model.do()
+
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1_Copy")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
+
+model.end()
+
+model.testNbResults(ExtrusionCut_2, 1)
+model.testNbSubResults(ExtrusionCut_2, [0])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.FACE, [8])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.EDGE, [36])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.VERTEX, [72])
+model.testResultsVolumes(ExtrusionCut_2, [937.1681469282])
+
+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 GeomAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Box_1_1")])
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Box_1_1/Top"))
+SketchCircle_1 = Sketch_1.addCircle(2, 2, 1)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_1.result(), 2, True)
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_2.result(), 2, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 1)
+ExtrusionCut_1.setNestedSketch(Sketch_1)
+
+Sketch_1_Copy = model.copySketch(Part_1_doc, Sketch_1)
+
+error = model.compareSketches(Sketch_1, Sketch_1_Copy)
+assert(error == ""), error
+
+Distance = model.lastSubFeature(Sketch_1_Copy, "SketchConstraintDistance")
+SketchAPI_Constraint(Distance).setValue(6)
+model.do()
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1_Copy")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_1_1")])
+
+model.end()
+
+model.testNbResults(ExtrusionCut_2, 1)
+model.testNbSubResults(ExtrusionCut_2, [0])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.FACE, [8])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.EDGE, [36])
+model.testNbSubShapes(ExtrusionCut_2, GeomAPI_Shape.VERTEX, [72])
+model.testResultsVolumes(ExtrusionCut_2, [937.1681469282])
+
+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
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(50, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 50)
+SketchLine_3 = Sketch_1.addLine(0, 50, 50, 50)
+SketchLine_4 = Sketch_1.addLine(50, 50, 50, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_1.result(), SketchLine_2.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 50)
+model.do()
+
+Copy1 = model.copySketch(partSet, Sketch_1)
+Copy2 = model.copySketch(partSet, Sketch_1)
+Copy3 = model.copySketch(partSet, Sketch_1)
+
+model.end()
+
+features = [Sketch_1, Copy1, Copy2, Copy3]
+for ind1 in range(len(features)):
+ for ind2 in range(ind1 + 1, len(features)):
+ assert(features[ind1].name() != features[ind2].name())
+
+assert(model.checkPythonDump())
translationFeature.rst
rotationFeature.rst
sketchDrawer.rst
+ sketchCopy.rst
--- /dev/null
+
+ .. _tui_copy_sketch:
+
+Sketch copy
+===========
+
+.. literalinclude:: examples/sketchcopy.py
+ :linenos:
+ :language: python
+
+:download:`Download this script <examples/sketchcopy.py>`
--- /dev/null
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(50, 0, 0, 0)
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 50)
+SketchLine_3 = Sketch_1.addLine(0, 50, 50, 50)
+SketchLine_4 = Sketch_1.addLine(50, 50, 50, 0)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+
+Sketch_1_Copy = model.copySketch(partSet, Sketch_1)
+
+model.end()
\ No newline at end of file
--- /dev/null
+.. _create_sketch_copy:
+.. |SketchCopy.icon| image:: images/SketchCopy.png
+
+Sketch Copy
+===========
+
+This macro will just copy the selected sketch feature into a new sketch feature and disappear.
+So, the new sketch feature will be placed into the current history location with all sub-elements
+of the sketch copied.
+
+To start a Sketch Copy operation:
+
+#. select in the Main Menu *Macros - > Sketch Copy* item or
+#. click |SketchCopy.icon| **Sketch Copy** button in Macros toolbar:
+
+The following property panel appears:
+
+.. image:: images/SketchCopy_panel.png
+ :align: center
+
+.. centered::
+ Sketch copy panel
+
+Select a sketch feature to copy. On Apply button press the copied sketch will be created in the Object Browser tree.
+
+
+**TUI Command**:
+
+.. py:function:: model.copySketch(Doc, Sketch)
+
+ :param document: A document where to copy the sketch.
+ :param object: A sketch to be copied.
+ :return: Copied sketch.
+
+**See Also** a sample TUI Script of :ref:`tui_copy_sketch` operation.
--- /dev/null
+<plugin>
+ <workbench id="Macros">
+ <group id="Sketch">
+ <feature id="SketchCopy"
+ title="Sketch copy"
+ tooltip="Copy sketch and all its elements to the same plane"
+ icon="icons/Sketch/copy.png"
+ helpfile="sketchCopy.html">
+ <feature_selector id="base_sketch"
+ label="Sketch:"
+ tooltip="Select a sketch to copy.">
+ <validator id="SketchPlugin_SketchFeatureValidator"/>
+ </feature_selector>
+ </feature>
+ </group>
+ </workbench>
+</plugin>
<plugin>
<workbench id="Macros" document="Part">
- <group id="Samples">
+ <group id="Sketch">
<feature id="SketchDrawer" title="Sketch drawer" tooltip="Creates sketch using elements of selected shape belonging to selected plane"
icon="icons/Sketch/drawer.png"