Salome HOME
Implementation of SketchCopy feature
authorArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Mon, 6 Apr 2020 06:57:15 +0000 (09:57 +0300)
committerArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Mon, 6 Apr 2020 09:04:53 +0000 (12:04 +0300)
37 files changed:
src/Config/plugins.xml.in
src/ModelAPI/ModelAPI.i
src/ModelHighAPI/ModelHighAPI_Dumper.cpp
src/PythonAPI/model/sketcher/__init__.py
src/PythonAPI/model/sketcher/tests.py
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/SketchPlugin_Projection.cpp
src/SketchPlugin/SketchPlugin_SketchCopy.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_SketchCopy.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_msg_fr.ts
src/SketchPlugin/Test/TestSketchCopy01.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy02.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy03.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy04.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy05.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy06.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy07.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy08.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy09.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy10.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy11.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy12.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy13.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchCopy14.py [new file with mode: 0644]
src/SketchPlugin/doc/SketchPlugin.rst
src/SketchPlugin/doc/TUI_sketchCopy.rst [new file with mode: 0644]
src/SketchPlugin/doc/examples/sketchcopy.py [new file with mode: 0644]
src/SketchPlugin/doc/images/SketchCopy.png [new file with mode: 0644]
src/SketchPlugin/doc/images/SketchCopy_panel.png [new file with mode: 0644]
src/SketchPlugin/doc/sketchCopy.rst [new file with mode: 0644]
src/SketchPlugin/icons/copy.png [new file with mode: 0644]
src/SketchPlugin/plugin-SketchCopy.xml [new file with mode: 0644]
src/SketchPlugin/plugin-SketchDrawer.xml

index 77c60c23c3efd7c8be4b63ce1cff38e221955a50..7c23b377e2d0a272b04a7b945f0a8e59e7c9c188 100644 (file)
@@ -12,6 +12,7 @@
   <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@
index d0f093813b9a422003990c9a72319907b416b4b1..5652538b04cca5ae1009f5da32afc2521829034f 100644 (file)
 
 // 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> >;
index 10d5385ea8f921380e431038e575ab995c8dc55d..f1a61c254903bd4921a664c27d788a7ea71d60da 100644 (file)
@@ -332,8 +332,18 @@ static int possibleSelectionsByPoint(const GeomPointPtr& thePoint,
 
   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;
index f2e2fbebe3fc51b3ee28008d02dd3e4de738cc1c..b93424b8614f90ceb8cee6afee5cfa97ef5e1dd8 100644 (file)
@@ -19,6 +19,6 @@
 """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 *
index 2d52f70bcf6d3ad1651f735e2e7ee26236493208..95eafa10cc182fd721a53750f0ffdf435596217b 100644 (file)
@@ -108,3 +108,89 @@ def checkSketchErrorDegenerated(theSketch):
     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
index 7b472113e72a508ca7e994bf0a65629c18d8d4e1..6ce7550f005e1bad1fda95aec479f5972fcd4e47 100644 (file)
@@ -41,6 +41,7 @@
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
 #include <SketchPlugin_MacroBSpline.h>
+#include <SketchPlugin_SketchCopy.h>
 #include <SketcherPrs_Tools.h>
 //--------------------------------------------------------------------------------------
 #include <ModelAPI_Events.h>
@@ -233,6 +234,23 @@ SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
   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()
index e8a2b089f1136b92fbe99f3633a4cdc4a19bc3fe..11b6ed91fb41b9a19df53c7d6f276bcbcd5e174c 100644 (file)
@@ -560,6 +560,8 @@ protected:
 //! Pointer on Sketch object
 typedef std::shared_ptr<SketchAPI_Sketch> SketchPtr;
 
+//--------------------------------------------------------------------------------------
+
 /**\ingroup CPPHighAPI
  * \brief Create Sketch feature
  */
@@ -589,5 +591,13 @@ SketchPtr addSketch(const std::shared_ptr<ModelAPI_Document> & thePart,
                     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_ */
index 91ddabcc94059eb202a21b76ee93e3538263bb47..f9ada5439d69d4d5e56e35887d7ba77f11fb4d67 100644 (file)
@@ -67,6 +67,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_Point.h
     SketchPlugin_Projection.h
     SketchPlugin_Sketch.h
+    SketchPlugin_SketchCopy.h
     SketchPlugin_SketchDrawer.h
     SketchPlugin_SketchEntity.h
     SketchPlugin_Split.h
@@ -119,6 +120,7 @@ SET(PROJECT_SOURCES
     SketchPlugin_Point.cpp
     SketchPlugin_Projection.cpp
     SketchPlugin_Sketch.cpp
+    SketchPlugin_SketchCopy.cpp
     SketchPlugin_SketchDrawer.cpp
     SketchPlugin_SketchEntity.cpp
     SketchPlugin_Split.cpp
@@ -140,6 +142,7 @@ SET(PROJECT_LIBRARIES
 
 SET(XML_RESOURCES
   plugin-Sketch.xml
+  plugin-SketchCopy.xml
   plugin-SketchDrawer.xml
 )
 
@@ -332,6 +335,20 @@ ADD_UNIT_TESTS(
   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
index db8995277246a8b5f079cea9fa7ac79e91e4e247..3d11107a7ccd24129f7f68bb61e04f65031208e1 100644 (file)
@@ -60,6 +60,7 @@
 #include <SketchPlugin_EllipticArc.h>
 #include <SketchPlugin_MacroEllipticArc.h>
 #include <SketchPlugin_SketchDrawer.h>
+#include <SketchPlugin_SketchCopy.h>
 
 #include <SketcherPrs_Tools.h>
 
@@ -276,6 +277,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(std::string theFeatureID)
     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();
index e069a3567a2806864d22a508db7ac7ba0e91a16f..5cb9740c1c74ebe3393aaf76949a0276e231af76 100644 (file)
@@ -219,7 +219,7 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
   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();
diff --git a/src/SketchPlugin/SketchPlugin_SketchCopy.cpp b/src/SketchPlugin/SketchPlugin_SketchCopy.cpp
new file mode 100644 (file)
index 0000000..24ce8f5
--- /dev/null
@@ -0,0 +1,349 @@
+// 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());
+}
diff --git a/src/SketchPlugin/SketchPlugin_SketchCopy.h b/src/SketchPlugin/SketchPlugin_SketchCopy.h
new file mode 100644 (file)
index 0000000..cad8ed6
--- /dev/null
@@ -0,0 +1,69 @@
+// 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
index c2371806074ac4721f94829cfac2dfe210155cdd..f9107bc4f9f2f7c55c4d499195bc565abd5b2847 100644 (file)
@@ -1800,31 +1800,41 @@ bool SketchPlugin_SketchFeatureValidator::isValid(const AttributePtr& theAttribu
                                                   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,
index 8faf6bec1f50d6b1f91576e7f96999cdd83aea12..86f682282b786fc9a6225b2091549c988ea142b3 100644 (file)
       <source>Sketch</source>
       <translation>Esquisse</translation>
     </message>
+    <message>
+      <source>Sketch copy</source>
+      <translation>Copie d&apos;esquisse</translation>
+    </message>
     <message>
       <source>Sketch drawer</source>
       <translation>Créer une esquisse Ã  partir d&apos;un contour</translation>
     </message>
   </context>
 
+  <!-- SketchCopy -->
+  <context>
+    <name>SketchCopy</name>
+    <message>
+      <source>Sketch copy</source>
+      <translation>Copie s&apos;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&apos;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&apos;objet sélectionné n&apos;est pas une fonction d&apos;esquisse</translation>
+    </message>
+  </context>
+
   <!-- SketchDrawer -->
   <context>
     <name>SketchDrawer</name>
diff --git a/src/SketchPlugin/Test/TestSketchCopy01.py b/src/SketchPlugin/Test/TestSketchCopy01.py
new file mode 100644 (file)
index 0000000..fd412c5
--- /dev/null
@@ -0,0 +1,135 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy02.py b/src/SketchPlugin/Test/TestSketchCopy02.py
new file mode 100644 (file)
index 0000000..2ecbc71
--- /dev/null
@@ -0,0 +1,148 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy03.py b/src/SketchPlugin/Test/TestSketchCopy03.py
new file mode 100644 (file)
index 0000000..52d4e57
--- /dev/null
@@ -0,0 +1,157 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy04.py b/src/SketchPlugin/Test/TestSketchCopy04.py
new file mode 100644 (file)
index 0000000..6cef49b
--- /dev/null
@@ -0,0 +1,150 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy05.py b/src/SketchPlugin/Test/TestSketchCopy05.py
new file mode 100644 (file)
index 0000000..1bfb8ae
--- /dev/null
@@ -0,0 +1,148 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy06.py b/src/SketchPlugin/Test/TestSketchCopy06.py
new file mode 100644 (file)
index 0000000..fe30f87
--- /dev/null
@@ -0,0 +1,158 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy07.py b/src/SketchPlugin/Test/TestSketchCopy07.py
new file mode 100644 (file)
index 0000000..00274e7
--- /dev/null
@@ -0,0 +1,149 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy08.py b/src/SketchPlugin/Test/TestSketchCopy08.py
new file mode 100644 (file)
index 0000000..0c5ef32
--- /dev/null
@@ -0,0 +1,161 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy09.py b/src/SketchPlugin/Test/TestSketchCopy09.py
new file mode 100644 (file)
index 0000000..27a3417
--- /dev/null
@@ -0,0 +1,162 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy10.py b/src/SketchPlugin/Test/TestSketchCopy10.py
new file mode 100644 (file)
index 0000000..e2fdb90
--- /dev/null
@@ -0,0 +1,67 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy11.py b/src/SketchPlugin/Test/TestSketchCopy11.py
new file mode 100644 (file)
index 0000000..a912d4d
--- /dev/null
@@ -0,0 +1,76 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy12.py b/src/SketchPlugin/Test/TestSketchCopy12.py
new file mode 100644 (file)
index 0000000..478aee0
--- /dev/null
@@ -0,0 +1,64 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy13.py b/src/SketchPlugin/Test/TestSketchCopy13.py
new file mode 100644 (file)
index 0000000..c691a69
--- /dev/null
@@ -0,0 +1,61 @@
+# 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())
diff --git a/src/SketchPlugin/Test/TestSketchCopy14.py b/src/SketchPlugin/Test/TestSketchCopy14.py
new file mode 100644 (file)
index 0000000..1de3270
--- /dev/null
@@ -0,0 +1,55 @@
+# 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())
index 6d2a5af6cdfc2b135adbb6e6e0c5ca79c503dad1..e405acaa0f297ce13a568e43a3508411ba66451d 100644 (file)
@@ -181,3 +181,4 @@ The plug-in includes the following operations:
    translationFeature.rst
    rotationFeature.rst
    sketchDrawer.rst
+   sketchCopy.rst
diff --git a/src/SketchPlugin/doc/TUI_sketchCopy.rst b/src/SketchPlugin/doc/TUI_sketchCopy.rst
new file mode 100644 (file)
index 0000000..e453d0e
--- /dev/null
@@ -0,0 +1,11 @@
+
+  .. _tui_copy_sketch:
+
+Sketch copy
+===========
+
+.. literalinclude:: examples/sketchcopy.py
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/sketchcopy.py>`
diff --git a/src/SketchPlugin/doc/examples/sketchcopy.py b/src/SketchPlugin/doc/examples/sketchcopy.py
new file mode 100644 (file)
index 0000000..99eb188
--- /dev/null
@@ -0,0 +1,22 @@
+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
diff --git a/src/SketchPlugin/doc/images/SketchCopy.png b/src/SketchPlugin/doc/images/SketchCopy.png
new file mode 100644 (file)
index 0000000..b96aef6
Binary files /dev/null and b/src/SketchPlugin/doc/images/SketchCopy.png differ
diff --git a/src/SketchPlugin/doc/images/SketchCopy_panel.png b/src/SketchPlugin/doc/images/SketchCopy_panel.png
new file mode 100644 (file)
index 0000000..609bf81
Binary files /dev/null and b/src/SketchPlugin/doc/images/SketchCopy_panel.png differ
diff --git a/src/SketchPlugin/doc/sketchCopy.rst b/src/SketchPlugin/doc/sketchCopy.rst
new file mode 100644 (file)
index 0000000..4325074
--- /dev/null
@@ -0,0 +1,35 @@
+.. _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.
diff --git a/src/SketchPlugin/icons/copy.png b/src/SketchPlugin/icons/copy.png
new file mode 100644 (file)
index 0000000..b96aef6
Binary files /dev/null and b/src/SketchPlugin/icons/copy.png differ
diff --git a/src/SketchPlugin/plugin-SketchCopy.xml b/src/SketchPlugin/plugin-SketchCopy.xml
new file mode 100644 (file)
index 0000000..3d896b5
--- /dev/null
@@ -0,0 +1,17 @@
+<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>
index 44a6bf7a09e9531b6764f428edc101a60a21f215..88733aa414842bdf3584f43ab6e7fb438b9987fb 100644 (file)
@@ -1,6 +1,6 @@
 <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"