Salome HOME
Fix for the issue #2172 and the issue #2198 : additional naming for revolution edges...
authormpv <mpv@opencascade.com>
Wed, 12 Jul 2017 07:04:24 +0000 (10:04 +0300)
committermpv <mpv@opencascade.com>
Wed, 12 Jul 2017 07:04:24 +0000 (10:04 +0300)
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_CompositeSketch.cpp
src/FeaturesPlugin/Test/Test2172.py [new file with mode: 0644]
src/FeaturesPlugin/Test/Test2197_1.py [new file with mode: 0644]
src/FeaturesPlugin/Test/Test2197_2.py [new file with mode: 0644]
src/GeomAPI/GeomAPI_Edge.cpp
src/GeomAPI/GeomAPI_Edge.h
src/Model/Model_SelectionNaming.cpp
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp

index 4673350c21a13ac84185f599ede26188907a3ee5..07d22019c35528b1a222273b990f3f4e9bed4a9e 100644 (file)
@@ -167,6 +167,9 @@ ADD_UNIT_TESTS(TestExtrusion.py
                Test2023.py
                Test2046.py
                Test2038.py
+               Test2172.py
                Test2194.py
+               Test2197_1.py
+               Test2197_2.py
                Test2215.py
 )
index 4d81b553b9fabe7a8f1f831e8d49dd8a8caabe1a..676023d3119ef3abd99c4fe9503302b46d5ccc73 100644 (file)
@@ -335,6 +335,56 @@ void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theRes
                                                 theTag++, aGenName + "Face",
                                                 *aMapOfSubShapes.get());
   }
+  // issue #2197: make naming of edges generated from vertices
+  if (aShapeTypeToExplode == GeomAPI_Shape::EDGE) {
+    GeomAPI_DataMapOfShapeShape aFacesFromFromEdges;
+    GeomAPI_ShapeExplorer anEdgeExp(theBaseShape, GeomAPI_Shape::EDGE);
+    for(; anEdgeExp.more(); anEdgeExp.next()) {
+      ListOfShape aGenerated;
+      theMakeShape->generated(anEdgeExp.current(), aGenerated);
+      ListOfShape::iterator aGenIter = aGenerated.begin();
+      for(; aGenIter != aGenerated.end(); aGenIter++) {
+        aFacesFromFromEdges.bind(*aGenIter, anEdgeExp.current());
+      }
+    }
+
+    // closed revolution of 1-3 faces can not distinguish lateral and base edges
+    if (aFacesFromFromEdges.size() <= 3) {
+      bool isClosed = false; // lateral edges are closed (in full revolution)
+      GeomAPI_DataMapOfShapeShape anEdgesFromVertices;
+      GeomAPI_ShapeExplorer aVertExp(theBaseShape, GeomAPI_Shape::VERTEX);
+      for(int anIndex = 1; aVertExp.more(); aVertExp.next()) {
+        ListOfShape aGenerated;
+        theMakeShape->generated(aVertExp.current(), aGenerated);
+        ListOfShape::iterator aGenIter = aGenerated.begin();
+        for(; aGenIter != aGenerated.end(); aGenIter++) {
+          std::shared_ptr<GeomAPI_Shape> aGenerated = *aGenIter;
+          if (anEdgesFromVertices.isBound(aGenerated)) // already here
+            continue;
+          std::ostringstream aStream;
+          aStream<<"Lateral_Edge_"<<anIndex++;
+          theResultBody->generated(aGenerated, aStream.str(), theTag++);
+
+          anEdgesFromVertices.bind(aGenerated, aVertExp.current());
+          std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aGenerated));
+          isClosed = isClosed || anEdge->isClosed();
+        }
+      }
+      if (isClosed) {
+        GeomAPI_ShapeExplorer anEdgesExp(theMakeShape->shape(), GeomAPI_Shape::EDGE);
+        for(int anIndex = 1; anEdgesExp.more(); anEdgesExp.next()) {
+          if (!anEdgesFromVertices.isBound(anEdgesExp.current())) {
+            // found a base edge
+            std::ostringstream aStream;
+            aStream<<"Base_Edge_"<<anIndex++;
+            theResultBody->generated(anEdgesExp.current(), aStream.str(), theTag++);
+            // only one orientation is needed
+            anEdgesFromVertices.bind(anEdgesExp.current(), anEdgesExp.current());
+          }
+        }
+      }
+    }
+  }
 
   std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep =
     std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
diff --git a/src/FeaturesPlugin/Test/Test2172.py b/src/FeaturesPlugin/Test/Test2172.py
new file mode 100644 (file)
index 0000000..af8c163
--- /dev/null
@@ -0,0 +1,89 @@
+## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(-85.62958302127123, 51.64856737222455, 159.4430553521271, 401.6485673722245)
+SketchLine_2 = Sketch_1.addLine(159.4430553521271, 401.6485673722245, 909.4430553521272, 401.6485673722245)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(909.4430553521272, 401.6485673722245, 909.4430553521272, -98.35143262777548)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(909.4430553521272, -98.35143262777548, 551.916977573864, -398.3514326277755)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(551.916977573864, -398.3514326277755, -18.08302242613596, -398.3514326277755)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-18.08302242613596, -398.3514326277755, -18.08302242613596, -98.35143262777552)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, -7.626897158721915e-023, -85.62958302127123, 51.64856737222455, -18.08302242613596, -98.35143262777552, False)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 100)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 750)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_3.result(), 500)
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_5.result(), 570)
+SketchConstraintAngle_1 = Sketch_1.setAngleBackward(SketchLine_5.result(), SketchLine_4.result(), 139.9999999999999)
+SketchConstraintAngle_2 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_2.result(), 124.9999999999987)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_6.result(), 300)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.startPoint(), SketchLine_2.result(), 350)
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_4.startPoint(), SketchLine_5.result(), 300)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchArc_1.center(), SketchPoint_1.coordinates())
+SketchCircle_1 = Sketch_1.addCircle(623.3624504738834, 247.4315530304268, 75)
+SketchCircle_2 = Sketch_1.addCircle(267.9975824521076, 55.86558171402226, 100)
+SketchLine_7 = Sketch_1.addLine(-18.08302242613596, -98.35143262777552, 356.0223839531057, 103.3169707422677)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(557.3438493481349, 211.8430112592427, 909.4430553521272, 401.6485673722245)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_8.endPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchCircle_2.center(), SketchLine_7.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_7.result())
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchCircle_2.results()[1], 100)
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchCircle_1.results()[1], 75)
+SketchPoint_2 = Sketch_1.addPoint(557.3438493481349, 211.8430112592427)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchLine_8.startPoint())
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_7.result(), SketchLine_8.result())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchCircle_2.results()[1])
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchCircle_2.center(), SketchLine_6.endPoint(), 325)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchCircle_1.results()[1])
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_2.endPoint(), 325)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f-SketchLine_8f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Revolution_2 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_2_2f-SketchLine_7r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_3"), model.selection("EDGE", "Revolution_2_1/Base_Edge_2"), model.selection("EDGE", "Revolution_2_1/Base_Edge_3"), model.selection("EDGE", "Revolution_2_1/Base_Edge_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 10)
+for a in range(3):
+  assert(Group_1.groupList().value(a).value().shapeTypeStr() == "EDGE")
+  assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/Test2197_1.py b/src/FeaturesPlugin/Test/Test2197_1.py
new file mode 100644 (file)
index 0000000..e157deb
--- /dev/null
@@ -0,0 +1,45 @@
+## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-150, 79, -50, 79)
+SketchCircle_2 = Sketch_1.addCircle(-155, 278, -10, 278)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f-SketchCircle_2_2f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_3")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_3")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+for aGroupIter in [Group_1, Group_2]:
+  assert(aFactory.validate(aGroupIter.feature()))
+  assert(aGroupIter.groupList().size() == 3)
+  for a in range(3):
+    assert(aGroupIter.groupList().value(a).value().shapeTypeStr() == "EDGE")
+
+assert(model.checkPythonDump())
diff --git a/src/FeaturesPlugin/Test/Test2197_2.py b/src/FeaturesPlugin/Test/Test2197_2.py
new file mode 100644 (file)
index 0000000..c32cd44
--- /dev/null
@@ -0,0 +1,48 @@
+## Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-150, 80, 100)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Base_Edge_1")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Lateral_Edge_1&Revolution_1_1/Base_Edge_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+for aGroupIter in [Group_1, Group_2, Group_3]:
+  assert(aFactory.validate(aGroupIter.feature()))
+  assert(aGroupIter.groupList().size() == 1)
+  if aGroupIter == Group_3:
+    assert(aGroupIter.groupList().value(0).value().shapeTypeStr() == "VERTEX")
+  else:
+    assert(aGroupIter.groupList().value(0).value().shapeTypeStr() == "EDGE")
+
+assert(model.checkPythonDump())
index c336050f9c08bdd5f35cf56cd3e08e8a090303da..1fd744fd4a07584b582062d56b811d1caff25d76 100644 (file)
@@ -247,3 +247,17 @@ double GeomAPI_Edge::length() const
   Adaptor3d_Curve* anAdaptor3d = &aBRepAdaptor;
   return GCPnts_AbscissaPoint::Length(*anAdaptor3d);
 }
+
+bool GeomAPI_Edge::isClosed() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+  if (aShape.IsNull())
+    return false;
+  double aFirst, aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+  if (aCurve.IsNull() || !aCurve->IsPeriodic())
+    return false;
+  aLast += aLast > aFirst ? -aCurve->Period() : aCurve->Period();;
+
+  return fabs(aFirst - aLast) < 1.e-9;
+}
index 44c76df82e306eee106ff9722afff13c6f81d00c..c1a0c1eaa4bb54a916099e15d8dd9ecd61d4155d 100644 (file)
@@ -87,6 +87,10 @@ public:
   /// Returns edge length.
   GEOMAPI_EXPORT
   double length() const;
+
+  /// Returns true if the edge is closed (like full circle)
+  GEOMAPI_EXPORT
+  bool isClosed() const;
 };
 
 #endif
index 188ffdb24506112f0c5fec2c94e26a810ebc90ba..2f88d7e65e2d224b3e4060b87452b17442a3e6ae 100644 (file)
@@ -137,6 +137,8 @@ bool isTrivial (const TopTools_ListOfShape& theAncestors, TopTools_IndexedMapOfS
   BB.MakeCompound(aCmp);
   TopTools_ListIteratorOfListOfShape it(theAncestors);
   for(;it.More();it.Next()) {
+    if (theSMap.Contains(it.Value()))
+      continue;
     BB.Add(aCmp, it.Value());
     theSMap.Add(it.Value());
   }
@@ -440,7 +442,7 @@ const TopoDS_Shape findFaceByName(
 size_t ParseName(const std::string& theSubShapeName,   std::list<std::string>& theList)
 {
   std::string aName = theSubShapeName;
-  std::string aLastName;
+  std::string aLastName = aName;
   size_t n1(0), n2(0); // n1 - start position, n2 - position of the delimiter
   while ((n2 = aName.find('&', n1)) != std::string::npos) {
     const std::string aName1 = aName.substr(n1, n2 - n1); //name of face
@@ -456,8 +458,17 @@ size_t ParseName(const std::string& theSubShapeName,   std::list<std::string>& t
 const TopoDS_Shape findCommonShape(
   const TopAbs_ShapeEnum theType, const TopTools_ListOfShape& theList)
 {
-  if(theList.Extent() < 2) {
+  if(theList.Extent() < 1) {
     return TopoDS_Shape();
+  } else if (theList.Extent() == 1) { // check that sub-shape is bounded by this alone shape
+    TopTools_MapOfShape aSubsInShape;
+    TopExp_Explorer anExp(theList.First(), theType);
+    for(; anExp.More(); anExp.Next()) {
+      if (aSubsInShape.Contains(anExp.Current())) { // found duplicate
+        return anExp.Current();
+      }
+      aSubsInShape.Add(anExp.Current());
+    }
   }
 
   // Store in maps sub-shapes from each face.
@@ -792,11 +803,15 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     return false;
     }
   }
+  if (!aSelection.IsNull() &&
+      aSelection.ShapeType() != aType && aSelection.ShapeType() != TopAbs_COMPOUND)
+      aSelection.Nullify(); // to avoid selection of face instead of edge that is described by face
   // another try to find edge or vertex by faces
   std::list<std::string> aListofNames;
   size_t aN = aSelection.IsNull() ? ParseName(aSubShapeName, aListofNames) : 0;
-  if (aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) {
-    if(aN > 1) {
+  if ((aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) ||
+      (!aSelection.IsNull() && aSelection.ShapeType() != aType)) { // edge by one face as example
+    if(aN >= 1) {
       TopTools_ListOfShape aList;
       std::list<std::string>::iterator it = aListofNames.begin();
       for(; it != aListofNames.end(); it++){
@@ -809,7 +824,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   }
   // in case of construction, there is no registered names for all sub-elements,
   // even for the main element; so, trying to find them by name (without "&" intersections)
-  if (aN == 0) {
+  if (aN < 2) {
     size_t aConstrNamePos = aSubShapeName.find("/");
     bool isFullName = aConstrNamePos == std::string::npos;
     std::string aContrName = aContName;
index 881eace025e0da979dd9944e1d319d6d60764853..36932d4ddee7442002e25a7cc3419c09a320f014 100644 (file)
@@ -138,7 +138,6 @@ bool SketchPlugin_ConstraintLength::getPoints(
 {
   if (!sketch())
     return false;
-  std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
   std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
   if (!anAttr)