Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
authormpv <mpv@opencascade.com>
Wed, 25 Mar 2015 09:00:51 +0000 (12:00 +0300)
committermpv <mpv@opencascade.com>
Wed, 25 Mar 2015 09:00:51 +0000 (12:00 +0300)
Conflicts:
src/SketchPlugin/SketchPlugin_Sketch.cpp

1  2 
src/GeomAPI/GeomAPI_AISObject.cpp
src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp
src/Model/Model_AttributeRefList.cpp
src/Model/Model_AttributeReference.cpp
src/Model/Model_AttributeSelection.cpp
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Circle.cpp
src/SketchPlugin/SketchPlugin_Line.cpp
src/SketchPlugin/SketchPlugin_Point.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp

index f4ae420490bada6d8d4b177459ba93c67198fb94,f4ae420490bada6d8d4b177459ba93c67198fb94..8f053f7cf90a838a5741d17fb442dc9d6e85ee29
@@@ -311,9 -311,9 +311,9 @@@ void GeomAPI_AISObject::getColor(int& t
      return;
  
    Quantity_Color aColor = anAIS->Color();
--  theR = aColor.Red()*255.;
--  theG = aColor.Green()*255.;
--  theB = aColor.Blue()*255.;
++  theR = (int)(aColor.Red()*255.);
++  theG = (int)(aColor.Green()*255.);
++  theB = (int)(aColor.Blue()*255.);
  }
  
  bool GeomAPI_AISObject::empty() const
index 3cc4f85aedc6bea31cedcd8ecf2e713996ef2a54,4b815e3a10a584bcb2ca22f6f3d892c1bac8fee6..9933454463b8291eeb282c427c6cda2f7708dcc0
  #include <GeomAlgoAPI_Placement.h>
  #include <GeomAlgoAPI_DFLoader.h>
  
+ #include <GeomAPI_Edge.h>
+ #include <GeomAPI_Lin.h>
  #include <GeomAPI_Pnt.h>
+ #include <GeomAPI_Pln.h>
+ #include <GeomAPI_Vertex.h>
+ #include <GeomAPI_XYZ.h>
  
  #include <BRepBuilderAPI_Transform.hxx>
  #include <gp_Trsf.hxx>
  #include <gp_Quaternion.hxx>
  #include <TopExp_Explorer.hxx>
  #include <BRepCheck_Analyzer.hxx>
+ #include <BRepClass3d_SolidClassifier.hxx>
  #include <GProp_GProps.hxx>
  #include <BRepGProp.hxx>
  #include <Precision.hxx>
  #define DEB_PLACEMENT 1
  GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
-     std::shared_ptr<GeomAPI_Shape> theAttractiveFace,
-     std::shared_ptr<GeomAPI_Pln> theSourcePlane,
-     std::shared_ptr<GeomAPI_Pln> theDestPlane)
+     std::shared_ptr<GeomAPI_Shape> theSourceSolid,
+     std::shared_ptr<GeomAPI_Shape> theDestSolid,
+     std::shared_ptr<GeomAPI_Shape> theSourceShape,
+     std::shared_ptr<GeomAPI_Shape> theDestShape,
+     bool theIsReverse,
+     bool theIsCentering)
    : myDone(false),
      myShape(new GeomAPI_Shape())
  {
-   build(theAttractiveFace, theSourcePlane, theDestPlane);
+   build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, theIsReverse, theIsCentering);
  }
  
  void GeomAlgoAPI_Placement::build(
-     const std::shared_ptr<GeomAPI_Shape>& theAttractiveShape,
-     const std::shared_ptr<GeomAPI_Pln>& theSourcePlane,
-     const std::shared_ptr<GeomAPI_Pln>& theDestPlane)
+     const std::shared_ptr<GeomAPI_Shape>& theSourceSolid,
+     const std::shared_ptr<GeomAPI_Shape>& theDestSolid,
+     const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
+     const std::shared_ptr<GeomAPI_Shape>& theDestShape,
+     bool theIsReverse,
+     bool theIsCentering)
  {
-   std::shared_ptr<GeomAPI_Dir> aSourceDir = theSourcePlane->direction();
-   std::shared_ptr<GeomAPI_Pnt> aSourceLoc = theSourcePlane->location();
-   std::shared_ptr<GeomAPI_Dir> aDestDir = theDestPlane->direction();
-   std::shared_ptr<GeomAPI_Pnt> aDestLoc = theDestPlane->location();
+   // Filling the parameters of the objects
+   static const int aNbObjects = 2;
+   gp_Pnt aSrcDstPoints[aNbObjects]; // points on the selected objects (0 - source, 1 - destination)
+   gp_Vec aSrcDstNormals[aNbObjects]; // normal vectors, if planar faces are selected
+   gp_Vec aSrcDstDirections[aNbObjects]; // directions of linear edges
+   bool hasNormal[aNbObjects];
+   bool hasDirection[aNbObjects];
+   std::shared_ptr<GeomAPI_Shape> aShapes[aNbObjects] = {theSourceShape, theDestShape};
+   for (int i = 0; i < aNbObjects; i++) {
+     if (aShapes[i]->isFace()) {
+       std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aShapes[i]));
+       std::shared_ptr<GeomAPI_Pln> aPlane = aFace->getPlane();
+       std::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
+       std::shared_ptr<GeomAPI_Pnt> aLoc = aPlane->location();
+       aSrcDstPoints[i].SetCoord(aLoc->x(), aLoc->y(), aLoc->z());
+       aSrcDstNormals[i].SetCoord(aDir->x(), aDir->y(), aDir->z());
+     } else if (aShapes[i]->isEdge()) {
+       std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aShapes[i]));
+       std::shared_ptr<GeomAPI_Lin> aLine = anEdge->line();
+       std::shared_ptr<GeomAPI_Dir> aDir = aLine->direction();
+       std::shared_ptr<GeomAPI_Pnt> aFirstPnt = anEdge->firstPoint();
+       std::shared_ptr<GeomAPI_Pnt> aLastPnt = anEdge->lastPoint();
+       std::shared_ptr<GeomAPI_XYZ> aLoc = aFirstPnt->xyz()->added(aLastPnt->xyz())->multiplied(0.5);
+       aSrcDstPoints[i].SetCoord(aLoc->x(), aLoc->y(), aLoc->z());
+       aSrcDstDirections[i].SetCoord(aDir->x(), aDir->y(), aDir->z());
+     } else if (aShapes[i]->isVertex()) {
+       std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aShapes[i]));
+       std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
+       aSrcDstPoints[i].SetCoord(aPnt->x(), aPnt->y(), aPnt->z());
+     } else // something goes wrong
+       return;
+     hasNormal[i] = aSrcDstNormals[i].SquareMagnitude() >= Precision::SquareConfusion();
+     hasDirection[i] = aSrcDstDirections[i].SquareMagnitude() >= Precision::SquareConfusion();
+   }
+   // Initial shapes
+   const TopoDS_Shape& aSourceShape = theSourceSolid->impl<TopoDS_Shape>();
+   const TopoDS_Shape& aDestShape = theDestSolid->impl<TopoDS_Shape>();
+   // Check the material of the solids to be on the correct side
+   BRepClass3d_SolidClassifier aClassifier;
+   static const double aTransStep = 10. * Precision::Confusion();
+   if (hasNormal[0]) {
+     aClassifier.Load(aSourceShape);
+     gp_Pnt aPoint = aSrcDstPoints[0];
+     aPoint.Translate(aSrcDstNormals[0] * aTransStep);
+     aClassifier.Perform(aPoint, Precision::Confusion());
+     if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) ||
+         (aClassifier.State() == TopAbs_IN && theIsReverse))
+       aSrcDstNormals[0].Reverse();
+   }
+   if (hasNormal[1]) {
+     aClassifier.Load(aDestShape);
+     gp_Pnt aPoint = aSrcDstPoints[1];
+     aPoint.Translate(aSrcDstNormals[1] * aTransStep);
+     aClassifier.Perform(aPoint, Precision::Confusion());
+     if (aClassifier.State() == TopAbs_IN)
+       aSrcDstNormals[1].Reverse();
+   }
+   // Calculate directions, which comply the normal, for vertices and edges
+   if (!hasNormal[0] || !hasNormal[1]) {
+     if (hasNormal[0] || hasNormal[1]) { // plane with line or vertex
+       if (hasDirection[0] || hasDirection[1]) { // plane - line
+         int anInd = hasDirection[0] ? 0 : 1;
+         gp_Vec aVec = aSrcDstNormals[1 - anInd].Crossed(aSrcDstDirections[anInd]);
+         if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and direction are collinear
+           aVec = aSrcDstNormals[1 - anInd].Crossed(
+               gp_Vec(aSrcDstPoints[1 - anInd], aSrcDstPoints[anInd]));
+           if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and points direction are collinear
+             if (Abs(aSrcDstNormals[1 - anInd].Y()) >= Precision::Confusion() || 
+                 Abs(aSrcDstNormals[1 - anInd].Z()) >= Precision::Confusion())
+               aVec = gp::DX();
+             else
+               aVec = gp::DY();
+           }
+         }
+         aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized();
+       } else { // plane - point
+         int anInd = hasNormal[0] ? 1 : 0;
+         aSrcDstNormals[anInd] = aSrcDstNormals[1 - anInd];
+       }
+     } else {
+       if (hasDirection[0] && hasDirection[1]) { // line - line
+         gp_Vec aVec = aSrcDstDirections[0].Crossed(aSrcDstDirections[1]);
+         if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are parallel
+           aVec = aSrcDstDirections[0].Crossed(gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1]));
+           if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are equal
+             if (Abs(aSrcDstDirections[0].Y()) >= Precision::Confusion() ||
+                 Abs(aSrcDstDirections[0].Z()) >= Precision::Confusion())
+               aVec = gp::DX();
+             else
+               aVec = gp::DY();
+           }
+         }
+         aSrcDstNormals[0] = aSrcDstDirections[0].Crossed(aVec);
+         aSrcDstNormals[0].Normalize();
+         aSrcDstNormals[1] = aSrcDstDirections[1].Crossed(aVec);
+         aSrcDstNormals[1].Normalize();
+         if (aSrcDstDirections[0].Dot(aSrcDstDirections[1]) < -Precision::Confusion())
+           aSrcDstNormals[1].Reverse();
+       } else if (!hasDirection[0] && !hasDirection[1]) { // point - point
+         aSrcDstNormals[0] = gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1]);
+         aSrcDstNormals[0].Normalize();
+         aSrcDstNormals[1] = -aSrcDstNormals[0];
+       } else { // line - point
+         int anInd = hasDirection[0] ? 0 : 1;
+         gp_Vec aVec(aSrcDstPoints[anInd], aSrcDstPoints[1 - anInd]);
+         aVec.Cross(aSrcDstDirections[anInd]);
+         if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // point is on line
+           if (Abs(aSrcDstDirections[1 - anInd].Y()) >= Precision::Confusion() || 
+               Abs(aSrcDstDirections[1 - anInd].Z()) >= Precision::Confusion())
+             aVec = gp::DX();
+           else
+             aVec = gp::DY();
+         }
+         aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized();
+         aSrcDstNormals[1 - anInd] = aSrcDstNormals[anInd];
+       }
+     }
+   }
+   // Reverse the normal if it was not done before
+   if (!hasNormal[0] && theIsReverse)
+     aSrcDstNormals[0].Reverse();
  
    // Calculate transformation
    gp_Trsf aTrsf;
-   gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z());
-   gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z());
+   gp_Vec aSrcDir = aSrcDstNormals[0];
+   gp_Vec aDstDir = aSrcDstNormals[1];
++  gp_Vec aSrcDir = aSrcDstNormals[0];
++  gp_Vec aDstDir = aSrcDstNormals[1];
+   // Calculate rotation
    gp_Quaternion aRot(aSrcDir, aDstDir);
    aTrsf.SetRotation(aRot);
-   gp_Vec aSrcCenter(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z());
-   aSrcCenter.Transform(aTrsf);
-   gp_Vec aTrans(aDestLoc->x() - aSrcCenter.X(),
-                 aDestLoc->y() - aSrcCenter.Y(),
-                 aDestLoc->z() - aSrcCenter.Z());
+   // Calculate translation
+   gp_Vec aSrcLoc(aSrcDstPoints[0].XYZ());
+   gp_Vec aDstLoc(aSrcDstPoints[1].XYZ());
+   if (!theIsCentering)
+     aDstLoc = aSrcLoc + gp_Vec(aDstDir) * (aDstLoc-aSrcLoc).Dot(aDstDir);
+   aSrcLoc.Transform(aTrsf);
+   gp_Vec aTrans = aDstLoc - aSrcLoc;
    aTrsf.SetTransformation(aRot, aTrans);
  
    // Transform the shape with copying it
-   const TopoDS_Shape& aShape = theAttractiveShape->impl<TopoDS_Shape>();
-   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aShape, aTrsf, true);
+   BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
    if(aBuilder) {
      setImpl(aBuilder);
      myDone = aBuilder->IsDone() == Standard_True;
index effa56db232cb21a0989fc801baad662fcf283a1,effa56db232cb21a0989fc801baad662fcf283a1..c9722835887b00258b8e1acbac9797dac0dd06c1
@@@ -16,6 -16,6 +16,12 @@@ void Model_AttributeRefList::append(Obj
  {
    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
    myRef->Append(aData->label().Father());  // store label of the object
++  // do it before the transaction finish to make just created/removed objects know dependencies
++  // and reference from composite feature is removed automatically
++  FeaturePtr anOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
++  if (anOwnerFeature.get()) {
++    aData->addBackReference(anOwnerFeature, id());
++  }
  
    owner()->data()->sendAttributeUpdated(this);
  }
index 43bbabe658fff74259890026c982b1302d55670c,43bbabe658fff74259890026c982b1302d55670c..91de64eb567de9f94889a6274c98f8ae8c6dcebc
@@@ -22,9 -22,9 +22,9 @@@ void Model_AttributeReference::setValue
    if(!theObject)
      return;
    if (!myIsInitialized || value() != theObject) {
--      std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(
--          theObject->data());
--      TDF_Label anObjLab = aData->label().Father(); // object label
++    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(
++        theObject->data());
++    TDF_Label anObjLab = aData->label().Father(); // object label
  
      if (owner()->document() == theObject->document()) { // same document, use reference attribute
  
        TDF_Tool::Entry(anObjLab, anEntry);
        TDataStd_AsciiString::Set(myRef->Label(), anEntry);
      }
++    // do it before the transaction finish to make just created/removed objects know dependencies
++    // and reference from composite feature is removed automatically
++    FeaturePtr anOwnerFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
++    if (anOwnerFeature.get()) {
++      aData->addBackReference(anOwnerFeature, id());
++    }
  
      owner()->data()->sendAttributeUpdated(this);
    }
index c09fff9920d521959be52a8b9072d5a0c4e47abe,4e1f21b91afd30e2121a6e55db511d24dd1566cf..f1cf7fa5b42f4b8266c9cfac080b76ed11ed2e57
@@@ -15,6 -15,7 +15,6 @@@
  #include <ModelAPI_CompositeFeature.h>
  #include <GeomAPI_Shape.h>
  #include <GeomAPI_PlanarEdges.h>
 -#include <GeomAlgoAPI_SketchBuilder.h>
  #include <Events_Error.h>
  
  #include <TNaming_Selector.hxx>
@@@ -85,6 -86,13 +85,13 @@@ void Model_AttributeSelection::setValue
    TDF_Label aSelLab = selectionLabel();
    aSelLab.ForgetAttribute(kSIMPLE_REF_ID);
    aSelLab.ForgetAttribute(kCONSTUCTION_SIMPLE_REF_ID);
+   if (!theContext.get()) {
+     // to keep the reference attribute label
+     TDF_Label aRefLab = myRef.myRef->Label();
+     aSelLab.ForgetAllAttributes(true);
+     myRef.myRef = TDF_Reference::Set(aSelLab, aSelLab);
+     return;
+   }
    if (theContext->groupName() == ModelAPI_ResultBody::group()) {
      // do not select the whole shape for body:it is already must be in the data framework
      if (theContext->shape().get() && theContext->shape()->isEqual(theSubShape)) {
@@@ -209,12 -217,10 +216,12 @@@ bool Model_AttributeSelection::update(
    } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
      // construction: identification by the results indexes, recompute faces and
      // take the face that more close by the indexes
 -    std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr = 
 -      std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(
 -      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext)->shape());
 -    if (aWirePtr && aWirePtr->hasPlane()) { // sketch sub-element
 +    ResultConstructionPtr aConstructionContext = 
 +      std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
 +    // sketch sub-element
 +    if (aConstructionContext && 
 +        std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aContext).get())
 +    {
        TDF_Label aLab = myRef.myRef->Label();
        // getting a type of selected shape
        Handle(TDataStd_Integer) aTypeAttr;
  
        if (aShapeType == TopAbs_FACE) { // compound is for the whole sketch selection
          // If this is a wire with plane defined thin it is a sketch-like object
 -        std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
 -        GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
 -          aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
 -        if (aFaces.empty()) // no faces, update can not work correctly
 +        if (!aConstructionContext->facesNum()) // no faces, update can not work correctly
            return false;
          // if there is no edges indexes, any face can be used: take the first
          std::shared_ptr<GeomAPI_Shape> aNewSelected;
          if (aNoIndexes) {
 -          aNewSelected = *(aFaces.begin());
 +          aNewSelected = aConstructionContext->face(0);
          } else { // searching for most looks-like initial face by the indexes
            // prepare edges of the current resut for the fast searching
            TColStd_MapOfTransient allCurves;
                }
              }
            }
 -          // iterate new result faces and searching for these edges
 -          std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFacesIter = aFaces.begin();
            double aBestFound = 0; // best percentage of found edges
 -          for(; aFacesIter != aFaces.end(); aFacesIter++) {
 +          for(int aFaceIndex = 0; aFaceIndex < aConstructionContext->facesNum(); aFaceIndex++) {
              int aFound = 0, aNotFound = 0;
 -            TopExp_Explorer anEdgesExp((*aFacesIter)->impl<TopoDS_Shape>(), TopAbs_EDGE);
 +            TopExp_Explorer anEdgesExp(
 +              aConstructionContext->face(aFaceIndex)->impl<TopoDS_Shape>(), TopAbs_EDGE);
              for(; anEdgesExp.More(); anEdgesExp.Next()) {
                TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current());
                if (!anEdge.IsNull()) {
                double aPercentage = double(aFound) / double(aFound + aNotFound);
                if (aPercentage > aBestFound) {
                  aBestFound = aPercentage;
 -                aNewSelected = *aFacesIter;
 +                aNewSelected = aConstructionContext->face(aFaceIndex);
                }
              }
            }
index f4bc7f93e3e5aca6c75a8b88e3d620cbcc6ab5fd,f4bc7f93e3e5aca6c75a8b88e3d620cbcc6ab5fd..0cb74987a0e63c5a060f709a26142415cdce9834
@@@ -190,7 -190,7 +190,7 @@@ double SketchPlugin_Arc::distanceToPoin
  }
  
  bool SketchPlugin_Arc::isFixed() {
--  return data()->selection(EXTERNAL_ID())->context().get();
++  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
  }
  
  bool SketchPlugin_Arc::isFeatureValid()
index 50b387414b82402e10bec366908b2d2d856f24fa,50b387414b82402e10bec366908b2d2d856f24fa..934f40a04eb331cf8a0fb0a37ba044140e29b9c7
@@@ -101,7 -101,7 +101,7 @@@ double SketchPlugin_Circle::distanceToP
  }
  
  bool SketchPlugin_Circle::isFixed() {
--  return data()->selection(EXTERNAL_ID())->context().get();
++  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
  }
  
  void SketchPlugin_Circle::attributeChanged(const std::string& theID) {
index f0c76538a92ff0973a46813f32945c8299bf854c,f0c76538a92ff0973a46813f32945c8299bf854c..ea5d0a42b1e57039053e2a7ff2c63b1d0b34d0c5
@@@ -101,7 -101,7 +101,7 @@@ double SketchPlugin_Line::distanceToPoi
  }
  
  bool SketchPlugin_Line::isFixed() {
--  return data()->selection(EXTERNAL_ID())->context().get();
++  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
  }
  
  void SketchPlugin_Line::attributeChanged(const std::string& theID) {
index 798140611b2755a7b86248a055617fa84aed4e44,798140611b2755a7b86248a055617fa84aed4e44..036fde19db093340f6a632a0b73b2f860e7e26a7
@@@ -73,7 -73,7 +73,7 @@@ double SketchPlugin_Point::distanceToPo
  }
  
  bool SketchPlugin_Point::isFixed() {
--  return data()->selection(EXTERNAL_ID())->context().get();
++  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
  }
  
  void SketchPlugin_Point::attributeChanged(const std::string& theID) {
index 2736bd84806caec3856fbf9d6500ac61c84f5807,365db4ca69b59d5d4aca8311afa65980b1aca50a..b57c1e3ba21e7b587c0a4fd950c6a516fa3d082b
@@@ -46,7 -46,6 +46,6 @@@ void SketchPlugin_Sketch::initAttribute
  {
    data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::type());
    data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::type());
-   data()->addAttribute(SketchPlugin_Sketch::DIRY_ID(), GeomDataAPI_Dir::type());
    data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::type());
    data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::type());
    // the selected face, base for the sketcher plane, not obligatory
@@@ -66,8 -65,6 +65,6 @@@ void SketchPlugin_Sketch::execute(
        data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
        data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-   std::shared_ptr<GeomDataAPI_Dir> aDirY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-       data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
        data()->attribute(SketchPlugin_Sketch::NORM_ID()));
  
    for (; aShapeIt != aFeaturesPreview.end(); ++aShapeIt) {
      aBigWire->addEdge(*aShapeIt);
    }
-   aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aDirY->dir(), aNorm->dir());
+   aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aNorm->dir());
 -
 -//  GeomAlgoAPI_SketchBuilder::createFaces(anOrigin->pnt(), aDirX->dir(), aDirY->dir(), aNorm->dir(),
 -//                                         aFeaturesPreview, aLoops, aWires);
    std::shared_ptr<ModelAPI_ResultConstruction> aConstr = document()->createConstruction(data());
    aConstr->setShape(aBigWire);
    setResult(aConstr);
@@@ -195,13 -195,14 +192,14 @@@ std::shared_ptr<GeomAPI_Pnt> SketchPlug
  {
    std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
        data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+   std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+       data()->attribute(SketchPlugin_Sketch::NORM_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
        data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-   std::shared_ptr<GeomDataAPI_Dir> aY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-       data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
+   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
  
    std::shared_ptr<GeomAPI_XYZ> aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX))
-       ->added(aY->dir()->xyz()->multiplied(theY));
+       ->added(aY->xyz()->multiplied(theY));
  
    return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aSum));
  }
@@@ -211,11 -212,12 +209,12 @@@ std::shared_ptr<GeomAPI_Pnt2d> SketchPl
  {
    std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
        data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+   std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+       data()->attribute(SketchPlugin_Sketch::NORM_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
        data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-   std::shared_ptr<GeomDataAPI_Dir> aY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-       data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
-   return thePnt->to2D(aC->pnt(), aX->dir(), aY->dir());
+   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
+   return thePnt->to2D(aC->pnt(), aX->dir(), aY);
  }
  
  
@@@ -247,12 -249,10 +246,10 @@@ std::shared_ptr<GeomAPI_Ax3> SketchPlug
      aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
      aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
-   std::shared_ptr<GeomDataAPI_Dir> aY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-     aData->attribute(SketchPlugin_Sketch::DIRY_ID()));
    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
      aData->attribute(SketchPlugin_Sketch::NORM_ID()));
  
-   return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(aC->pnt(), aX->dir(), aY->dir(), aNorm->dir()));
+   return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(aC->pnt(), aX->dir(), aNorm->dir()));
  }
  
  void SketchPlugin_Sketch::erase()
@@@ -306,9 -306,6 +303,6 @@@ void SketchPlugin_Sketch::attributeChan
          std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
            data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
          aDirX->setValue(aXDir);
-         std::shared_ptr<GeomDataAPI_Dir> aDirY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-           data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
-         aDirY->setValue(aYDir);
          std::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
        }
      }