]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'master' into cgt/devCEA
authorClarisse Genrault <clarisse.genrault@cea.fr>
Thu, 6 Apr 2017 13:37:22 +0000 (15:37 +0200)
committerClarisse Genrault <clarisse.genrault@cea.fr>
Thu, 6 Apr 2017 13:37:22 +0000 (15:37 +0200)
43 files changed:
src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py
src/GeomAPI/GeomAPI_Face.cpp
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.h
src/GeomValidators/GeomValidators_BooleanArguments.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/Model/Model_SelectionNaming.cpp
src/ModelAPI/ModelAPI_Document.h
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_SketcherReentrantMgr.cpp
src/PartSet/PartSet_SketcherReentrantMgr.h
src/PartSet/PartSet_WidgetFeaturePointSelector.cpp
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/PartSetPlugin/PartSetPlugin_Part.cpp
src/PartSetPlugin/PartSetPlugin_Part.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Fillet.cpp
src/SketchPlugin/SketchPlugin_Projection.cpp
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/Test/Test2095.py [new file with mode: 0644]
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Manager.h
src/XGUI/XGUI_DataModel.cpp
test.models/bobine_film_reel.py
test.models/bracket32.py
test.models/bushing.py
test.models/case24.py
test.models/ecran.py
test.models/gear.py
test.models/idler_plate.py [new file with mode: 0644]

index c59d9e249ad83e13c585245001a514866d5917bb..6427951a11fbc65975ce27473272367101a31067 100644 (file)
@@ -132,7 +132,8 @@ class ExportFeature(ModelAPI.ModelAPI_Feature):
             aSelection = theSelectionList.value(aSelIndex)
             # issue 1326: bodies that are already concealed did not exported, so groups should not be invalid
             aContext =  ModelAPI.modelAPI_Result(aSelection.context())
-            if aContext is None or aContext.isConcealed() or aContext.isDisabled():
+            # chcking of concealment removed because of #1799, remark #13 "aContext.isConcealed()"
+            if aContext is None or aContext.isDisabled():
                 continue
 
             anID = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(self.shape, aSelection.value())
index e6453787e9ba54ee047f995dd6d7e06f86125b87..6dac2d05762cbc2fc1229ff62360bd9ecc5e844b 100644 (file)
@@ -68,7 +68,9 @@ bool GeomAPI_Face::isEqual(std::shared_ptr<GeomAPI_Shape> theFace) const
     return false;
 
   Handle(IntTools_Context) aContext = new IntTools_Context();
-  Standard_Boolean aRes = BOPTools_AlgoTools::CheckSameGeom(aMyFace, aInFace, aContext);
+  // Double check needed bacause BOPTools_AlgoTools::CheckSameGeom not very smart.
+  Standard_Boolean aRes = BOPTools_AlgoTools::CheckSameGeom(aMyFace, aInFace, aContext)
+    && BOPTools_AlgoTools::CheckSameGeom(aInFace, aMyFace, aContext);
 
   return aRes == Standard_True;
 }
index c811116dff5529eb7b96243b3eecbd07d05bdf2d..78179ec86047d1ea1e080a01d62c28b66307bf33 100644 (file)
@@ -10,6 +10,7 @@
 #include <BRepAlgoAPI_Section.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepTools.hxx>
 #include <Bnd_Box.hxx>
 #include <Geom_Circle.hxx>
@@ -31,6 +32,8 @@
 #include <sstream>
 #include <algorithm> // for std::transform
 
+#include <BRepTools.hxx>
+
 #define MY_SHAPE implPtr<TopoDS_Shape>()
 
 GeomAPI_Shape::GeomAPI_Shape()
@@ -455,3 +458,21 @@ GeomShapePtr GeomAPI_Shape::intersect(const GeomShapePtr theShape) const
   aResShape->setImpl(new TopoDS_Shape(aResult));
   return aResShape;
 }
+
+bool GeomAPI_Shape::isIntersect(const GeomShapePtr theShape) const
+{
+  if(!theShape.get()) {
+    return false;
+  }
+
+  const TopoDS_Shape& aShape1 = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aShape2 = theShape->impl<TopoDS_Shape>();
+
+  BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
+  aDist.Perform();
+  if(aDist.IsDone() && aDist.Value() < Precision::Confusion()) {
+    return true;
+  }
+
+  return false;
+}
index 1c7f2c7f849e06a1ff6fa0640224799a82434ad7..fa1b7766b87ef4082e6da6d3e2619b042666c9d4 100644 (file)
@@ -124,6 +124,10 @@ public:
   /// Returns intersection of shapes
   GEOMAPI_EXPORT
   std::shared_ptr<GeomAPI_Shape> intersect(const std::shared_ptr<GeomAPI_Shape> theShape) const;
+
+  /// Returns true if min distance between shapes < tolerance.
+  GEOMAPI_EXPORT
+  bool isIntersect(const std::shared_ptr<GeomAPI_Shape> theShape) const;
 };
 
 //! Pointer on list of shapes
index fed51bda42259a13c5fd7b044fec652012b84b46..8cb92153842d53e5ff13ab672b42532a041c5b4e 100644 (file)
@@ -54,6 +54,21 @@ std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
   return aRes;
 }
 
+std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
+    const std::shared_ptr<GeomAPI_Lin> theLin)
+{
+  if(!theLin.get()) {
+    return std::shared_ptr<GeomAPI_Edge>();
+  }
+
+  const gp_Lin& aLin = theLin->impl<gp_Lin>();
+  BRepBuilderAPI_MakeEdge anEdgeBuilder(aLin);
+  std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge());
+  TopoDS_Edge anEdge = anEdgeBuilder.Edge();
+  aRes->setImpl(new TopoDS_Shape(anEdge));
+  return aRes;
+}
+
 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::cylinderAxis(
     std::shared_ptr<GeomAPI_Shape> theCylindricalFace)
 {
@@ -143,6 +158,21 @@ std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircle(
   return aRes;
 }
 
+std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircle(
+    std::shared_ptr<GeomAPI_Circ> theCircle)
+{
+  if(!theCircle.get()) {
+    return std::shared_ptr<GeomAPI_Edge>();
+  }
+
+  const gp_Circ& aCirc = theCircle->impl<gp_Circ>();
+  BRepBuilderAPI_MakeEdge anEdgeBuilder(aCirc);
+  std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge());
+  TopoDS_Edge anEdge = anEdgeBuilder.Edge();
+  aRes->setImpl(new TopoDS_Shape(anEdge));
+  return aRes;
+}
+
 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircleArc(
     std::shared_ptr<GeomAPI_Pnt> theCenter, std::shared_ptr<GeomAPI_Pnt> theStartPoint,
     std::shared_ptr<GeomAPI_Pnt> theEndPoint, std::shared_ptr<GeomAPI_Dir> theNormal)
index b7b97aa7ee6818e881ed2106c38d0dd3e79adc09..a781ce219ac8ca76356f73c5ad29611fa0a4ad62 100644 (file)
@@ -11,6 +11,8 @@
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Dir.h>
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Circ.h>
 #include <memory>
 
 /**\class GeomAlgoAPI_EdgeBuilder
@@ -35,6 +37,10 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_EdgeBuilder
                                             double theDY,
                                             double theDZ);
 
+  /// Creates linear edge by GeomAPI_Lin.
+  /// \param theLin line.
+  static std::shared_ptr<GeomAPI_Edge> line(const std::shared_ptr<GeomAPI_Lin> theLin);
+
   /// Creates edge - axis of the given cylindrical face. The result axis edge is infinite
   static std::shared_ptr<GeomAPI_Edge> cylinderAxis(
     std::shared_ptr<GeomAPI_Shape> theCylindricalFace);
@@ -44,6 +50,9 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_EdgeBuilder
                                                     std::shared_ptr<GeomAPI_Dir> theNormal,
                                                     double theRadius);
 
+  /// Creates linear edge in a form of a circle by GeomAPI_Circle
+  static std::shared_ptr<GeomAPI_Edge> lineCircle(std::shared_ptr<GeomAPI_Circ> theCircle);
+
   /// Creates linear edge in a form of a circle arc by a three points
   static std::shared_ptr<GeomAPI_Edge> lineCircleArc(std::shared_ptr<GeomAPI_Pnt> theCenter,
                                                        std::shared_ptr<GeomAPI_Pnt> theStartPoint,
index 54cb1069eee9ff42f5dc077f84c0e03324d5730a..7890550f28b1b658b72b516be3fe0e98b25358f2 100644 (file)
@@ -46,6 +46,7 @@ bool GeomValidators_BooleanArguments::isValid(const std::shared_ptr<ModelAPI_Fea
         }
       } else {
         isAllInSameCompSolid = false;
+        break;
       }
     }
   }
@@ -55,18 +56,21 @@ bool GeomValidators_BooleanArguments::isValid(const std::shared_ptr<ModelAPI_Fea
   anAttrSelList = theFeature->selectionList(*anIt);
   if(anAttrSelList) {
     aToolsNb = anAttrSelList->size();
-    for(int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
-      AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
-      ResultPtr aContext = anAttr->context();
-      ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
-      if(aResCompSolidPtr.get()) {
-        if(aCompSolid.get()) {
-          isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+    if(isAllInSameCompSolid) {
+      for(int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
+        AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
+        ResultPtr aContext = anAttr->context();
+        ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
+        if(aResCompSolidPtr.get()) {
+          if(aCompSolid.get()) {
+            isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
+          } else {
+            aCompSolid = aResCompSolidPtr;
+          }
         } else {
-          aCompSolid = aResCompSolidPtr;
+          isAllInSameCompSolid = false;
+          break;
         }
-      } else {
-        isAllInSameCompSolid = false;
       }
     }
   }
index 7c93ab7b596a35df445dca43627dc1d615ac12cd..bf263768d895e06125e3fbc25ab5c9a589b4dab9 100755 (executable)
@@ -1629,3 +1629,9 @@ void Model_Document::restoreNodesState(std::list<bool>& theStates) const
     }
   }
 }
+
+void Model_Document::eraseAllFeatures()
+{
+  if (myObjs)
+    myObjs->eraseAllFeatures();
+}
index 639d84b0b572c84c30f2fea5de99b22699e14c92..6d9c58b98969e353bc5d98dd55bdb7e4a2c17bc1 100644 (file)
@@ -225,6 +225,10 @@ class Model_Document : public ModelAPI_Document
   /// Returns true if theLater is in history of features creation later than theCurrent
   MODEL_EXPORT virtual bool isLater(FeaturePtr theLater, FeaturePtr theCurrent) const;
 
+  /// Just removes all features without touching the document data (to be able undo)
+  MODEL_EXPORT virtual void eraseAllFeatures();
+
+
  protected:
   //! Returns (creates if needed) the general label
   TDF_Label generalLabel() const;
index f635941b3aeecb60a10eb7658f76405799351d1c..b0964875d73c03b3de14be09f3ee13e0f217bcc9 100644 (file)
@@ -269,6 +269,13 @@ void Model_Objects::removeFeature(FeaturePtr theFeature)
   }
 }
 
+void Model_Objects::eraseAllFeatures()
+{
+  ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Feature::group());
+  myFeatures.Clear(); // just remove features without modification of DS
+  updateHistory(ModelAPI_Feature::group());
+}
+
 void Model_Objects::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis)
 {
   TDF_Label aFeaturesLab = featuresLabel();
@@ -667,7 +674,7 @@ void Model_Objects::synchronizeFeatures(
       aFeature = myFeatures.Find(aFeatureLabel);
       aKeptFeatures.insert(aFeature);
       if (anUpdatedMap.Contains(aFeatureLabel)) {
-        if (!theOpen) { // on abort/undo/redo reinitialize attributes is something is changed
+        if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed
           std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
             aFeature->data()->attributes("");
           std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
@@ -1073,7 +1080,7 @@ void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& t
   theProcessed.insert(theFeature);
   // for composites update subs recursively (sketch elements results are needed for the sketch)
   CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
-  if (aComp.get()) {
+  if (aComp.get() && aComp->getKind() != "Part") { // don't go inside of parts sub-features
     // update subs of composites first
     int aSubNum = aComp->numberOfSubs();
     for(int a = 0; a < aSubNum; a++) {
index c4bc24476d0c6debef193b6edfa8bee62ccd55eb..45b2ed0ba0b38009ea7ff0f23a5d57b0c60651cb 100644 (file)
@@ -212,6 +212,9 @@ class Model_Objects
   void synchronizeBackRefsForObject(
     const std::set<std::shared_ptr<ModelAPI_Attribute>>& theNewRefs, ObjectPtr theObject);
 
+  /// Just removes all features without touching the document data (to be able undo)
+  virtual void eraseAllFeatures();
+
  private:
   TDF_Label myMain; ///< main label of the data storage
 
index 42c97b2a973d366a2bd6812df240f23e840d1589..966618b183cfa0cdf552d703804df6b78b2a7813 100644 (file)
@@ -143,8 +143,11 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
   const bool theAnotherDoc)
 {
   std::string aName("Undefined name");
-  if(!theContext.get() || theContext->shape()->isNull())
+  if(!theContext.get()
+      || !theContext->shape().get()
+      || theContext->shape()->isNull()) {
     return !theDefaultName.empty() ? theDefaultName : aName;
+  }
 
   // if it is in result of another part
   std::shared_ptr<Model_Document> aDoc =
index 427b332671e649461e7bef7ddad2798e9d2511f9..3d4d75f7f70422e6473f9d55da7277cf2b07c682 100644 (file)
@@ -184,6 +184,9 @@ public:
   /// Appends the values to theStates list.
   MODELAPI_EXPORT virtual void restoreNodesState(std::list<bool>& theStates) const = 0;
 
+  /// Just removes all features without touching the document data (to be able undo)
+  MODELAPI_EXPORT virtual void eraseAllFeatures() = 0;
+
 protected:
   //! Only for SWIG wrapping it is here
   MODELAPI_EXPORT ModelAPI_Document();
index 39f9abc799b7e20de9e6ba9aa09aba247b15d782..fe5bff496eceae0bfe665b358a8a558a6590a0d7 100644 (file)
@@ -114,10 +114,11 @@ void ModuleBase_IModule::launchOperation(const QString& theCmdId,
         if (aMessage.get()) {
           ModuleBase_IPropertyPanel* aPanel = workshop()->propertyPanel();
           std::string aPrevAttribute = aReentrantFeature->processEvent(aMessage);
-          workshop()->errorMgr()->updateActions(aFeature);
-
-          ModuleBase_ModelWidget* aPrevWidget = aPanel->modelWidget(aPrevAttribute);
-          aPanel->activateNextWidget(aPrevWidget);
+          if (!aPrevAttribute.empty()) {
+            workshop()->errorMgr()->updateActions(aFeature);
+            ModuleBase_ModelWidget* aPrevWidget = aPanel->modelWidget(aPrevAttribute);
+            aPanel->activateNextWidget(aPrevWidget);
+          }
         }
       }
     }
index 81bf3970fe89dbc9b58d4b1e2d8dcbb8a1a79e06..48358bcfdd12809021c2ff2a01be70f2a19cc3a4 100755 (executable)
@@ -407,6 +407,7 @@ QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 //********************************************************************
 void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
 {
+  clearValidatedCash();
   activateSelectionAndFilters(true);
 
   if (!myFeature)
@@ -815,7 +816,7 @@ bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject,
     for (; anIt != aLast && !aFound; anIt++) {
       GeomShapePtr aCShape = *anIt;
       if (aCShape.get())
-        aFound = aCShape->isEqual(aShape);
+        aFound = aCShape->isSame(aShape);
     }
   }
   return aFound;
index f724f3aa64619fdb862a6802234b490320057cd1..7a9c2c78872af19e2650b8e2404e32920938aac9 100755 (executable)
 void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
                             const FeaturePtr& theFeature, const FeaturePtr& theSketch,
                             const ResultPtr& theResult,
-                            std::set<AttributePtr>& aSelectedAttributes,
-                            std::set<ResultPtr>& aSelectedResults)
+                            std::set<AttributePtr>& theSelectedAttributes,
+                            std::set<ResultPtr>& theSelectedResults,
+                            TopTools_MapOfShape& theShapes)
 {
   Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
   if (aBRepOwner.IsNull())
@@ -118,16 +119,17 @@ void getAttributesOrResults(const Handle(SelectMgr_EntityOwner)& theOwner,
                                                                     aBRepOwner->Selectable());
   if (aBRepOwner->HasShape()) {
     const TopoDS_Shape& aShape = aBRepOwner->Shape();
+    theShapes.Add(aShape);
     TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
     if (aShapeType == TopAbs_VERTEX) {
       AttributePtr aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theFeature,
                                                                     aShape, theSketch);
       if (aPntAttr.get() != NULL)
-        aSelectedAttributes.insert(aPntAttr);
+        theSelectedAttributes.insert(aPntAttr);
     }
     else if (aShapeType == TopAbs_EDGE &&
-             aSelectedResults.find(theResult) == aSelectedResults.end()) {
-      aSelectedResults.insert(theResult);
+             theSelectedResults.find(theResult) == theSelectedResults.end()) {
+      theSelectedResults.insert(theResult);
     }
   }
 }
@@ -443,6 +445,10 @@ void PartSet_SketcherMgr::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouse
       // Only for sketcher operations
       if (aWasDragging) {
         if (myDragDone) {
+          /// the previous selection is lost by mouse release in the viewer(Select method), but
+          /// it is still stored in myCurrentSelection. So, it is possible to restore selection
+          /// It is important for drag(edit with mouse) of sketch entities.
+          restoreSelection();
           myCurrentSelection.clear();
         }
       }
@@ -536,7 +542,7 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     for (; anIt != aLast; anIt++) {
       FeaturePtr aFeature = anIt.key();
 
-      std::set<AttributePtr> anAttributes = anIt.value().first;
+      std::set<AttributePtr> anAttributes = anIt.value().myAttributes;
       // Process selection by attribute: the priority to the attribute
       if (!anAttributes.empty()) {
         std::set<AttributePtr>::const_iterator anAttIt = anAttributes.begin(),
@@ -1485,8 +1491,9 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
     return;
 
   FeatureToSelectionMap::const_iterator anIt = theSelection.find(theFeature);
-  std::set<AttributePtr> aSelectedAttributes = anIt.value().first;
-  std::set<ResultPtr> aSelectedResults = anIt.value().second;
+  SelectionInfo anInfo = anIt.value();
+  std::set<AttributePtr> aSelectedAttributes = anInfo.myAttributes;
+  std::set<ResultPtr> aSelectedResults = anInfo.myResults;
 
   ModuleBase_IViewer* aViewer = theWorkshop->viewer();
 
@@ -1510,8 +1517,16 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
   // 2. found the feature results's owners
   std::list<ResultPtr> aResults = theFeature->results();
   std::list<ResultPtr>::const_iterator aIt;
-  for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt)
-  {
+
+  bool isSameShape = false;
+  if (aResults.size() > 0) {
+    ResultPtr aFirstResult = theFeature->firstResult();
+    if (aFirstResult.get() && aFirstResult->shape().get()) {
+      const TopoDS_Shape& aFirstShape = aFirstResult->shape()->impl<TopoDS_Shape>();
+      isSameShape = aFirstShape.IsEqual(anInfo.myFirstResultShape);
+    }
+  }
+  for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
     ResultPtr aResult = *aIt;
     AISObjectPtr aAISObj = aDisplayer->getAISObject(aResult);
     if (aAISObj.get() == NULL)
@@ -1520,10 +1535,11 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
 
     SelectMgr_IndexedMapOfOwner aSelectedOwners;
     aConnector->workshop()->selector()->selection()->entityOwners(anAISIO, aSelectedOwners);
+    bool aFoundLocalShape = false;
     for  ( Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++ ) {
       Handle(StdSelect_BRepOwner) anOwner =
         Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i));
-      if ( anOwner.IsNull() || !anOwner->HasShape() )
+      if ( anOwner.IsNull() || !anOwner->HasShape() || theOwnersToSelect.FindIndex(anOwner))
         continue;
       const TopoDS_Shape& aShape = anOwner->Shape();
       TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
@@ -1531,15 +1547,34 @@ void PartSet_SketcherMgr::getSelectionOwners(const FeaturePtr& theFeature,
         AttributePtr aPntAttr =
           PartSet_Tools::findAttributeBy2dPoint(theFeature, aShape, theSketch);
         if (aPntAttr.get() != NULL &&
-            aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end()) {
+            aSelectedAttributes.find(aPntAttr) != aSelectedAttributes.end())
+          theOwnersToSelect.Add(anOwner);
+        else if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) {
           theOwnersToSelect.Add(anOwner);
         }
       }
       else if (aShapeType == TopAbs_EDGE) {
-        bool aFound = aSelectedResults.find(aResult) != aSelectedResults.end();
-        if (aSelectedResults.find(aResult) != aSelectedResults.end() &&
-            theOwnersToSelect.FindIndex(anOwner) <= 0)
+        if (isSameShape && anInfo.myLocalSelectedShapes.Contains(aShape)) {
+          // try to restore local selection on Shape result
+          // we can do this only if the shape was not changed
           theOwnersToSelect.Add(anOwner);
+          aFoundLocalShape = true;
+          break;
+        }
+      }
+    }
+    if (!aFoundLocalShape) {
+      // result owners are put in the list of selection only if local selected shapes were not
+      // found
+      if (aSelectedResults.find(aResult) != aSelectedResults.end()) {
+        for  ( Standard_Integer i = 1, n = aSelectedOwners.Extent(); i <= n; i++ ) {
+          Handle(StdSelect_BRepOwner) anOwner =
+            Handle(StdSelect_BRepOwner)::DownCast(aSelectedOwners(i));
+          if ( anOwner.IsNull() || !anOwner->HasShape() || theOwnersToSelect.FindIndex(anOwner))
+            continue;
+            // select whole result
+            theOwnersToSelect.Add(anOwner);
+        }
       }
     }
   }
@@ -1697,17 +1732,19 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
 
     std::set<AttributePtr> aSelectedAttributes;
     std::set<ResultPtr> aSelectedResults;
-    if (myCurrentSelection.find(aFeature) != myCurrentSelection.end()) {
-      std::pair<std::set<AttributePtr>, std::set<ResultPtr> > aPair =
-        myCurrentSelection.find(aFeature).value();
-      aSelectedAttributes = aPair.first;
-      aSelectedResults = aPair.second;
-    }
-
+    SelectionInfo anInfo;
+    if (myCurrentSelection.find(aFeature) != myCurrentSelection.end())
+      anInfo = myCurrentSelection.find(aFeature).value();
+
+    TopoDS_Shape aFirstShape;
+    ResultPtr aFirstResult = aFeature->firstResult();
+    if (aFirstResult.get() && aFirstResult->shape().get())
+      aFirstShape = aFirstResult->shape()->impl<TopoDS_Shape>();
+    anInfo.myFirstResultShape = aFirstShape;
     Handle(SelectMgr_EntityOwner) anOwner = aPrs->owner();
     if (aResult.get()) {
       getAttributesOrResults(anOwner, aFeature, aSketch, aResult,
-                             aSelectedAttributes, aSelectedResults);
+          anInfo.myAttributes, anInfo.myResults, anInfo.myLocalSelectedShapes);
     }
     else {
       std::list<ResultPtr> aResults = aFeature->results();
@@ -1715,10 +1752,10 @@ void PartSet_SketcherMgr::storeSelection(const bool theHighlightedOnly)
       for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
         ResultPtr aResult = *aIt;
         getAttributesOrResults(anOwner, aFeature, aSketch, aResult,
-                               aSelectedAttributes, aSelectedResults);
+          anInfo.myAttributes, anInfo.myResults, anInfo.myLocalSelectedShapes);
       }
     }
-    myCurrentSelection[aFeature] = std::make_pair(aSelectedAttributes, aSelectedResults);
+    myCurrentSelection[aFeature] = anInfo;
   }
   //qDebug(QString("  storeSelection: %1").arg(myCurrentSelection.size()).toStdString().c_str());
 }
@@ -1737,7 +1774,7 @@ void PartSet_SketcherMgr::restoreSelection()
   anOwnersToSelect.Clear();
   for (; aSIt != aSLast; aSIt++) {
     getSelectionOwners(aSIt.key(), myCurrentSketch, aWorkshop, myCurrentSelection,
-                        anOwnersToSelect);
+                       anOwnersToSelect);
   }
   aConnector->workshop()->selector()->setSelectedOwners(anOwnersToSelect, false);
 }
index 7e0ce1f273d2c5d05af786b3dee64f45a049aded..db177e582cbbf1eaf869f2f0aa5ffa798b62f956 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <GeomAPI_Pln.h>
 #include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 #include <QObject>
 #include <QList>
@@ -315,8 +317,15 @@ private:
                                              ModuleBase_IWorkshop* theWorkshop,
                                              bool& theCanCommitOperation);
 
-  typedef QMap<FeaturePtr, std::pair<std::set<AttributePtr>, std::set<ResultPtr> > >
-                                                                       FeatureToSelectionMap;
+  struct SelectionInfo
+  {
+    std::set<AttributePtr> myAttributes;
+    std::set<ResultPtr> myResults;
+    TopoDS_Shape myFirstResultShape;
+    TopTools_MapOfShape myLocalSelectedShapes;
+  };
+
+  typedef QMap<FeaturePtr, SelectionInfo> FeatureToSelectionMap;
 
   /// Applyes the current selection to the object in the workshop viewer
   /// It includes the selection in all modes of activation, even local context - vertexes, edges
@@ -334,7 +343,7 @@ private:
                                   const FeaturePtr& theSketch,
                                   ModuleBase_IWorkshop* theWorkshop,
                                   const FeatureToSelectionMap& theSelection,
-                                  SelectMgr_IndexedMapOfOwner& anOwnersToSelect);
+                                  SelectMgr_IndexedMapOfOwner& theOwnersToSelect);
 
   /// Returns true if the created feature is visible
   /// \param
index b9c92f940c6a08d417f4ea475cb1d873f8698882..23e759020ed5c723cf7f434759177d40bfdd3b8a 100644 (file)
@@ -117,13 +117,13 @@ void PartSet_SketcherReentrantMgr::operationStarted(ModuleBase_Operation* theOpe
   if (!isActiveMgr())
     return;
 
-  if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) {
-    ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
-                                                                myWorkshop->currentOperation());
-    CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
-    if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed
-      copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
-  }
+  //if (myPreviousFeature.get() && myRestartingMode == RM_LastFeatureUsed) {
+    //ModuleBase_OperationFeature* aCurrentOperation = dynamic_cast<ModuleBase_OperationFeature*>(
+    //                                                            myWorkshop->currentOperation());
+    //CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
+    //if (myPreviousFeature.get() && myPreviousFeature->data()->isValid()) // it is not removed
+      //copyReetntrantAttributes(myPreviousFeature, aCurrentOperation->feature(), aSketch);
+  //}
   resetFlags();
 }
 
@@ -152,17 +152,16 @@ bool PartSet_SketcherReentrantMgr::processMouseMoved(ModuleBase_IViewWindow* the
       ModuleBase_IPropertyPanel* aPanel = myWorkshop->currentOperation()->propertyPanel();
 
       FeaturePtr aCurrentFeature = aFOperation->feature();
-      bool isLineFeature = false, isArcFeature = false;
+      bool isLineFeature = false, isReentrantArcFeature = false;
       std::string anAttributeOnStart;
       if (aCurrentFeature->getKind() == SketchPlugin_Line::ID()) {
         anAttributeOnStart = SketchPlugin_Line::START_ID();
         isLineFeature = anActiveWidget->attributeID() == anAttributeOnStart;
       }
       else if (isTangentArc(aFOperation, module()->sketchMgr()->activeSketch())) {
-        anAttributeOnStart = SketchPlugin_MacroArc::TANGENT_POINT_ID();
-        isArcFeature = anActiveWidget->attributeID() == anAttributeOnStart;
+        isReentrantArcFeature = true;
       }
-      bool aCanBeActivatedByMove = isLineFeature || isArcFeature;
+      bool aCanBeActivatedByMove = isLineFeature || isReentrantArcFeature;
       if (aCanBeActivatedByMove) {
         /// before restarting of operation we need to clear selection, as it may take part in
         /// new feature creation, e.g. tangent arc. But it is not necessary as it was processed
@@ -263,7 +262,7 @@ bool PartSet_SketcherReentrantMgr::processMouseReleased(ModuleBase_IViewWindow*
             && !aSelectedPrs->object()->data()->isValid()) {
           // the selected object was removed diring restart, e.g. presentable macro feature
           // there are created objects to replace the object depending on created feature kind
-          aSelectedPrs = generatePreSelection();
+          aSelectedPrs = std::shared_ptr<ModuleBase_ViewerPrs>();
         }
         aMouseProcessor->setPreSelection(aSelectedPrs, theWindow, theEvent);
         //aPoint2DWdg->mouseReleased(theWindow, theEvent);
@@ -548,7 +547,7 @@ void PartSet_SketcherReentrantMgr::restartOperation()
 
       if (myInternalFeature.get())
         copyReetntrantAttributes(myInternalFeature, aFOperation->feature(),
-                                  module()->sketchMgr()->activeSketch());
+                                 module()->sketchMgr()->activeSketch());
 
       myNoMoreWidgetsAttribute = "";
       myIsFlagsBlocked = true;
@@ -690,16 +689,16 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th
     AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
     if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
       aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
-    //ModuleBase_Tools::flushUpdated(theNewFeature);
-    aChanged = true;*/
+    //ModuleBase_Tools::flushUpdated(theNewFeature);*/
+    //aChanged = true;
   }
   else if (aFeatureKind == SketchPlugin_MacroArc::ID()) {
     // set arc type
-    std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE();
+    /*std::string aTypeAttributeId = SketchPlugin_MacroArc::ARC_TYPE();
     AttributeStringPtr aSourceFeatureTypeAttr = theSourceFeature->data()->string(aTypeAttributeId);
     AttributeStringPtr aNewFeatureTypeAttr = theNewFeature->data()->string(aTypeAttributeId);
     if (aNewFeatureTypeAttr->value() != aTypeAttributeId) // do nothing if there is no changes
-      aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());
+      aNewFeatureTypeAttr->setValue(aSourceFeatureTypeAttr->value());*/
     //// if the arc is tangent, set coincidence to end point of the previous arc
     //std::string anArcType = aSourceFeatureTypeAttr->value();
     //if (anArcType == SketchPlugin_Arc::ARC_TYPE_TANGENT()) {
@@ -720,7 +719,7 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th
 
     //}
     //ModuleBase_Tools::flushUpdated(theNewFeature);
-    aChanged = true;
+    //aChanged = true;
   }
   else if (aFeatureKind == SketchPlugin_Trim::ID()) {
     /*std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
@@ -754,8 +753,7 @@ bool PartSet_SketcherReentrantMgr::copyReetntrantAttributes(const FeaturePtr& th
                       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
                       theNewFeature->data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
     aNPointPreviewAttr->setValue(aPointPreviewAttr->x(), aPointPreviewAttr->y());
-
-    aChanged = true;
+    //aChanged = true;
   }
   return aChanged;
 }
@@ -777,13 +775,6 @@ bool PartSet_SketcherReentrantMgr::isTangentArc(ModuleBase_Operation* theOperati
   return aTangentArc;
 }
 
-std::shared_ptr<ModuleBase_ViewerPrs> PartSet_SketcherReentrantMgr::generatePreSelection()
-{
-  std::shared_ptr<ModuleBase_ViewerPrs> aPrs;
-
-  return aPrs;
-}
-
 void PartSet_SketcherReentrantMgr::updateAcceptAllAction()
 {
   CompositeFeaturePtr aSketch = module()->sketchMgr()->activeSketch();
index 3fc5c22469eb820acbbff38bb63648e2a0060565..0b66869830daed9ef974bbcf55465dcc7afc30ba 100644 (file)
@@ -186,10 +186,6 @@ private:
   bool isTangentArc(ModuleBase_Operation* theOperation,
                     const std::shared_ptr<ModelAPI_CompositeFeature>& /*theSketch*/) const;
 
-  /// Creates selection instance by the current feature and created by restart objects
-  /// \returns viewer selection presentation
-  std::shared_ptr<ModuleBase_ViewerPrs> generatePreSelection();
-
   /// Accept All action is enabled if an internal edit is started.
   /// It updates the state of the button
   void updateAcceptAllAction();
index 0fecb7ed7855e535d11dfc007a7ffe30e5565f84..663bc658b568bdf7813b23abd027ff5f46aebdc6 100644 (file)
@@ -213,6 +213,7 @@ void PartSet_WidgetFeaturePointSelector::setPreSelection(
                                   ModuleBase_IViewWindow* theWnd,
                                   QMouseEvent* theEvent)
 {
-  if (fillFeature(thePreSelected, theWnd, theEvent))
-    mouseReleased(theWnd, theEvent);
+  // the method is empty because firstly by starging of the feature there is no selection of
+  // sub-segments in the viewer, secondly preselection of restart operation is processed by
+  // special reentrant message sent by the feature
 }
index 0d296dc097204e2aa7804e2f4b51c375af35107b..150b5909561c2e915fd3a752ed72217948aa7086 100644 (file)
@@ -591,8 +591,18 @@ void PartSet_WidgetPoint2D::mouseReleased(ModuleBase_IViewWindow* theWindow, QMo
       else {
         if (getPoint2d(aView, aShape, aX, aY))
           setPoint(aX, aY);
-        else
+        else {
+          if (aShape.ShapeType() == TopAbs_EDGE) {
+            // point is taken from mouse event and set in attribute. It should be done before set
+            // coinident constraint to the external line. If a point is created, it should be in
+            // the mouse clicked point
+            gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(),
+                                                               theWindow->v3dView());
+            PartSet_Tools::convertTo2D(aPoint, mySketch, aView, aX, aY);
+            setPoint(aX, aY);
+          }
           setValueState(Stored); // in case of edge selection, Apply state should also be updated
+        }
         bool anOrphanPoint = aShape.ShapeType() == TopAbs_VERTEX ||
                               isOrphanPoint(aSelectedFeature, mySketch, aX, aY);
         if (anExternal) {
index bdf32db5416f40a1a99098b50d5841fd250083f1..2b53b2ec9ea889db0ed389ed93cbdb0de7b09a04 100644 (file)
@@ -310,9 +310,6 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
     bool aRotate = Config_PropManager::boolean(SKETCH_TAB_NAME, "rotate_to_plane");
     if (aRotate) {
       myWorkshop->viewer()->setViewProjection(aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aTwist);
-      PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
-      if (aModule)
-        aModule->onViewTransformed();
     }
     QString aSizeOfViewStr = mySizeOfView->text();
     if (!aSizeOfViewStr.isEmpty()) {
@@ -328,6 +325,9 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
         }
       }
     }
+    PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
+    if (aModule)
+      aModule->onViewTransformed();
   }
   // 3. Clear text in the label
   myStackWidget->setCurrentIndex(1);
index 9c358dd7f2211a941863660d64204c6a9d6129f2..df8b645109bd5d87b6315a15134a99cb5bc9ac66 100644 (file)
@@ -107,3 +107,12 @@ bool PartSetPlugin_Part::isSub(ObjectPtr theObject) const
 void PartSetPlugin_Part::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
 {
 }
+
+void PartSetPlugin_Part::erase() {
+  ResultPartPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultPart>(firstResult());
+  if (aResult.get()) {
+    DocumentPtr aDoc = aResult->partDoc();
+    aDoc->eraseAllFeatures();
+  }
+  ModelAPI_Feature::erase();
+}
index 242848300acf36be66efb857f624a8c8d6fc9a62..d6300ae91a485278b3c9b5f87a5595ed4622aa6e 100644 (file)
@@ -70,6 +70,9 @@ class PartSetPlugin_Part : public ModelAPI_CompositeFeature
 
   /// Use plugin manager for features creation
   PartSetPlugin_Part();
+
+  /// Just removes all features of the part without touching the document data (to be able undo)
+  PARTSETPLUGIN_EXPORT virtual void erase();
 };
 
 #endif
index 75fe9e99392841d1f5cad66aefb88dcaacc5b1c8..d9aa0c5dadc288890e78120859c019649ed80c3c 100644 (file)
@@ -164,6 +164,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                Test1924.py
                Test1966.py
                Test1967.py
+               Test2095.py
                TestTrimArc01.py
                TestTrimArc02.py
                TestTrimArc03.py
index 2a9acd4b1e7e26af080be5eca8b9c84bafaa93ac..cb856fdc8bc03e6dde57bf87f887cf754ca6a2f6 100644 (file)
@@ -13,6 +13,7 @@
 #include "SketchPlugin_ConstraintEqual.h"
 #include "SketchPlugin_ConstraintCoincidence.h"
 #include "SketchPlugin_ConstraintLength.h"
+#include "SketchPlugin_ConstraintMiddle.h"
 #include "SketchPlugin_ConstraintTangent.h"
 #include "SketchPlugin_ConstraintRadius.h"
 #include "SketchPlugin_Tools.h"
@@ -84,6 +85,9 @@ void SketchPlugin_Fillet::execute()
   if (isUpdateFlushed)
     Events_Loop::loop()->setFlushed(anUpdateEvent, false);
 
+  // set flag here to avoid building Fillet presentation if "Redisplay" event appears
+  myFilletCreated = true;
+
   // Calculate Fillet parameters if does not yet
   if (!myBaseFeatures[0] || !myBaseFeatures[1])
     calculateFilletParameters();
@@ -178,8 +182,6 @@ void SketchPlugin_Fillet::execute()
   if(isUpdateFlushed) {
     Events_Loop::loop()->setFlushed(anUpdateEvent, true);
   }
-
-  myFilletCreated = true;
 }
 
 AISObjectPtr SketchPlugin_Fillet::getAISObject(AISObjectPtr thePrevious)
@@ -521,7 +523,8 @@ std::set<FeaturePtr> findFeaturesToRemove(const FeaturePtr theFeature,
       continue;
     }
     if(aFeature->getKind() == SketchPlugin_ConstraintLength::ID()
-        || aFeature->getKind() == SketchPlugin_ConstraintEqual::ID()) {
+        || aFeature->getKind() == SketchPlugin_ConstraintEqual::ID()
+        || aFeature->getKind() == SketchPlugin_ConstraintMiddle::ID()) {
       aFeaturesToBeRemoved.insert(aFeature);
     } else {
       std::list<AttributePtr> anAttrs =
index 8b3f611273f24549d96af5d1882e03d3e0a7f6a5..2a034e0f5f72c8bd6db7f6e6ab68263df23e8c41 100644 (file)
@@ -126,7 +126,7 @@ void SketchPlugin_Projection::computeProjection(const std::string& theID)
 
   ResultConstructionPtr aResult =
       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(lastResult());
-  if (aResult && aResult->shape()) {
+  if (aResult && aResult->shape() && theID == EXTERNAL_FEATURE_ID()) {
     aResult->setShape(std::shared_ptr<GeomAPI_Edge>());
     aProjection->selection(EXTERNAL_ID())->setValue(lastResult(), lastResult()->shape());
   }
index 4e60668376998ee0c60c7a55317efdd15f1b99d3..f2d2c4da8bc856f4ef3492a3152cf05b32eece81 100644 (file)
@@ -189,8 +189,10 @@ void SketchPlugin_Trim::execute()
 #endif
 
   SketchPlugin_Sketch* aSketch = sketch();
-  if (!aSketch)
+  if (!aSketch) {
+    setError("Error: Sketch object is empty.");
     return;
+  }
 
   // Check the base objects are initialized.
   AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
@@ -200,8 +202,10 @@ void SketchPlugin_Trim::execute()
     return;
   }
   ObjectPtr aBaseObject = aBaseObjectAttr->value();
-  if (!aBaseObject.get())
+  if (!aBaseObject.get()) {
+    setError("Error: Base object is not initialized.");
     return;
+  }
   FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
 
   /// Remove reference of this feature to feature used in preview, it is not necessary anymore
@@ -481,7 +485,6 @@ std::string SketchPlugin_Trim::processEvent(const std::shared_ptr<Events_Message
 #ifdef DEBUG_TRIM_METHODS
   std::cout << "SketchPlugin_Trim::processEvent:" << data()->name() << std::endl;
 #endif
-
   std::string aFilledAttributeName;
 
   std::shared_ptr<ModelAPI_EventReentrantMessage> aMessage =
@@ -491,34 +494,39 @@ std::string SketchPlugin_Trim::processEvent(const std::shared_ptr<Events_Message
     std::shared_ptr<GeomAPI_Pnt2d> aPoint = aMessage->clickedPoint();
 
     if (anObject.get() && aPoint.get()) {
-      std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
-                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-                            data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
-      std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
-                            std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-                            data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
-      aRefSelectedAttr->setValue(anObject);
-      aRefPreviewAttr->setValue(anObject);
-
-      std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
-                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-                            data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
-      std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
-                            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-                            data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
-      aPointSelectedAttr->setValue(aPoint);
-      aPointPreviewAttr->setValue(aPoint);
-
-      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
-
-      GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
-#ifdef DEBUG_TRIM_METHODS
-      if (!aSelectedShape.get())
-        std::cout << "Set empty selected object" << std::endl;
-      else
-        std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
-#endif
-      aFilledAttributeName = SketchPlugin_Trim::SELECTED_OBJECT();
+      if (myCashedShapes.find(anObject) == myCashedShapes.end())
+        fillObjectShapes(anObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
+      const std::set<GeomShapePtr>& aShapes = myCashedShapes[anObject];
+      if (aShapes.size() > 1) {
+        std::shared_ptr<ModelAPI_AttributeReference> aRefSelectedAttr =
+                              std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                              data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
+        std::shared_ptr<ModelAPI_AttributeReference> aRefPreviewAttr =
+                              std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                              data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
+        aRefSelectedAttr->setValue(anObject);
+        aRefPreviewAttr->setValue(anObject);
+
+        std::shared_ptr<GeomDataAPI_Point2D> aPointSelectedAttr =
+                              std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                              data()->attribute(SketchPlugin_Trim::SELECTED_POINT()));
+        std::shared_ptr<GeomDataAPI_Point2D> aPointPreviewAttr =
+                              std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                              data()->attribute(SketchPlugin_Trim::PREVIEW_POINT()));
+        aPointSelectedAttr->setValue(aPoint);
+        aPointPreviewAttr->setValue(aPoint);
+
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+
+        GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
+  #ifdef DEBUG_TRIM_METHODS
+        if (!aSelectedShape.get())
+          std::cout << "Set empty selected object" << std::endl;
+        else
+          std::cout << "Set shape with ShapeType: " << aSelectedShape->shapeTypeStr() << std::endl;
+  #endif
+        aFilledAttributeName = SketchPlugin_Trim::SELECTED_OBJECT();
+      }
     }
   }
   return aFilledAttributeName;
@@ -1037,7 +1045,6 @@ FeaturePtr SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theS
                                (aBaseFeature->attribute(aModifiedAttribute)));
 
     // equal Radius constraint for arcs
-    anNewFeature->execute(); // we need the created arc result to set equal constraint
     createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
                                getFeatureResult(aBaseFeature),
                                getFeatureResult(anNewFeature));
@@ -1271,7 +1278,7 @@ FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
     bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
     aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed);
   }
-  //aFeature->execute(); // to obtain result
+  aFeature->execute(); // to obtain result (need to calculate arc parameters before sending Update)
   aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
 
   #ifdef DEBUG_TRIM
index 236a104d1f5f94bf2aba41e777dddea9c5be425d..a441c6f658589c3413197c3e3db50146d900c08f 100755 (executable)
@@ -41,6 +41,7 @@
 #include <ModelGeomAlgo_Point2D.h>
 #include <ModelGeomAlgo_Shape.h>
 
+#include <GeomAlgoAPI_EdgeBuilder.h>
 #include <GeomAlgoAPI_ShapeTools.h>
 
 #include <GeomAPI_Circ.h>
@@ -1325,6 +1326,37 @@ bool SketchPlugin_ArcEndPointValidator::isValid(
   return true;
 }
 
+static GeomShapePtr toInfiniteEdge(const GeomShapePtr theShape)
+{
+  if(!theShape.get()) {
+    return theShape;
+  }
+
+  if(!theShape->isEdge()) {
+    return theShape;
+  }
+
+  std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theShape));
+
+  if(!anEdge.get()) {
+    return theShape;
+  }
+
+  if(anEdge->isLine()) {
+    std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
+    GeomShapePtr aShape = GeomAlgoAPI_EdgeBuilder::line(aLine);
+    return aShape;
+  }
+
+  if(anEdge->isCircle() || anEdge->isArc()) {
+    std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
+    GeomShapePtr aShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCircle);
+    return aShape;
+  }
+
+  return theShape;
+}
+
 bool SketchPlugin_ArcEndPointIntersectionValidator::isValid(
     const AttributePtr& theAttribute,
     const std::list<std::string>& theArguments,
@@ -1338,7 +1370,7 @@ bool SketchPlugin_ArcEndPointIntersectionValidator::isValid(
     return true;
   }
 
-  GeomShapePtr anArcShape = anArcFeature->getArcShape(false);
+  GeomShapePtr anArcShape = toInfiniteEdge(anArcFeature->getArcShape(false));
 
   if(!anArcShape.get() || anArcShape->isNull()) {
     return true;
@@ -1352,10 +1384,9 @@ bool SketchPlugin_ArcEndPointIntersectionValidator::isValid(
 
   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
   if(aResult.get()) {
-    GeomShapePtr aShape = aResult->shape();
+    GeomShapePtr aShape = toInfiniteEdge(aResult->shape());
     if(aShape.get() && !aShape->isNull()) {
-      GeomShapePtr anIntersection = anArcShape->intersect(aShape);
-      if(anIntersection.get() && !anIntersection->isNull()) {
+      if(anArcShape->isIntersect(aShape)) {
         return true;
       }
     }
@@ -1368,10 +1399,9 @@ bool SketchPlugin_ArcEndPointIntersectionValidator::isValid(
         anIt != aResults.cend();
         ++anIt)
     {
-      GeomShapePtr aShape = (*anIt)->shape();
+      GeomShapePtr aShape = toInfiniteEdge((*anIt)->shape());
       if(aShape.get() && !aShape->isNull()) {
-        GeomShapePtr anIntersection = anArcShape->intersect(aShape);
-        if(anIntersection.get() && !anIntersection->isNull()) {
+        if(anArcShape->isIntersect(aShape)) {
           return true;
         }
       }
diff --git a/src/SketchPlugin/Test/Test2095.py b/src/SketchPlugin/Test/Test2095.py
new file mode 100644 (file)
index 0000000..bed556c
--- /dev/null
@@ -0,0 +1,29 @@
+from SketchAPI import *
+from salome.shaper import model
+
+lineStart = [26, 53]
+lineEnd = [71, 30]
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(lineStart[0], lineStart[1], lineEnd[0], lineEnd[1])
+SketchLine_2 = Sketch_1.addLine(model.selection("EDGE", "OX"))
+SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_2.result(), [SketchLine_1.result()])
+[SketchLine_3] = SketchConstraintMirror_1.mirrored()
+
+SketchLine_4 = Sketch_1.addLine(lineEnd[0], lineEnd[1], lineEnd[0], -lineEnd[1])
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_3).endPoint(), SketchLine_4.endPoint())
+
+Sketch_1.setFillet(SketchLine_1.endPoint())
+model.do()
+
+assert(SketchLine_1.startPoint().x() ==  SketchAPI_Line(SketchLine_3).startPoint().x())
+assert(SketchLine_1.startPoint().y() == -SketchAPI_Line(SketchLine_3).startPoint().y())
+assert(SketchLine_1.endPoint().x() ==  SketchAPI_Line(SketchLine_3).endPoint().x())
+assert(SketchLine_1.endPoint().y() == -SketchAPI_Line(SketchLine_3).endPoint().y())
+assert(SketchLine_1.endPoint().x() != lineEnd[0])
+assert(SketchLine_1.endPoint().y() != lineEnd[1])
+
+model.end()
index 96235587d0bd0f2b4bd96d4c01f8bcba4131ce79..b68c6aae5197049fdbc626f9a3e7ee1ab37b7a75 100644 (file)
@@ -244,20 +244,19 @@ bool PlaneGCSSolver_Storage::update(AttributePtr theAttribute, bool theForce)
   }
 
   EntityWrapperPtr aRelated = entity(anAttribute);
+  FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner());
   if (!aRelated) { // Attribute does not exist, create it.
     // First of all check if the parent feature exists. If not, add it.
-    FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner());
     if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end())
       return update(aFeature, theForce); // theAttribute has been processed while adding feature
-
-////    PlaneGCSSolver_AttributeBuilder aBuilder(this);
-////    aRelated = createAttribute(anAttribute, &aBuilder);
     return aRelated.get() != 0;
   }
 
   bool isUpdated = updateValues(anAttribute, aRelated);
-  if (isUpdated)
+  if (isUpdated) {
     setNeedToResolve(true);
+    notify(aFeature);
+  }
   return isUpdated;
 }
 
index 6b1d358cb6725c8e09b4b2e4e4b3d9584415fe8a..51cf2f9854d2b218cba0bc3cfe9c37c3d3191777 100644 (file)
@@ -193,7 +193,13 @@ bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence(
     if (hasExternal()) {
       if (myExternalAndConnected.find(theOtherEntity) == myExternalAndConnected.end())
         myExternalAndConnected[theOtherEntity] = std::set<EntityWrapperPtr>();
-      return false;
+      // check whether all external entities are edges
+      bool isNewCoinc = true;
+      std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::iterator
+          anIt = myExternalAndConnected.begin();
+      for (; anIt != myExternalAndConnected.end() && isNewCoinc; ++anIt)
+        isNewCoinc = (anIt->first->type() != ENTITY_POINT);
+      return isNewCoinc;
     } else {
       myExternalAndConnected[theOtherEntity] = myExternalAndConnected[EntityWrapperPtr()];
       myExternalAndConnected.erase(EntityWrapperPtr());
index 05840ba95c936f7a36845a5761526b585d8523a2..0664550a29441c7802a3981dc0b998dc190369b6 100644 (file)
@@ -141,11 +141,14 @@ bool SketchSolver_Group::moveFeature(FeaturePtr theFeature)
 //  Function: resolveConstraints
 //  Class:    SketchSolver_Group
 //  Purpose:  solve the set of constraints for the current group
+#include <iostream>
 // ============================================================================
 bool SketchSolver_Group::resolveConstraints()
 {
+  static const int MAX_STACK_SIZE = 5;
   // check the "Multi" constraints do not drop sketch into infinite loop
-  if (myMultiConstraintUpdateStack > 1) {
+  if (myMultiConstraintUpdateStack > MAX_STACK_SIZE) {
+    myMultiConstraintUpdateStack = 0;
     myPrevResult = PlaneGCSSolver_Solver::STATUS_FAILED;
     // generate error message due to loop update of the sketch
     getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
@@ -162,7 +165,7 @@ bool SketchSolver_Group::resolveConstraints()
 
     PlaneGCSSolver_Solver::SolveStatus aResult = PlaneGCSSolver_Solver::STATUS_OK;
     try {
-      if (!isGroupEmpty && myMultiConstraintUpdateStack <= 1)
+      if (!isGroupEmpty)
         aResult = mySketchSolver->solve();
     } catch (...) {
       getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())
index ec2f8d77bbb5be2f5047486ca7579ed016315d14..849c95b0c9eb6ac72de7010c53c2ec4abbb99b1a 100644 (file)
@@ -151,6 +151,7 @@ void SketchSolver_Manager::processEvent(
 
   // resolve constraints if needed
   bool needToUpdate = needToResolve && resolveConstraints();
+  releaseFeaturesIfEventsBlocked();
 
   // Features may be updated => now send events, but for all changed at once
   if (isUpdateFlushed)
@@ -238,11 +239,17 @@ bool SketchSolver_Manager::resolveConstraints()
   for (; aGroupIter != myGroups.end(); ++aGroupIter) {
     if ((*aGroupIter)->resolveConstraints())
       needToUpdate = true;
-    (*aGroupIter)->blockEvents(false);
   }
   return needToUpdate;
 }
 
+void SketchSolver_Manager::releaseFeaturesIfEventsBlocked() const
+{
+  std::list<SketchGroupPtr>::const_iterator aGroupIter = myGroups.begin();
+  for (; aGroupIter != myGroups.end(); ++aGroupIter)
+    (*aGroupIter)->blockEvents(false);
+}
+
 bool SketchSolver_Manager::stopSendUpdate() const
 {
 static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
index d69cccbfd4a8e5c8a1926aded8091b0a3fbb75a6..fc1b4222956f80db2f05942fc36b34cc9afa9530 100644 (file)
@@ -77,8 +77,11 @@ private:
   /// \brief Allow to send the Update event
   void allowSendUpdate() const;
 
+  /// \brief Allow send events about changing features in groups
+  void releaseFeaturesIfEventsBlocked() const;
+
 private:
-  std::list<SketchGroupPtr>   myGroups;  ///< Groups of constraints
+  std::list<SketchGroupPtr> myGroups; ///< Groups of constraints
   /// true if computation is performed and all "updates" are generated by this algo
   /// and needs no recomputation
   bool myIsComputed;
index 2eef35a764ad3cc07869240ddb8a9d30aadfbfa4..88fb28eeb6c6eff05766fad8028f74dd1611e778 100644 (file)
@@ -644,7 +644,11 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &
           } else {
             // this is an object under sub document root
             std::string aType = myXMLReader->subType();
-            ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders);
+            int aCount = theRow - aNbSubFolders;
+            // To check number of objects before using
+            if (aSubDoc->size(aType) <= aCount)
+              return QModelIndex();
+            ObjectPtr aObj = aSubDoc->object(aType, aCount);
             aIndex = objectIndex(aObj);
           }
         } else {
index 3c52a0085ebd372061491984e1278f06b05195ab..348dc27292fe9eeca47792ebff0d68f7ae1bb378 100644 (file)
@@ -6,7 +6,7 @@ model.begin()
 partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
-model.addParameter(Part_1_doc, "R", "40")
+Parameter_R = model.addParameter(Part_1_doc, "R", "40")
 model.addParameter(Part_1_doc, "h", "3")
 model.addParameter(Part_1_doc, "R2", "33.5")
 model.addParameter(Part_1_doc, "h2", "4")
@@ -107,6 +107,12 @@ SketchLine_13.setName("SketchLine_16")
 SketchLine_13.result().setName("SketchLine_16")
 model.do()
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_8/Face-SketchLine_7r-SketchLine_8r-SketchLine_10f-SketchLine_11f"), model.selection("FACE", "Sketch_8/Face-SketchLine_16f-SketchLine_17f-SketchLine_18r-SketchLine_19r"), model.selection("FACE", "Sketch_8/Face-SketchLine_12f-SketchLine_13f-SketchLine_14r-SketchLine_15r")], model.selection(), model.selection("FACE", "ExtrusionCut_2_1/Modfied_23"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_2_1")])
+
+# Test reexecution after parameter change
+Parameter_R.setValue(50)
+model.do()
+model.testResultsVolumes(ExtrusionCut_3, [35832.402050074902945198118686676])
+Parameter_R.setValue(40)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
index c353823ec958be8ab34c914fa71192f0e4da501e..d0a766288f27fad3f79a6f131e979286afdbbbf2 100644 (file)
@@ -8,7 +8,7 @@ model.addParameter(Part_1_doc, "BHD", "8", "Base Hole Diameter")
 model.addParameter(Part_1_doc, "BHPD", "14", "Base Hole Plate Diameter")
 model.addParameter(Part_1_doc, "BHPS", "2", "Base Hole Plate Thickness")
 model.addParameter(Part_1_doc, "BHPFR", "BHPS/4*3", "Base Hole Plate Fillet Radius")
-model.addParameter(Part_1_doc, "BPS", "6", "Base Plate Thickness")
+Parameter_BPS = model.addParameter(Part_1_doc, "BPS", "6", "Base Plate Thickness")
 model.addParameter(Part_1_doc, "Draft", "100", "Bracket Draft")
 model.addParameter(Part_1_doc, "TDI", "14", "Tube Internal Diameter")
 model.addParameter(Part_1_doc, "TDE", "TDI+8", "Tube External Diameter")
@@ -809,6 +809,12 @@ model.do()
 RevolutionFuse_3 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "Sketch_9/Edge-SketchLine_58"), 360, 0, [model.selection("SOLID", "RevolutionFuse_2_1")])
 RevolutionFuse_4 = model.addRevolutionFuse(Part_1_doc, [model.selection("COMPOUND", "Sketch_10")], model.selection("EDGE", "Sketch_10/Edge-SketchLine_66"), 360, 0, [model.selection("SOLID", "RevolutionFuse_3_1")])
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_6/Face-SketchCircle_11_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_9_2f"), model.selection("WIRE", "Sketch_6/Wire-SketchCircle_10_2f"), model.selection("FACE", "Sketch_6/Face-SketchCircle_12_2f")], model.selection("EDGE", "PartSet/OZ"), "BPS+5", 5, [model.selection("SOLID", "RevolutionFuse_4_1")])
+
+# Test reexecution after parameter change
+Parameter_BPS.setValue(3)
+model.do()
+model.testResultsVolumes(ExtrusionCut_3, [154096.039414040715200826525688171])
+Parameter_BPS.setValue(6)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
index 6b0cddb12d840c81025dae88ad260de5979be144..6028f640dc4e765bdf60ed7589759ad4d84db7f4 100644 (file)
@@ -4,6 +4,7 @@ model.begin()
 partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
+Parameter_H = model.addParameter(Part_1_doc, "H", "12")
 Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
 SketchLine_1 = Sketch_1.addLine(0, 0, 0, -14)
 SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
@@ -47,7 +48,7 @@ SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_5.result())
 SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
 SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_7.result())
 SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result())
-SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_7.result(), 12)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_7.result(), "H")
 SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_1.result(), 14)
 SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_1.endPoint(), SketchLine_3.result(), 1)
 SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_2.endPoint(), SketchLine_1.result(), 1)
@@ -564,6 +565,12 @@ model.do()
 Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_8f-SketchLine_9f-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_14f")], model.selection("EDGE", "PartSet/OX"), 360, 0)
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchArc_1_2r-SketchLine_382f-SketchLine_383f-SketchLine_20f-SketchArc_2_2r-SketchLine_21f-SketchLine_22f-SketchLine_23f-SketchLine_24f-SketchLine_25f-SketchLine_26f-SketchLine_27f-SketchLine_28f-SketchLine_29f-SketchLine_30f-SketchLine_31f-SketchLine_32f-SketchLine_33f-SketchLine_34f-SketchLine_35f-SketchLine_36f-SketchLine_37f-SketchLine_38f-SketchLine_39f-SketchLine_40f-SketchLine_41f-SketchLine_42f-SketchLine_43f-SketchLine_44f-SketchLine_45f-SketchLine_46f-SketchLine_47f-SketchLine_48f-SketchLine_49f-SketchLine_50f-SketchLine_51f-SketchLine_52f-SketchLine_53f-SketchLine_54f-SketchLine_55f-SketchLine_56f-SketchLine_57f-SketchLine_58f-SketchLine_59f-SketchLine_60f-SketchLine_61f-SketchLine_62f-SketchLine_63f-SketchLine_64f-SketchLine_65f-SketchLine_66f-SketchLine_67f-SketchLine_68f-SketchLine_69f-SketchLine_70f-SketchLine_71f-SketchLine_72f-SketchLine_73f-SketchLine_74f-SketchLine_75f-SketchLine_76f-SketchLine_77f-SketchLine_78f-SketchLine_79f-SketchLine_80f-SketchLine_81f-SketchLine_82f-SketchLine_83f-SketchLine_84f-SketchLine_85f-SketchLine_86f-SketchLine_87f-SketchLine_88f-SketchLine_89f-SketchLine_90f-SketchLine_91f-SketchLine_92f-SketchLine_93f-SketchLine_94f-SketchLine_95f-SketchLine_96f-SketchLine_97f-SketchLine_98f-SketchLine_99f-SketchLine_100f-SketchLine_101f-SketchLine_102f-SketchLine_103f-SketchLine_104f-SketchLine_105f-SketchLine_106f-SketchLine_107f-SketchLine_108f-SketchLine_109f-SketchLine_110f-SketchLine_111f-SketchLine_112f-SketchLine_113f-SketchLine_114f-SketchLine_115f-SketchLine_116f-SketchLine_117f-SketchLine_118f-SketchLine_119f-SketchLine_120f-SketchLine_121f-SketchLine_122f-SketchLine_123f-SketchLine_124f-SketchLine_125f-SketchLine_126f-SketchLine_127f-SketchLine_128f-SketchLine_129f-SketchLine_130f-SketchLine_131f-SketchLine_132f-SketchLine_133f-SketchLine_134f-SketchLine_135f-SketchLine_136f-SketchLine_137f-SketchLine_138f-SketchLine_139f-SketchLine_140f-SketchLine_141f-SketchLine_142f-SketchLine_143f-SketchLine_144f-SketchLine_145f-SketchLine_146f-SketchLine_147f-SketchLine_148f-SketchLine_149f-SketchLine_150f-SketchLine_151f-SketchLine_152f-SketchLine_153f-SketchLine_154f-SketchLine_155f-SketchLine_156f-SketchLine_157f-SketchLine_158f-SketchLine_159f-SketchLine_160f-SketchLine_161f-SketchLine_162f-SketchLine_163f-SketchLine_164f-SketchLine_165f-SketchLine_166f-SketchLine_167f-SketchLine_168f-SketchLine_169f-SketchLine_170f-SketchLine_171f-SketchLine_172f-SketchLine_173f-SketchLine_174f-SketchLine_175f-SketchLine_176f-SketchLine_177f-SketchLine_178f-SketchLine_179f-SketchLine_180f-SketchLine_181f-SketchLine_182f-SketchLine_183f-SketchLine_184f-SketchLine_185f-SketchLine_186f-SketchLine_187f-SketchLine_188f-SketchLine_189f-SketchLine_190f-SketchLine_191f-SketchLine_192f-SketchLine_193f-SketchLine_194f-SketchLine_195f-SketchLine_196f-SketchLine_197f-SketchLine_198f-SketchLine_199f-SketchArc_3_2r-SketchArc_4_2r-SketchArc_5_2r-SketchArc_6_2r-SketchArc_7_2r-SketchArc_8_2r-SketchArc_9_2r-SketchArc_10_2r-SketchArc_11_2r-SketchArc_12_2r-SketchArc_13_2r-SketchArc_14_2r-SketchArc_15_2r-SketchArc_16_2r-SketchArc_17_2r-SketchArc_18_2r-SketchArc_19_2r-SketchArc_20_2r-SketchArc_21_2r-SketchArc_22_2r-SketchArc_23_2r-SketchArc_24_2r-SketchArc_25_2r-SketchArc_26_2r-SketchArc_27_2r-SketchArc_28_2r-SketchArc_29_2r-SketchArc_30_2r-SketchArc_31_2r-SketchArc_32_2r-SketchArc_33_2r-SketchArc_34_2r-SketchArc_35_2r-SketchArc_36_2r-SketchArc_37_2r-SketchArc_38_2r-SketchArc_39_2r-SketchArc_40_2r-SketchArc_41_2r-SketchArc_42_2r-SketchArc_43_2r-SketchArc_44_2r-SketchArc_45_2r-SketchArc_46_2r-SketchArc_47_2r-SketchArc_48_2r-SketchArc_49_2r-SketchArc_50_2r-SketchArc_51_2r-SketchArc_52_2r-SketchArc_53_2r-SketchArc_54_2r-SketchArc_55_2r-SketchArc_56_2r-SketchArc_57_2r-SketchArc_58_2r-SketchArc_59_2r-SketchArc_60_2r-SketchArc_61_2r-SketchArc_62_2r-SketchArc_63_2r-SketchArc_64_2r-SketchArc_65_2r-SketchArc_66_2r-SketchArc_67_2r-SketchArc_68_2r-SketchArc_69_2r-SketchArc_70_2r-SketchArc_71_2r-SketchArc_72_2r-SketchArc_73_2r-SketchArc_74_2r-SketchArc_75_2r-SketchArc_76_2r-SketchArc_77_2r-SketchArc_78_2r-SketchArc_79_2r-SketchArc_80_2r-SketchArc_81_2r-SketchArc_82_2r-SketchArc_83_2r-SketchArc_84_2r-SketchArc_85_2r-SketchArc_86_2r-SketchArc_87_2r-SketchArc_88_2r-SketchArc_89_2r-SketchArc_90_2r-SketchArc_91_2r-SketchArc_92_2r-SketchArc_93_2r-SketchArc_94_2r-SketchArc_95_2r-SketchArc_96_2r-SketchArc_97_2r-SketchArc_98_2r-SketchArc_99_2r-SketchArc_100_2r-SketchArc_101_2r-SketchArc_102_2r-SketchArc_103_2r-SketchArc_104_2r-SketchArc_105_2r-SketchArc_106_2r-SketchArc_107_2r-SketchArc_108_2r-SketchArc_109_2r-SketchArc_110_2r-SketchArc_111_2r-SketchArc_112_2r-SketchArc_113_2r-SketchArc_114_2r-SketchArc_115_2r-SketchArc_116_2r-SketchArc_117_2r-SketchArc_118_2r-SketchArc_119_2r-SketchArc_120_2r-SketchArc_121_2r-SketchArc_122_2r-SketchArc_123_2r-SketchArc_124_2r-SketchArc_125_2r-SketchArc_126_2r-SketchArc_127_2r-SketchArc_128_2r-SketchArc_129_2r-SketchArc_130_2r-SketchArc_131_2r-SketchArc_132_2r-SketchArc_133_2r-SketchArc_134_2r-SketchArc_135_2r-SketchArc_136_2r-SketchArc_137_2r-SketchArc_138_2r-SketchArc_139_2r-SketchArc_140_2r-SketchArc_141_2r-SketchArc_142_2r-SketchArc_143_2r-SketchArc_144_2r-SketchArc_145_2r-SketchArc_146_2r-SketchArc_147_2r-SketchArc_148_2r-SketchArc_149_2r-SketchArc_150_2r-SketchArc_151_2r-SketchArc_152_2r-SketchArc_153_2r-SketchArc_154_2r-SketchArc_155_2r-SketchArc_156_2r-SketchArc_157_2r-SketchArc_158_2r-SketchArc_159_2r-SketchArc_160_2r-SketchArc_161_2r-SketchArc_162_2r-SketchArc_163_2r-SketchArc_164_2r-SketchArc_165_2r-SketchArc_166_2r-SketchArc_167_2r-SketchArc_168_2r-SketchArc_169_2r-SketchArc_170_2r-SketchArc_171_2r-SketchArc_172_2r-SketchArc_173_2r-SketchArc_174_2r-SketchArc_175_2r-SketchArc_176_2r-SketchArc_177_2r-SketchArc_178_2r-SketchArc_179_2r-SketchArc_180_2r-SketchLine_200f-SketchLine_201f-SketchLine_202f-SketchLine_203f-SketchLine_204f-SketchLine_205f-SketchLine_206f-SketchLine_207f-SketchLine_208f-SketchLine_209f-SketchLine_210f-SketchLine_211f-SketchLine_212f-SketchLine_213f-SketchLine_214f-SketchLine_215f-SketchLine_216f-SketchLine_217f-SketchLine_218f-SketchLine_219f-SketchLine_220f-SketchLine_221f-SketchLine_222f-SketchLine_223f-SketchLine_224f-SketchLine_225f-SketchLine_226f-SketchLine_227f-SketchLine_228f-SketchLine_229f-SketchLine_230f-SketchLine_231f-SketchLine_232f-SketchLine_233f-SketchLine_234f-SketchLine_235f-SketchLine_236f-SketchLine_237f-SketchLine_238f-SketchLine_239f-SketchLine_240f-SketchLine_241f-SketchLine_242f-SketchLine_243f-SketchLine_244f-SketchLine_245f-SketchLine_246f-SketchLine_247f-SketchLine_248f-SketchLine_249f-SketchLine_250f-SketchLine_251f-SketchLine_252f-SketchLine_253f-SketchLine_254f-SketchLine_255f-SketchLine_256f-SketchLine_257f-SketchLine_258f-SketchLine_259f-SketchLine_260f-SketchLine_261f-SketchLine_262f-SketchLine_263f-SketchLine_264f-SketchLine_265f-SketchLine_266f-SketchLine_267f-SketchLine_268f-SketchLine_269f-SketchLine_270f-SketchLine_271f-SketchLine_272f-SketchLine_273f-SketchLine_274f-SketchLine_275f-SketchLine_276f-SketchLine_277f-SketchLine_278f-SketchLine_279f-SketchLine_280f-SketchLine_281f-SketchLine_282f-SketchLine_283f-SketchLine_284f-SketchLine_285f-SketchLine_286f-SketchLine_287f-SketchLine_288f-SketchLine_289f-SketchLine_290f-SketchLine_291f-SketchLine_292f-SketchLine_293f-SketchLine_294f-SketchLine_295f-SketchLine_296f-SketchLine_297f-SketchLine_298f-SketchLine_299f-SketchLine_300f-SketchLine_301f-SketchLine_302f-SketchLine_303f-SketchLine_304f-SketchLine_305f-SketchLine_306f-SketchLine_307f-SketchLine_308f-SketchLine_309f-SketchLine_310f-SketchLine_311f-SketchLine_312f-SketchLine_313f-SketchLine_314f-SketchLine_315f-SketchLine_316f-SketchLine_317f-SketchLine_318f-SketchLine_319f-SketchLine_320f-SketchLine_321f-SketchLine_322f-SketchLine_323f-SketchLine_324f-SketchLine_325f-SketchLine_326f-SketchLine_327f-SketchLine_328f-SketchLine_329f-SketchLine_330f-SketchLine_331f-SketchLine_332f-SketchLine_333f-SketchLine_334f-SketchLine_335f-SketchLine_336f-SketchLine_337f-SketchLine_338f-SketchLine_339f-SketchLine_340f-SketchLine_341f-SketchLine_342f-SketchLine_343f-SketchLine_344f-SketchLine_345f-SketchLine_346f-SketchLine_347f-SketchLine_348f-SketchLine_349f-SketchLine_350f-SketchLine_351f-SketchLine_352f-SketchLine_353f-SketchLine_354f-SketchLine_355f-SketchLine_356f-SketchLine_357f-SketchLine_358f-SketchLine_359f-SketchLine_360f-SketchLine_361f-SketchLine_362f-SketchLine_363f-SketchLine_364f-SketchLine_365f-SketchLine_366f-SketchLine_367f-SketchLine_368f-SketchLine_369f-SketchLine_370f-SketchLine_371f-SketchLine_372f-SketchLine_373f-SketchLine_374f-SketchLine_375f-SketchLine_376f-SketchLine_377f-SketchCircle_3_2f")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_7"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
 ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_4_2f")], model.selection(), 30, 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+
+# Test reexecution after parameter change
+Parameter_H.setValue(14)
+model.do()
+model.testResultsVolumes(ExtrusionCut_2, [10205.255531030932615976780653000])
+Parameter_H.setValue(12)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
index 65afa9b008a1e7354b69624e1aaa22f4b83b417c..8008bfb8e90aa825f835abbb629a3f0eeb0123d3 100644 (file)
@@ -6,6 +6,7 @@ model.begin()
 partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
+Parameter_R = model.addParameter(Part_1_doc, "R", "3")
 model.addParameter(Part_1_doc, "DBody", "65")
 Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 89, False)
 Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
@@ -54,7 +55,7 @@ SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.startPoint()
 SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_4.endPoint())
 SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_6.result())
 SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_4.startPoint(), SketchLine_5.result())
-SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 3)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], "R")
 SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchAPI_Line(SketchLine_7).startPoint())
 SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_2.startPoint(), SketchLine_3.result(), 20)
 SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_3.endPoint(), SketchLine_2.result(), 20)
@@ -763,6 +764,12 @@ model.do()
 RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_9")], model.selection("EDGE", "PartSet/OZ"), 0, 360, [model.selection("SOLID", "ExtrusionFuse_3_1")])
 ExtrusionCut_3 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_4_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_3_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_5_2f")], model.selection(), 30, -15, [model.selection("SOLID", "RevolutionCut_1_1")])
 ExtrusionCut_4 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_11/Wire-SketchCircle_2_2f"), model.selection("FACE", "Sketch_11/Face-SketchCircle_6_2f"), model.selection("WIRE", "Sketch_11/Wire-SketchCircle_7_2f")], model.selection(), 30, 2, [model.selection("SOLID", "ExtrusionCut_3_1")])
+
+# Test reexecution after parameter change
+Parameter_R.setValue(5)
+model.do()
+model.testResultsVolumes(ExtrusionCut_4, [502615.944655187719035893678665161])
+Parameter_R.setValue(3)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
index 6e09d950ef5ba3244a27276f96ce0883008e63ff..e68c36f74f12d6acafdca3aa253a4908b20ffa5b 100644 (file)
@@ -6,6 +6,7 @@ model.begin()
 partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
+Parameter_H = model.addParameter(Part_1_doc, "H", "0.3")
 Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
 SketchLine_1 = Sketch_1.addLine(55.1, 10.3, 55.1, 0.3)
 SketchLine_2 = Sketch_1.addLine(55.1, 0.3, 2.3, 0.3)
@@ -71,7 +72,7 @@ SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_8.result(), S
 SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_11.result(), 55.4)
 SketchConstraintLength_3.setName("SketchConstraintLength_5")
 SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
-SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 0.3)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), "H")
 SketchArc_1 = Sketch_1.addArc(2.3, 2.3, 0.3, 2.3, 2.3, 0.3, False)
 SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_4.startPoint())
 SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_2.endPoint())
@@ -1040,6 +1041,12 @@ Sketch_8.setName("Sketch_9")
 Sketch_8.result().setName("Sketch_9")
 ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_9/Face-SketchLine_147f-SketchLine_148f-SketchArc_64_2f-SketchArc_65_2f"), model.selection("FACE", "Sketch_9/Face-SketchLine_139f-SketchLine_141f-SketchArc_63_2f-SketchArc_62_2f"), model.selection("FACE", "Sketch_9/Face-SketchArc_66_2f-SketchArc_67_2f-SketchLine_149r-SketchLine_150r")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_6_1")])
 model.do()
+
+# Test reexecution after parameter change
+Parameter_H.setValue(0.4)
+model.do()
+model.testResultsVolumes(ExtrusionCut_7, [5641.450357292746048187837004662])
+Parameter_H.setValue(0.3)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
index d5190da9a16bc929970ec068f292bec7b7cb1756..a25353b364bea9d87ca374a57e055c42289ef551 100644 (file)
@@ -36,6 +36,7 @@ SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_8.endPoint(),
 model.do()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
+Parameter_R = model.addParameter(Part_1_doc, "R", "15")
 Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
 SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "PartSet/Origin"))
 SketchLine_9 = Sketch_2.addLine(0, 0, 0, 45.59203984275747)
@@ -107,7 +108,7 @@ SketchLine_79 = Sketch_3.addLine(0, 0, 0, 15)
 SketchLine_79.setAuxiliary(True)
 SketchConstraintCoincidence_36 = Sketch_3.setCoincident(SketchLine_79.startPoint(), SketchPoint_3.result())
 SketchConstraintVertical_7 = Sketch_3.setVertical(SketchLine_79.result())
-SketchConstraintLength_8 = Sketch_3.setLength(SketchLine_79.result(), 15)
+SketchConstraintLength_8 = Sketch_3.setLength(SketchLine_79.result(), "R")
 SketchLine_80 = Sketch_3.addLine(0, 15, 0.5, 15)
 SketchLine_80.setAuxiliary(True)
 SketchConstraintCoincidence_37 = Sketch_3.setCoincident(SketchLine_79.endPoint(), SketchLine_80.startPoint())
@@ -171,6 +172,12 @@ model.do()
 ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Revolution_1_1/Generated_Face_1"), 0, model.selection(), 0, [model.selection("SOLID", "Revolution_1_1")])
 RevolutionCut_1 = model.addRevolutionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection("EDGE", "PartSet/OX"), 0, 360, [model.selection("SOLID", "ExtrusionCut_1_1")])
 model.do()
+
+# Test reexecution after parameter change
+Parameter_R.setValue(16)
+model.do()
+model.testResultsVolumes(RevolutionCut_1, [65207.601331337653391528874635696])
+Parameter_R.setValue(15)
 model.end()
 
 from GeomAPI import GeomAPI_Shape
diff --git a/test.models/idler_plate.py b/test.models/idler_plate.py
new file mode 100644 (file)
index 0000000..27cbc5c
--- /dev/null
@@ -0,0 +1,168 @@
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "ob1", "4.37")
+model.addParameter(Part_1_doc, "ob2", "4.38")
+model.addParameter(Part_1_doc, "axe", "11.25")
+Parameter_trou = model.addParameter(Part_1_doc, "trou", "7.5")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 0, 17.71094752491076, 14.8612495359528)
+SketchLine_1.setAuxiliary(True)
+SketchLine_2 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OX"))
+SketchConstraintAngle_1 = Sketch_1.setAngleBackward(SketchLine_1.result(), SketchLine_2.result(), 40.00000000000006)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, 0, 17.71094752491076, 14.8612495359528, 23.12, -6.011798491948799e-033, True)
+SketchArc_1.setAuxiliary(True)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_2.startPoint(), SketchArc_1.endPoint(), 23.12)
+SketchArc_2 = Sketch_1.addArc(23.12, -6.011798491948799e-033, 18.74, 0, 27.5, 0, False)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.center())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_2.endPoint())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_2.results()[1], "ob2")
+SketchArc_3 = Sketch_1.addArc(0, 0, 18.74, 0, 14.35567286404965, 12.04583980552575, False)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_3.center())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchArc_2.startPoint(), SketchArc_3.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_3.endPoint())
+SketchArc_4 = Sketch_1.addArc(0, 0, 27.5, 0, 21.0662221857694, 17.67665926638303, False)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_4.center())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_4.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchArc_4.endPoint(), SketchLine_1.result())
+SketchArc_5 = Sketch_1.addArc(17.71094752491078, 14.86124953595279, 14.35567286404965, 12.04583980552575, 21.0662221857694, 17.67665926638303, True)
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchArc_5.startPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchArc_4.endPoint(), SketchArc_5.endPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_5.results()[1], SketchArc_3.results()[1])
+SketchArc_6 = Sketch_1.addArc(-34.92, 0, -34.92, 4.370000000000002, -34.91999999999997, -4.370000000000019, False)
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchArc_6.center(), SketchLine_2.result())
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_6.results()[1], "ob1")
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchArc_6.center(), SketchArc_2.center(), 58.04)
+SketchLine_3 = Sketch_1.addLine(-24.92, 4.37, -34.92, 4.370000000000002)
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchArc_6.startPoint(), SketchLine_3.endPoint())
+SketchLine_4 = Sketch_1.addLine(-24.92, -4.37, -34.91999999999997, -4.370000000000019)
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchArc_6.endPoint(), SketchLine_4.endPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc_6.results()[1])
+SketchConstraintTangent_3 = Sketch_1.setTangent(SketchLine_4.result(), SketchArc_6.results()[1])
+SketchArc_7 = Sketch_1.addArc(-24.92, 1.467818159729891e-016, -24.92, 4.37, -24.92, -4.37, True)
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchArc_7.startPoint())
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_4.startPoint(), SketchArc_7.endPoint())
+SketchConstraintTangent_4 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc_7.results()[1])
+SketchConstraintTangent_5 = Sketch_1.setTangent(SketchArc_7.results()[1], SketchLine_4.result())
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchArc_6.center(), SketchArc_7.center(), 10)
+SketchCircle_1 = Sketch_1.addCircle(9.498292007139793e-031, -4.263345141625117e-031, 5.625)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchCircle_1.center())
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchCircle_1.results()[1], "axe/2")
+SketchCircle_2 = Sketch_1.addCircle(-7.5, 18.75, 3.75)
+SketchConstraintRadius_4 = Sketch_1.setRadius(SketchCircle_2.results()[1], "trou/2")
+SketchLine_5 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchLine_5.result(), SketchCircle_2.center(), 7.5)
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchLine_2.result(), SketchCircle_2.center(), 18.75)
+SketchArc_8 = Sketch_1.addArc(-34.92, -6.497717112746075e-027, -34.91999999999937, 7.500000000006299, -36.26235395189003, -7.378894623711957, False)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchArc_6.center(), SketchArc_8.center())
+SketchConstraintRadius_5 = Sketch_1.setRadius(SketchArc_8.results()[1], 7.5)
+SketchArc_9 = Sketch_1.addArc(-7.5, 18.75, 0.0511741035599095, 21.7492323447386, -15.3796231578326, 20.73170731707517, False)
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchCircle_2.center(), SketchArc_9.center())
+SketchConstraintRadius_6 = Sketch_1.setRadius(SketchArc_9.results()[1], "16.25/2")
+SketchArc_10 = Sketch_1.addArc(-32.35111919008745, 25.0000000000063, -15.3796231578326, 20.73170731707517, -32.35111919008745, 7.500000000006299, True)
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchArc_9.endPoint(), SketchArc_10.startPoint())
+SketchConstraintTangent_6 = Sketch_1.setTangent(SketchArc_9.results()[1], SketchArc_10.results()[1])
+SketchConstraintRadius_7 = Sketch_1.setRadius(SketchArc_10.results()[1], 17.5)
+SketchLine_6 = Sketch_1.addLine(-34.91999999999937, 7.500000000006299, -32.35111919008745, 7.500000000006299)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchArc_8.startPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchArc_10.endPoint(), SketchLine_6.endPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintTangent_7 = Sketch_1.setTangent(SketchLine_6.result(), SketchArc_10.results()[1])
+SketchArc_11 = Sketch_1.addArc(2.841203857564676e-031, -1.848261526152319e-031, -2.46098224513173, -13.52797347680525, 10.54941392733564, -8.818864200663077, False)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_11.center())
+SketchConstraintRadius_8 = Sketch_1.setRadius(SketchArc_11.results()[1], 13.75)
+SketchLine_7 = Sketch_1.addLine(-36.26235395189003, -7.378894623711957, -2.460982245131729, -13.52797347680525)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchArc_8.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchArc_11.startPoint(), SketchLine_7.endPoint())
+SketchConstraintTangent_8 = Sketch_1.setTangent(SketchLine_7.result(), SketchArc_8.results()[1])
+SketchConstraintTangent_9 = Sketch_1.setTangent(SketchLine_7.result(), SketchArc_11.results()[1])
+SketchArc_12 = Sketch_1.addArc(23.12, 7.384930033544359e-028, 18.58435121107267, -7.482672655108066, 31.87, -1.068593854246008e-030, False)
+SketchConstraintCoincidence_30 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_12.center())
+SketchConstraintCoincidence_31 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_12.endPoint())
+SketchArc_13 = Sketch_1.addArc(15.34460207612463, -12.82743883732818, 10.5494139273357, -8.818864200663123, 18.58435121107276, -7.482672655108122, True)
+SketchConstraintCoincidence_32 = Sketch_1.setCoincident(SketchArc_11.endPoint(), SketchArc_13.startPoint())
+SketchConstraintCoincidence_33 = Sketch_1.setCoincident(SketchArc_12.startPoint(), SketchArc_13.endPoint())
+SketchConstraintTangent_10 = Sketch_1.setTangent(SketchArc_13.results()[1], SketchArc_12.results()[1])
+SketchConstraintRadius_9 = Sketch_1.setRadius(SketchArc_12.results()[1], 8.75)
+SketchConstraintTangent_11 = Sketch_1.setTangent(SketchArc_13.results()[1], SketchArc_11.results()[1])
+SketchArc_14 = Sketch_1.addArc(7.217739748128488e-031, -7.397577026331382e-031, 31.87, 1.64056023214913e-033, 24.41383640220182, 20.48564112071002, False)
+SketchConstraintCoincidence_34 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_14.center())
+SketchConstraintCoincidence_35 = Sketch_1.setCoincident(SketchArc_12.endPoint(), SketchArc_14.startPoint())
+SketchConstraintCoincidence_36 = Sketch_1.setCoincident(SketchArc_14.endPoint(), SketchLine_1.result())
+SketchArc_15 = Sketch_1.addArc(17.71094752491077, 14.86124953595279, 24.41383640220183, 20.48564112071001, 10.79776038328427, 20.22504889320414, False)
+SketchConstraintCoincidence_37 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchArc_15.center())
+SketchConstraintCoincidence_38 = Sketch_1.setCoincident(SketchArc_14.endPoint(), SketchArc_15.startPoint())
+SketchArc_16 = Sketch_1.addArc(5.859769567836763, 24.05633414838368, 10.79776038328427, 20.22504889320414, 0.05117410355990894, 21.7492323447386, True)
+SketchConstraintCoincidence_39 = Sketch_1.setCoincident(SketchArc_15.endPoint(), SketchArc_16.startPoint())
+SketchConstraintCoincidence_40 = Sketch_1.setCoincident(SketchArc_9.startPoint(), SketchArc_16.endPoint())
+SketchConstraintTangent_12 = Sketch_1.setTangent(SketchArc_16.results()[1], SketchArc_15.results()[1])
+SketchConstraintTangent_13 = Sketch_1.setTangent(SketchArc_16.results()[1], SketchArc_9.results()[1])
+SketchConstraintRadius_10 = Sketch_1.setRadius(SketchArc_16.results()[1], 6.25)
+SketchConstraintRadius_11 = Sketch_1.setRadius(SketchArc_13.results()[1], 6.25)
+SketchConstraintTangent_14 = Sketch_1.setTangent(SketchLine_6.result(), SketchArc_8.results()[1])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_2_2r-SketchArc_3_2f-SketchArc_4_2r-SketchArc_5_2r-SketchArc_6_2r-SketchLine_3r-SketchLine_4f-SketchArc_7_2r-SketchCircle_1_2r-SketchCircle_2_2r-SketchArc_8_2f-SketchArc_9_2f-SketchArc_10_2r-SketchLine_6r-SketchArc_11_2f-SketchLine_7f-SketchArc_12_2f-SketchArc_13_2r-SketchArc_14_2f-SketchArc_15_2f-SketchArc_16_2r")], model.selection(), 0, 2)
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_2.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_7"))
+SketchArc_17 = Sketch_2.addArc(-24.92, -4.314010717669617e-016, -24.92, 7.500000000006299, -24.92, -7.500000000006299, True)
+SketchConstraintCoincidence_41 = Sketch_2.setCoincident(SketchPoint_1.result(), SketchArc_17.center())
+SketchPoint_2 = Sketch_2.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_8_2s-SketchLine_6s"))
+SketchPoint_3 = Sketch_2.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_6-SketchArc_8"))
+SketchArc_18 = Sketch_2.addArc(-34.92, 0, -34.91999999999937, 7.500000000006299, -34.92003434105975, -7.500000000006299, False)
+SketchConstraintCoincidence_42 = Sketch_2.setCoincident(SketchPoint_3.result(), SketchArc_18.center())
+SketchConstraintCoincidence_43 = Sketch_2.setCoincident(SketchPoint_2.result(), SketchArc_18.startPoint())
+SketchLine_8 = Sketch_2.addLine(-34.91999999999937, 7.500000000006299, -24.92, 7.500000000006299)
+SketchConstraintCoincidence_44 = Sketch_2.setCoincident(SketchPoint_2.coordinates(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_45 = Sketch_2.setCoincident(SketchArc_17.startPoint(), SketchLine_8.endPoint())
+SketchLine_9 = Sketch_2.addLine(-34.92003434105975, -7.500000000006299, -24.92, -7.500000000006299)
+SketchConstraintCoincidence_46 = Sketch_2.setCoincident(SketchArc_18.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_47 = Sketch_2.setCoincident(SketchArc_17.endPoint(), SketchLine_9.endPoint())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_8.result())
+SketchConstraintHorizontal_5 = Sketch_2.setHorizontal(SketchLine_9.result())
+SketchConstraintTangent_15 = Sketch_2.setTangent(SketchLine_8.result(), SketchArc_17.results()[1])
+SketchConstraintTangent_16 = Sketch_2.setTangent(SketchArc_17.results()[1], SketchLine_9.result())
+SketchPoint_4 = Sketch_2.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchCircle_2-SketchArc_9"))
+SketchCircle_3 = Sketch_2.addCircle(-7.5, 18.75, 8.125)
+SketchConstraintCoincidence_48 = Sketch_2.setCoincident(SketchPoint_4.result(), SketchCircle_3.center())
+SketchArc_19 = Sketch_2.addArc(model.selection("EDGE", "Sketch_1/Edge-SketchArc_9_2"))
+SketchConstraintEqual_1 = Sketch_2.setEqual(SketchCircle_3.results()[1], SketchArc_19.results()[1])
+SketchPoint_5 = Sketch_2.addPoint(model.selection("VERTEX", "Sketch_1/Vertex-SketchArc_1-SketchArc_3-SketchArc_4-SketchCircle_1-SketchArc_11-SketchArc_14-SketchLine_1s-SketchLine_2s-SketchLine_5s"))
+SketchCircle_4 = Sketch_2.addCircle(0, 0, 8.75)
+SketchConstraintCoincidence_49 = Sketch_2.setCoincident(SketchPoint_5.result(), SketchCircle_4.center())
+SketchConstraintRadius_12 = Sketch_2.setRadius(SketchCircle_4.results()[1], "17.5/2")
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchArc_17_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_9"), model.selection("EDGE", "Sketch_2/Edge-SketchArc_18_2"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_6_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchArc_7_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_2_2")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1")], model.selection(), 2, 0)
+Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2"), model.selection("SOLID", "Extrusion_2_3")], [])
+model.do()
+
+# Test reexecution after parameter change
+Parameter_trou.setValue(3.5)
+model.do()
+model.testResultsVolumes(Boolean_1, [4039.112573151546712324488908052])
+Parameter_trou.setValue(7.5)
+model.end()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Boolean_1, 1)
+model.testNbSubResults(Boolean_1, [0])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.FACE, [38])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.EDGE, [188])
+model.testNbSubShapes(Boolean_1, GeomAPI_Shape.VERTEX, [376])
+model.testResultsVolumes(Boolean_1, [3900.882496393901419651228934526])
+
+assert(model.checkPythonDump())