//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_CylinderDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ICylinder aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  gp_Pnt aP;
  gp_Vec aV;

  if (aType == CYLINDER_R_H) {
    aP = gp::Origin();
    aV = gp::DZ();
  }
  else if (aType == CYLINDER_PNT_VEC_R_H) {
    Handle(GEOM_Function) aRefPoint  = aCI.GetPoint();
    Handle(GEOM_Function) aRefVector = aCI.GetVector();
    TopoDS_Shape aShapePnt = aRefPoint->GetValue();
    TopoDS_Shape aShapeVec = aRefVector->GetValue();
    if (aShapePnt.IsNull() || aShapeVec.IsNull()) {
      Standard_NullObject::Raise("Cylinder creation aborted: point or vector is not defined");
    }
    if (aShapePnt.ShapeType() != TopAbs_VERTEX ||
        aShapeVec.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise("Cylinder creation aborted: point or vector shapes has wrong type");
    }

    aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));

    TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (V1.IsNull() || V2.IsNull()) {
      Standard_NullObject::Raise("Cylinder creation aborted: vector is not defined");
    }
    aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
  }
  else {
    return 0;
  }

  if (aCI.GetH() < 0.0) aV.Reverse();
  gp_Ax2 anAxes (aP, aV);

  BRepPrimAPI_MakeCylinder MC (anAxes, aCI.GetR(), Abs(aCI.GetH()));
  MC.Build();
  if (!MC.IsDone()) {
    StdFail_NotDone::Raise("Cylinder can't be computed from the given parameters");
  }

  TopoDS_Shape aShape = MC.Shape();
  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOM_SubShapeDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOM_ISubShape aCI (aFunction);

  TDF_Label aLabel = aCI.GetMainShape()->GetOwnerEntry();
  if (aLabel.IsRoot()) return 0;
  Handle(GEOM_Object) anObj = GEOM_Object::GetObject(aLabel);
  if (anObj.IsNull()) return 0;
  TopoDS_Shape aMainShape = anObj->GetValue();
  if (aMainShape.IsNull()) return 0;

  Handle(TColStd_HArray1OfInteger) anIndices = aCI.GetIndices();
  if (anIndices.IsNull() || anIndices->Length() <= 0) return 0;

  BRep_Builder B;
  TopoDS_Compound aCompound;
  TopoDS_Shape aShape;

  if (anIndices->Length() == 1 && anIndices->Value(1) == -1) { //The empty sub-shape
    B.MakeCompound(aCompound);
    aShape = aCompound;
  }
  else {
    TopTools_IndexedMapOfShape aMapOfShapes;
    TopExp::MapShapes(aMainShape, aMapOfShapes);

    if (anIndices->Length() > 1) {
      B.MakeCompound(aCompound);

      for (int i = anIndices->Lower(); i <= anIndices->Upper(); i++) {
        if (aMapOfShapes.Extent() < anIndices->Value(i))
          Standard_NullObject::Raise("GEOM_SubShapeDriver::Execute: Index is out of range");
        TopoDS_Shape aSubShape = aMapOfShapes.FindKey(anIndices->Value(i));
        if (aSubShape.IsNull()) continue;
        B.Add(aCompound,aSubShape);
      }

      aShape = aCompound;
    }
    else {
      int i = anIndices->Lower();
      if (aMapOfShapes.Extent() < anIndices->Value(i))
        Standard_NullObject::Raise("GEOM_SubShapeDriver::Execute: Index is out of range");
      aShape = aMapOfShapes.FindKey(anIndices->Value(i));
    }
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_BoxDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IBox aBI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == BOX_DX_DY_DZ) {
    BRepPrimAPI_MakeBox MB (aBI.GetDX(), aBI.GetDY(), aBI.GetDZ());
    MB.Build();

    if (!MB.IsDone()) {
      StdFail_NotDone::Raise("Box with the given dimensions can not be computed");
    }
    aShape = MB.Shape();
  }
  else if (aType == BOX_TWO_PNT) {
    Handle(GEOM_Function) aRefPoint1 = aBI.GetRef1();
    Handle(GEOM_Function) aRefPoint2 = aBI.GetRef2();
    TopoDS_Shape aShape1 = aRefPoint1->GetValue();
    TopoDS_Shape aShape2 = aRefPoint2->GetValue();
    if (aShape1.ShapeType() == TopAbs_VERTEX &&
        aShape2.ShapeType() == TopAbs_VERTEX) {
      gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
      gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));

      if (std::abs(P1.X() - P2.X()) < Precision::Confusion() || 
          std::abs(P1.Y() - P2.Y()) < Precision::Confusion() || 
          std::abs(P1.Z() - P2.Z()) < Precision::Confusion() ) {
        StdFail_NotDone::Raise("Box can not be created, the points belong both to one of the OXY, OYZ or OZX planes");
        return 0;
      }

      BRepPrimAPI_MakeBox MB (P1,P2);
      MB.Build();

      if (!MB.IsDone()) {
        StdFail_NotDone::Raise("Box can not be computed from the given point");
      }
      aShape = MB.Shape();
    }
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  if (aFunction.IsNull()) return 0;

  GEOMImpl_IHealing HI (aFunction);
  Standard_Integer aType = aFunction->GetType();
  Handle(GEOM_Function) anOriginalFunction = HI.GetOriginal();
  if (anOriginalFunction.IsNull()) return 0;
  TopoDS_Shape aShape, anOriginalShape = anOriginalFunction->GetValue();
  if (anOriginalShape.IsNull()) return 0;

  switch (aType)
  {
  case SHAPE_PROCESS:
    ShapeProcess(&HI, anOriginalShape, aShape);
    break;
  case SUPPRESS_FACES:
    SuppressFaces(&HI, anOriginalShape, aShape);
    break;
  case CLOSE_CONTOUR:
    CloseContour(&HI, anOriginalShape, aShape);
    break;
  case REMOVE_INT_WIRES:
    RemoveIntWires(&HI, anOriginalShape, aShape);
    break;
  case FILL_HOLES:
    RemoveHoles(&HI, anOriginalShape, aShape);
    break;
  case SEWING:
    Sew(&HI, anOriginalShape, aShape);
    break;
  case DIVIDE_EDGE:
    AddPointOnEdge(&HI, anOriginalShape, aShape);
    break;
  case CHANGE_ORIENTATION:
    ChangeOrientation(&HI, anOriginalShape, aShape);
    break;
  case LIMIT_TOLERANCE:
    LimitTolerance(&HI, anOriginalShape, aShape);
    break;
  default:
    return 0;
  }

  if (aShape.IsNull())
    raiseNotDoneExeption( ShHealOper_ErrorExecution );

  aFunction->SetValue(aShape);

  log.SetTouched(Label());
  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_TorusDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ITorus aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == TORUS_RR) {
    aShape = BRepPrimAPI_MakeTorus(aCI.GetRMajor(), aCI.GetRMinor()).Shape();

  } else if (aType == TORUS_PNT_VEC_RR) {
    Handle(GEOM_Function) aRefPoint  = aCI.GetCenter();
    Handle(GEOM_Function) aRefVector = aCI.GetVector();
    TopoDS_Shape aShapePnt = aRefPoint->GetValue();
    TopoDS_Shape aShapeVec = aRefVector->GetValue();
    if (aShapePnt.ShapeType() != TopAbs_VERTEX) {
      Standard_TypeMismatch::Raise("Torus Center must be a vertex");
    }
    if (aShapeVec.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise("Torus Axis must be an edge");
    }

    gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
    TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (V1.IsNull() || V2.IsNull()) {
      Standard_ConstructionError::Raise("Bad edge for the Torus Axis given");
    }

    gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
    if (aV.Magnitude() < Precision::Confusion()) {
      Standard_ConstructionError::Raise
        ("End vertices of edge, defining the Torus Axis, are too close");
    }

    gp_Ax2 anAxes (aP, aV);
    BRepPrimAPI_MakeTorus MT (anAxes, aCI.GetRMajor(), aCI.GetRMinor());
    if (!MT.IsDone()) MT.Build();
    if (!MT.IsDone()) StdFail_NotDone::Raise("Torus construction algorithm has failed");
    aShape = MT.Shape();
  } else {
  }

  if (aShape.IsNull()) return 0;
  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_SphereDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ISphere aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  char aMsg[] = "Sphere creation aborted: radius value less than 1e-07 is not acceptable";

  double theAngle = aCI.GetAngle();
  if (theAngle == 0.)
	theAngle = PI * 2.;

  double theVCoordStart = aCI.GetVCoordStart();
  double theVCoordEnd = aCI.GetVCoordEnd();

  if (aType == SPHERE_R) {
    double anR = aCI.GetR();
    if (anR < Precision::Confusion())
      Standard_ConstructionError::Raise(aMsg);

    //There seems to be an issue with the  BRepPrimAPI_MakeSphere command concerning
    //the limitations on V coodinates of its parametric space ... (Will not be used for the moment)
    aShape = BRepPrimAPI_MakeSphere(anR /*, theVCoordStart, theVCoordEnd*/ , theAngle).Shape();
  }
  else if (aType == SPHERE_PNT_R) {

    double anR = aCI.GetR();
    if (anR < Precision::Confusion())
      Standard_ConstructionError::Raise(aMsg);

    Handle(GEOM_Function) aRefPoint  = aCI.GetPoint();
    TopoDS_Shape aShapePnt = aRefPoint->GetValue();

    if (aShapePnt.ShapeType() != TopAbs_VERTEX)
      Standard_ConstructionError::Raise("Invalid shape given for sphere center: it must be a point");

    gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
    aShape = BRepPrimAPI_MakeSphere(aP, anR/*, theVCoordStart, theVCoordEnd*/, theAngle).Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_SphereDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ISphere aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  char aMsg[] = "Sphere creation aborted: radius value less than 1e-07 is not acceptable";

  if (aType == SPHERE_R) {
    double anR = aCI.GetR();
    if (anR < Precision::Confusion())
      Standard_ConstructionError::Raise(aMsg);

    aShape = BRepPrimAPI_MakeSphere(anR).Shape();
  }
  else if (aType == SPHERE_PNT_R) {
    double anR = aCI.GetR();
    if (anR < Precision::Confusion())
      Standard_ConstructionError::Raise(aMsg);

    Handle(GEOM_Function) aRefPoint  = aCI.GetPoint();
    TopoDS_Shape aShapePnt = aRefPoint->GetValue();
    if (aShapePnt.ShapeType() != TopAbs_VERTEX)
      Standard_ConstructionError::Raise("Invalid shape given for sphere center: it must be a point");
    gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));

    aShape = BRepPrimAPI_MakeSphere(aP, anR).Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ICircle aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == CIRCLE_PNT_VEC_R) {
    // Center
    gp_Pnt aP = gp::Origin();
    Handle(GEOM_Function) aRefPoint = aCI.GetCenter();
    if (!aRefPoint.IsNull()) {
      TopoDS_Shape aShapePnt = aRefPoint->GetValue();
      if (aShapePnt.ShapeType() != TopAbs_VERTEX) {
        Standard_ConstructionError::Raise
          ("Circle creation aborted: invalid center argument, must be a point");
      }
      aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
    }
    // Normal
    gp_Vec aV = gp::DZ();
    Handle(GEOM_Function) aRefVector = aCI.GetVector();
    if (!aRefVector.IsNull()) {
      TopoDS_Shape aShapeVec = aRefVector->GetValue();
      if (aShapeVec.ShapeType() != TopAbs_EDGE) {
        Standard_ConstructionError::Raise
          ("Circle creation aborted: invalid vector argument, must be a vector or an edge");
      }
      TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
      TopoDS_Vertex V1, V2;
      TopExp::Vertices(anE, V1, V2, Standard_True);
      if (!V1.IsNull() && !V2.IsNull()) {
        aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
        if (aV.Magnitude() < gp::Resolution()) {
          Standard_ConstructionError::Raise
            ("Circle creation aborted: vector of zero length is given");
        }
      }
    }
    // Axes
    gp_Ax2 anAxes (aP, aV);

    // Radius
    double anR = aCI.GetRadius();
    char aMsg[] = "Circle creation aborted: radius value less than 1e-07 is not acceptable";
    if (anR < Precision::Confusion())
      Standard_ConstructionError::Raise(aMsg);

    // Circle
    gp_Circ aCirc (anAxes, anR);
    aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge();
  }
  else if (aType == CIRCLE_CENTER_TWO_PNT) {
    Handle(GEOM_Function) aRefPoint1 = aCI.GetPoint1();
    Handle(GEOM_Function) aRefPoint2 = aCI.GetPoint2();
    Handle(GEOM_Function) aRefPoint3 = aCI.GetPoint3();
    TopoDS_Shape aShapePnt1 = aRefPoint1->GetValue();
    TopoDS_Shape aShapePnt2 = aRefPoint2->GetValue();
    TopoDS_Shape aShapePnt3 = aRefPoint3->GetValue();
    if (aShapePnt1.ShapeType() == TopAbs_VERTEX &&
        aShapePnt2.ShapeType() == TopAbs_VERTEX &&
        aShapePnt3.ShapeType() == TopAbs_VERTEX)
    {
      gp_Pnt aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt1));
      gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt2));
      gp_Pnt aP3 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt3));

      if (aP1.Distance(aP2) < gp::Resolution() ||
          aP1.Distance(aP3) < gp::Resolution() ||
          aP2.Distance(aP3) < gp::Resolution())
        Standard_ConstructionError::Raise("Circle creation aborted: coincident points given");

      if (gp_Vec(aP1, aP2).IsParallel(gp_Vec(aP1, aP3), Precision::Angular()))
        Standard_ConstructionError::Raise("Circle creation aborted: points lay on one line");

      double x, y, z, x1, y1, z1, x2, y2, z2, dx, dy, dz, dx2, dy2, dz2, dx3, dy3, dz3, aRadius;
      //Calculations for Radius
      x = aP1.X(); y = aP1.Y(); z = aP1.Z();
      x1 = aP2.X(); y1 = aP2.Y(); z1 = aP2.Z();
      dx = x1 - x;
      dy = y1 - y;
      dz = z1 - z;
      aRadius = sqrt(dx*dx + dy*dy + dz*dz);
      //Calculations for Plane Vector
      x2 = aP3.X(); y2 = aP3.Y(); z2 = aP3.Z();
      dx2 = x2 - x; dy2 = y2 - y; dz2 = z2 - z;
      dx3 = ((dy*dz2) - (dy2*dz))/100;
      dy3 = ((dx2*dz) - (dx*dz2))/100;
      dz3 = ((dx*dy2) - (dx2*dy))/100;
      //Make Plane Vector
      gp_Dir aDir ( dx3, dy3, dz3 );
      //Make Circle
      gp_Ax2 anAxes (aP1, aDir);
      gp_Circ aCirc (anAxes, aRadius);
      aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge();  
    }
  }
  else if (aType == CIRCLE_THREE_PNT) {
    Handle(GEOM_Function) aRefPoint1 = aCI.GetPoint1();
    Handle(GEOM_Function) aRefPoint2 = aCI.GetPoint2();
    Handle(GEOM_Function) aRefPoint3 = aCI.GetPoint3();
    TopoDS_Shape aShapePnt1 = aRefPoint1->GetValue();
    TopoDS_Shape aShapePnt2 = aRefPoint2->GetValue();
    TopoDS_Shape aShapePnt3 = aRefPoint3->GetValue();
    if (aShapePnt1.ShapeType() == TopAbs_VERTEX &&
        aShapePnt2.ShapeType() == TopAbs_VERTEX &&
        aShapePnt3.ShapeType() == TopAbs_VERTEX) {
      gp_Pnt aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt1));
      gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt2));
      gp_Pnt aP3 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt3));
      if (aP1.Distance(aP2) < gp::Resolution() ||
          aP1.Distance(aP3) < gp::Resolution() ||
          aP2.Distance(aP3) < gp::Resolution())
        Standard_ConstructionError::Raise("Circle creation aborted: coincident points given");
      if (gp_Vec(aP1, aP2).IsParallel(gp_Vec(aP1, aP3), Precision::Angular()))
        Standard_ConstructionError::Raise("Circle creation aborted: points lay on one line");
      Handle(Geom_Circle) aCirc = GC_MakeCircle(aP1, aP2, aP3).Value();
      aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge();
    }  
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_DraftDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
  if(aFunction.IsNull()) return 0;

  GEOMImpl_IDraft aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;
  TopoDS_Shape aPlaneShape;

  gp_Pln theNeutralPlane;
  gp_Dir theDirection;

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShapeBase = aRefShape->GetValue();

  //get the reference plane and direction
  if (aType == DRAFT_BY_FACE_PLN_ANG) {
	Handle(GEOM_Function) aRefPlane = aCI.GetPlane();
	if (aRefPlane.IsNull())
	  return 0;
	aPlaneShape = aRefPlane->GetValue();
  }
  else if (aType == DRAFT_BY_FACE_STA_ANG) {
	GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetStationary(), aPlaneShape);
  }
  if (aPlaneShape.IsNull() || aPlaneShape.ShapeType() != TopAbs_FACE)
	return 0;

  TopoDS_Face aFace = TopoDS::Face(aPlaneShape);

  Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
  Handle(Geom_Plane) myPlane = Handle(Geom_Plane)::DownCast(surf);

  theNeutralPlane = myPlane->Pln();
  theDirection = theNeutralPlane.Axis().Direction();

  //compute the value
  Standard_Real theAngle = aCI.GetAngle();

  int aLen = aCI.GetLength();
  int ind = 1;
  int added = 0;

  BRepOffsetAPI_DraftAngle aDraft (aShapeBase);

  for (; ind <= aLen; ind++) {
	TopoDS_Shape aShapeFace;
	if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace)) {
	  TopoDS_Face aFace = TopoDS::Face(aShapeFace);
	  aDraft.Add(aFace, theDirection, theAngle, theNeutralPlane);
	  if (aDraft.AddDone())
		added++;
	  else
		aDraft.Remove(aFace);
	}
  }
  if (added == 0)
	StdFail_NotDone::Raise("None of the faces provided can be used for draft algo");

  aDraft.Build();

  if (!aDraft.IsDone()) {
	StdFail_NotDone::Raise("Draft can't be computed on the given shape with the given parameters");
  }
  aShape = aDraft.Shape();

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
	Standard_CString anErrStr("Draft algorythm has produced an invalid shape result");
	#ifdef THROW_ON_INVALID_SH
	  Standard_ConstructionError::Raise(anErrStr);
	#else
	  MESSAGE(anErrStr);
	  //further processing can be performed here
	  //...
	  //in case of failure of automatic treatment
	  //mark the corresponding GEOM_Object as problematic
	  TDF_Label aLabel = aFunction->GetOwnerEntry();
	  if (!aLabel.IsRoot()) {
		Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
		if (!aMainObj.IsNull())
		  aMainObj->SetDirty(Standard_True);
	  }
	#endif
  }
  aFunction->SetValue(aShape);
  log.SetTouched(Label());
  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IChamfer aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShapeBase = aRefShape->GetValue();



  if (aType == CHAMFER_SHAPE_EDGES_2D)
  {
	BRepFilletAPI_MakeFillet2d fill;
	TopoDS_Face aFace;

	Standard_Boolean aWireFlag = Standard_False;
	
	if (aShapeBase.ShapeType() == TopAbs_FACE)
		aFace = TopoDS::Face(aShapeBase);
	else if (aShapeBase.ShapeType() == TopAbs_WIRE)
	{
		TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
		BRepBuilderAPI_MakeFace aMF(aWire);
		aMF.Build();
		if (!aMF.IsDone()) {
			StdFail_NotDone::Raise("Cannot build initial face from given wire");
		}
		aFace = aMF.Face();
		aWireFlag = Standard_True;
	}
	else
		StdFail_NotDone::Raise("Base shape is neither a face or a wire !");

	fill.Init(aFace);

	double aD1_2D = aCI.GetD1();
	double aD2_2D = aCI.GetD2();

	TopoDS_Shape aShapeFace1, aShapeFace2;

	if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge1(), aShapeFace1) &&
		GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge2(), aShapeFace2))
	{
		fill.AddChamfer(TopoDS::Edge(aShapeFace1), TopoDS::Edge(aShapeFace2), aD1_2D, aD2_2D);
	}
	else
		StdFail_NotDone::Raise("Cannot get 2d egde from sub-shape index!");

	fill.Build();
	if (!fill.IsDone()) {
		StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
	}
	if (aWireFlag)
	{
		BRepBuilderAPI_MakeWire MW;
		TopExp_Explorer exp (fill.Shape(), TopAbs_EDGE);
		for (; exp.More(); exp.Next())
			MW.Add(TopoDS::Edge(exp.Current()));
		MW.Build();
		if (!MW.IsDone())
			StdFail_NotDone::Raise("Resulting wire cannot be built");
			
		aShape = MW.Shape();
	}
	else
		aShape = fill.Shape();
  }
  else
  {
	  // Check the shape type. It have to be shell
	  // or solid, or compsolid, or compound of these shapes.
	  if (!isGoodForChamfer(aShapeBase)) {
		StdFail_NotDone::Raise
		  ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
	  }

	  BRepFilletAPI_MakeChamfer fill (aShapeBase);

	  if (aType == CHAMFER_SHAPE_ALL) {
		// symmetric chamfer on all edges
		double aD = aCI.GetD();
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (int i = 1; i <= M.Extent(); i++) {
		  TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
		  TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
		  if (!BRepTools::IsReallyClosed(E, F) &&
			  !BRep_Tool::Degenerated(E) &&
			  M.FindFromIndex(i).Extent() == 2)
			fill.Add(aD, E, F);
		}
	  }else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
		// chamfer on edges, common to two faces, with D1 on the first face

		TopoDS_Shape aFace1, aFace2;
		if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
			GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
		  {
		TopoDS_Face F = TopoDS::Face(aFace1);

		// fill map of edges of the second face
		TopTools_MapOfShape aMap;
		TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
		for (; Exp2.More(); Exp2.Next()) {
		  aMap.Add(Exp2.Current());
		}
	
		// find edges of the first face, common with the second face
		TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
		for (; Exp.More(); Exp.Next()) {
		  if (aMap.Contains(Exp.Current())) {
			TopoDS_Edge E = TopoDS::Edge(Exp.Current());
			if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
			  {
			if ( aType == CHAMFER_SHAPE_EDGE )
			  {
				double aD1 = aCI.GetD1();
				double aD2 = aCI.GetD2();
				fill.Add(aD1, aD2, E, F);
			  }
			else
			  {
				double aD = aCI.GetD();
				double anAngle = aCI.GetAngle();
				if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
				  fill.AddDA(aD, anAngle, E, F);
			  }
			  }
		  }
		}
		  }
	  }
	  else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
		// chamfer on all edges of the selected faces, with D1 on the selected face
		// (on first selected face, if the edge belongs to two selected faces)

		int aLen = aCI.GetLength();
		int ind = 1;
		TopTools_MapOfShape aMap;
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (; ind <= aLen; ind++)
		{
		  TopoDS_Shape aShapeFace;
		  if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
		{
		  TopoDS_Face F = TopoDS::Face(aShapeFace);
		  TopExp_Explorer Exp (F, TopAbs_EDGE);
		  for (; Exp.More(); Exp.Next()) {
			if (!aMap.Contains(Exp.Current()))
			  {
			TopoDS_Edge E = TopoDS::Edge(Exp.Current());
			if (!BRepTools::IsReallyClosed(E, F) &&
				!BRep_Tool::Degenerated(E) &&
				M.FindFromKey(E).Extent() == 2)
			  if (aType == CHAMFER_SHAPE_FACES)
				{
				  double aD1 = aCI.GetD1();
				  double aD2 = aCI.GetD2();
				  fill.Add(aD1, aD2, E, F);
				}
			  else
				{
				  double aD = aCI.GetD();
				  double anAngle = aCI.GetAngle();
				  if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
				fill.AddDA(aD, anAngle, E, F);
				}
			  }
		  }
		}
		}
	  }
	else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
	  {
		// chamfer on selected edges with lenght param D1 & D2.

		int aLen = aCI.GetLength();
		int ind = 1;
		TopTools_MapOfShape aMap;
		TopTools_IndexedDataMapOfShapeListOfShape M;
		GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
		for (; ind <= aLen; ind++)
		{
		  TopoDS_Shape aShapeEdge;
		  if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
		{
		  TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
		  const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
		  TopoDS_Face F = TopoDS::Face( aFacesList.First() );
		  if (aType == CHAMFER_SHAPE_EDGES)
			{
			  double aD1 = aCI.GetD1();
			  double aD2 = aCI.GetD2();
			  fill.Add(aD1, aD2, E, F);
			}
		  else
			{
			  double aD = aCI.GetD();
			  double anAngle = aCI.GetAngle();
			  if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) )
			fill.AddDA(aD, anAngle, E, F);
			}
		}
		}
	  }
	  else {
	  }

	  fill.Build();
	  if (!fill.IsDone()) {
		StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
	  }
	  aShape = fill.Shape();
  }

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
  	// 08.07.2008 added by skl during fixing bug 19761 from Mantis
	ShapeFix_ShapeTolerance aSFT;
	aSFT.LimitTolerance(aShape, Precision::Confusion(),
						Precision::Confusion(), TopAbs_SHAPE);
	Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
	aSfs->Perform();
	aShape = aSfs->Shape();

    // fix SameParameter flag
    BRepLib::SameParameter(aShape, 1.E-5, Standard_True);

	ana.Init(aShape);
	if (!ana.IsValid()) {
	  Standard_CString anErrStr("Chamfer algorithm has produced an invalid shape result");
	  #ifdef THROW_ON_INVALID_SH
		Standard_ConstructionError::Raise(anErrStr);
	  #else
		MESSAGE(anErrStr);
		//further processing can be performed here
		//...
		//in case of failure of automatic treatment
		//mark the corresponding GEOM_Object as problematic
		TDF_Label aLabel = aFunction->GetOwnerEntry();
		if (!aLabel.IsRoot()) {
		  Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
		  if (!aMainObj.IsNull())
			aMainObj->SetDirty(Standard_True);
		}
	  #endif
	}
  }

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_ScaleDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IScale aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == SCALE_SHAPE || aType == SCALE_SHAPE_COPY) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    if (aShapeBase.IsNull()) return 0;

    gp_Pnt aP (0,0,0);
    Handle(GEOM_Function) aRefPoint = aCI.GetPoint();
    if (!aRefPoint.IsNull()) {
      TopoDS_Shape aShapePnt = aRefPoint->GetValue();
      if (aShapePnt.IsNull()) return 0;
      if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0;
      aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
    }

    // Bug 6839: Check for standalone (not included in faces) degenerated edges
    TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
    TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
    Standard_Integer i, nbE = aEFMap.Extent();
    for (i = 1; i <= nbE; i++) {
      TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
      if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
        const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
        if (aFaces.IsEmpty())
          Standard_ConstructionError::Raise
            ("Scaling aborted : cannot scale standalone degenerated edge");
      }
    }

    // Perform Scaling
    gp_Trsf aTrsf;
    aTrsf.SetScale(aP, aCI.GetFactor());
    BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
	aShape = aBRepTrsf.Shape();
  }
  else if (aType == SCALE_SHAPE_AFFINE || aType == SCALE_SHAPE_AFFINE_COPY) {
	Handle(GEOM_Function) aRefShape = aCI.GetShape();
	Handle(GEOM_Function) aRefVector = aCI.GetVector();
	TopoDS_Shape aShapeBase = aRefShape->GetValue();
	TopoDS_Shape aShapeVector  = aRefVector->GetValue();
	if (aShapeBase.IsNull() || aShapeVector.IsNull()) return 0;
	if (aShapeVector.ShapeType() != TopAbs_EDGE) return 0;
	TopoDS_Edge anEdgeVector = TopoDS::Edge(aShapeVector);

	// Bug 6839: Check for standalone (not included in faces) degenerated edges
	TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
	TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
	Standard_Integer i, nbE = aEFMap.Extent();
	for (i = 1; i <= nbE; i++) {
	  TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
	  if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
		const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
		if (aFaces.IsEmpty())
		  Standard_ConstructionError::Raise
			("Scaling aborted : cannot scale standalone degenerated edge");
	  }
	}

	//Get axis
	gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdgeVector));
	gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdgeVector));
    gp_Dir aDir(gp_Vec(aP1, aP2));
	gp_Ax2 anAx2(aP1, aDir);

	// Perform Scaling
	gp_GTrsf aGTrsf;
	aGTrsf.SetAffinity(anAx2, aCI.GetFactor());
	BRepBuilderAPI_GTransform aBRepGTrsf(aShapeBase, aGTrsf, Standard_False);
	aShape = aBRepGTrsf.Shape();
  }
  else if (aType == SCALE_SHAPE_AXES || aType == SCALE_SHAPE_AXES_COPY) {
	Handle(GEOM_Function) aRefShape = aCI.GetShape();
    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    if (aShapeBase.IsNull()) return 0;

    bool isP = false;
    gp_Pnt aP (0,0,0);
    Handle(GEOM_Function) aRefPoint = aCI.GetPoint();
    if (!aRefPoint.IsNull()) {
      TopoDS_Shape aShapePnt = aRefPoint->GetValue();
      if (aShapePnt.IsNull()) return 0;
      if (aShapePnt.ShapeType() != TopAbs_VERTEX) return 0;
      aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
      isP = true;
    }

    // Bug 6839: Check for standalone (not included in faces) degenerated edges
    TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
    TopExp::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
    Standard_Integer i, nbE = aEFMap.Extent();
    for (i = 1; i <= nbE; i++) {
      TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
      if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
        const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
        if (aFaces.IsEmpty())
          Standard_ConstructionError::Raise
            ("Scaling aborted : cannot scale standalone degenerated edge");
      }
    }

    // Perform Scaling
    gp_GTrsf aGTrsf;
    gp_Mat rot (aCI.GetFactorX(), 0, 0,
                0, aCI.GetFactorY(), 0,
                0, 0, aCI.GetFactorZ());
    aGTrsf.SetVectorialPart(rot);

    if (isP) {
      gp_Pnt anO (0,0,0);
      if (anO.Distance(aP) > Precision::Confusion()) {
        gp_GTrsf aGTrsfP0;
        aGTrsfP0.SetTranslationPart(anO.XYZ() - aP.XYZ());
        gp_GTrsf aGTrsf0P;
        aGTrsf0P.SetTranslationPart(aP.XYZ());
        //aGTrsf = aGTrsf0P * aGTrsf * aGTrsfP0;
        aGTrsf = aGTrsf0P.Multiplied(aGTrsf);
        aGTrsf = aGTrsf.Multiplied(aGTrsfP0);
      }
    }

    BRepBuilderAPI_GTransform aBRepGTrsf (aShapeBase, aGTrsf, Standard_False);
    if (!aBRepGTrsf.IsDone())
      Standard_ConstructionError::Raise("Scaling not done");
	aShape = aBRepGTrsf.Shape();
  } else {
  }

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
    ShapeFix_ShapeTolerance aSFT;
    aSFT.LimitTolerance(aShape,Precision::Confusion(),Precision::Confusion());
    Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
    aSfs->SetPrecision(Precision::Confusion());
    aSfs->Perform();
    aShape = aSfs->Shape();

    ana.Init(aShape, Standard_False);
	if (!ana.IsValid()) {
	  Standard_CString anErrStr("Scaling aborted : non valid shape result");
	  #ifdef THROW_ON_INVALID_SH
		Standard_ConstructionError::Raise(anErrStr);
	  #else
	  MESSAGE(anErrStr);
	  //further processing can be performed here
		//...
	  //in case of failure of automatic treatment
	  //mark the corresponding GEOM_Object as problematic
	  TDF_Label aLabel = aFunction->GetOwnerEntry();
	  if (!aLabel.IsRoot()) {
		Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
		if (!aMainObj.IsNull())
		  aMainObj->SetDirty(Standard_True);
	  }
	  #endif
	}
  }

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_MarkerDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull())  return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IMarker aPI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == MARKER_CS) {
    double OX, OY, OZ;
    double XDX, XDY, XDZ;
    double YDX, YDY, YDZ;
    aPI.GetOrigin(OX, OY, OZ);
    aPI.GetXDir(XDX, XDY, XDZ);
    aPI.GetYDir(YDX, YDY, YDZ);

    gp_Pnt aPO (OX, OY, OZ);
    gp_Vec aVX (XDX, XDY, XDZ);
    gp_Vec aVY (YDX, YDY, YDZ);
    Standard_Real aTol = Precision::Confusion();
    if (aVX.Magnitude() < aTol ||
        aVY.Magnitude() < aTol ||
        aVX.IsParallel(aVY, Precision::Angular())) {
      Standard_ConstructionError::Raise("Degenerated or parallel directions given");
    }

    gp_Vec aN = aVX ^ aVY;
    gp_Ax3 anA (aPO, aN, aVX);
    gp_Pln aPln (anA);

    double aTrimSize = 100.0;
    aShape = BRepBuilderAPI_MakeFace(aPln, -aTrimSize, +aTrimSize, -aTrimSize, +aTrimSize).Shape();
  } else if (aType == MARKER_SHAPE) {
    Handle(GEOM_Function) aRefShape = aPI.GetShape();
    TopoDS_Shape aSh = aRefShape->GetValue();
    gp_Ax3 anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aSh);
    gp_Pln aPln (anAx3);

    double aTrimSize = 100.0;
    aShape = BRepBuilderAPI_MakeFace(aPln, -aTrimSize, +aTrimSize, -aTrimSize, +aTrimSize).Shape();
  } else if (aType == MARKER_PNT2VEC) {
    Handle(GEOM_Function) aRefOrigin  = aPI.GetOrigin();
    Handle(GEOM_Function) aRefXVec = aPI.GetXVec();
    Handle(GEOM_Function) aRefYVec = aPI.GetYVec();
    TopoDS_Shape aShapeOrigin = aRefOrigin->GetValue();
    TopoDS_Shape aShapeXVec = aRefXVec->GetValue();
    TopoDS_Shape aShapeYVec = aRefYVec->GetValue();
    if (aShapeOrigin.ShapeType() != TopAbs_VERTEX || aShapeOrigin.IsNull()) return 0;
    if (aShapeXVec.ShapeType() != TopAbs_EDGE || aShapeXVec.IsNull()) return 0;
    if (aShapeYVec.ShapeType() != TopAbs_EDGE || aShapeYVec.IsNull()) return 0;

    gp_Pnt aPO = BRep_Tool::Pnt( TopoDS::Vertex( aShapeOrigin ) );

    gp_Pnt aPX1 = BRep_Tool::Pnt( TopExp::FirstVertex( TopoDS::Edge( aShapeXVec ) ) );
    gp_Pnt aPX2 = BRep_Tool::Pnt( TopExp::LastVertex( TopoDS::Edge( aShapeXVec ) ) );
    gp_Vec aVX( aPX1, aPX2 );

    gp_Pnt aPY1 = BRep_Tool::Pnt( TopExp::FirstVertex( TopoDS::Edge( aShapeYVec ) ) );
    gp_Pnt aPY2 = BRep_Tool::Pnt( TopExp::LastVertex( TopoDS::Edge( aShapeYVec ) ) );
    gp_Vec aVY( aPY1, aPY2 );

    if (aVX.Magnitude() < gp::Resolution() || aVY.Magnitude() < gp::Resolution())
        Standard_ConstructionError::Raise
          ("Local CS creation aborted: vector of zero length is given");

    if ( aVX.IsParallel(aVY, Precision::Angular()))
      Standard_ConstructionError::Raise("Parallel Vectors given");
    
    gp_Vec aN = aVX ^ aVY;
    gp_Ax3 anA (aPO, aN, aVX);
    gp_Pln aPln (anA);
    
    double aTrimSize = 100.0;
    aShape = BRepBuilderAPI_MakeFace(aPln, -aTrimSize, +aTrimSize, -aTrimSize, +aTrimSize).Shape();
  } else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IMeasure aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == CDG_MEASURE)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase);
    gp_Pnt aCenterMass = aPos.Location();
    aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
  }
  else if (aType == VERTEX_BY_INDEX)
  {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Shape for centre of mass calculation is null");
    }

    int index = aCI.GetIndex();
    gp_Pnt aVertex;

    if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
      if ( index != 1 )
        Standard_NullObject::Raise("Vertex index is out of range");
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase));
    } else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
      TopoDS_Vertex aV1, aV2;
      TopoDS_Edge anEdgeE = TopoDS::Edge(aShapeBase);
      
      TopExp::Vertices(anEdgeE, aV1, aV2);
      gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
      gp_Pnt aP2 = BRep_Tool::Pnt(aV2);

      if (index < 0 || index > 1)
        Standard_NullObject::Raise("Vertex index is out of range");

      if ( ( anEdgeE.Orientation() == TopAbs_FORWARD && index == 0 ) ||
           ( anEdgeE.Orientation() == TopAbs_REVERSED && index == 1 ) )
        aVertex = aP1;
      else
      aVertex = aP2;
    } else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
      TopTools_IndexedMapOfShape anEdgeShapes;
      TopTools_IndexedMapOfShape aVertexShapes;
      TopoDS_Vertex aV1, aV2;
      TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
      TopExp_Explorer exp (aWire, TopAbs_EDGE);
      for (; exp.More(); exp.Next()) {
        anEdgeShapes.Add(exp.Current());
        TopoDS_Edge E = TopoDS::Edge(exp.Current());
        TopExp::Vertices(E, aV1, aV2);
        if ( aVertexShapes.Extent() == 0)
          aVertexShapes.Add(aV1);
        if ( !aV1.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV1);
        if ( !aV2.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
          aVertexShapes.Add(aV2);
      }

      if (index < 0 || index > aVertexShapes.Extent())
        Standard_NullObject::Raise("Vertex index is out of range");

      if (aWire.Orientation() == TopAbs_FORWARD)
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(index+1)));
      else
        aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(aVertexShapes.Extent() - index)));
    } else {
      Standard_NullObject::Raise("Shape for vertex calculation is not an edge or wire");
    }

    aShape = BRepBuilderAPI_MakeVertex(aVertex).Shape();
  }
  else if (aType == VECTOR_FACE_NORMALE)
  {
    // Face
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull()) {
      Standard_NullObject::Raise("Face for normale calculation is null");
    }
    if (aShapeBase.ShapeType() != TopAbs_FACE) {
      Standard_NullObject::Raise("Shape for normale calculation is not a face");
    }
    TopoDS_Face aFace = TopoDS::Face(aShapeBase);

    // Point
    gp_Pnt p1 (0,0,0);

    Handle(GEOM_Function) aPntFunc = aCI.GetPoint();
    if (!aPntFunc.IsNull())
    {
      TopoDS_Shape anOptPnt = aPntFunc->GetValue();
      if (anOptPnt.IsNull())
        Standard_NullObject::Raise("Invalid shape given for point argument");
      p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt));
    }
    else
    {
      gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace);
      p1 = aPos.Location();
    }

    // Point parameters on surface
    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
    Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
    gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion());

    // Normal direction
    gp_Vec Vec1,Vec2;
    BRepAdaptor_Surface SF (aFace);
    SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2);
    if (Vec1.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X(), pUV.Y()-0.1, tmpP, Vec1, tmpV);
    }
    else if (Vec2.Magnitude() < Precision::Confusion()) {
      gp_Vec tmpV;
      gp_Pnt tmpP;
      SF.D1(pUV.X()-0.1, pUV.Y(), tmpP, tmpV, Vec2);
    }

    gp_Vec V = Vec1.Crossed(Vec2);
    Standard_Real mod = V.Magnitude();
    if (mod < Precision::Confusion())
      Standard_NullObject::Raise("Normal vector of a face has null magnitude");

    // Set length of normal vector to average radius of curvature
    Standard_Real radius = 0.0;
    GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion());
    if (aProperties.IsCurvatureDefined()) {
      Standard_Real radius1 = Abs(aProperties.MinCurvature());
      Standard_Real radius2 = Abs(aProperties.MaxCurvature());
      if (Abs(radius1) > Precision::Confusion()) {
        radius = 1.0 / radius1;
        if (Abs(radius2) > Precision::Confusion()) {
          radius = (radius + 1.0 / radius2) / 2.0;
        }
      }
      else {
        if (Abs(radius2) > Precision::Confusion()) {
          radius = 1.0 / radius2;
        }
      }
    }

    // Set length of normal vector to average dimension of the face
    // (only if average radius of curvature is not appropriate)
    if (radius < Precision::Confusion()) {
        Bnd_Box B;
        Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
        BRepBndLib::Add(aFace, B);
        B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
        radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0;
    }

    if (radius < Precision::Confusion())
      radius = 1.0;

    V *= radius / mod;

    // consider the face orientation
    if (aFace.Orientation() == TopAbs_REVERSED ||
        aFace.Orientation() == TopAbs_INTERNAL) {
      V = - V;
    }

    // Edge
    gp_Pnt p2 = p1.Translated(V);
    BRepBuilderAPI_MakeEdge aBuilder (p1, p2);
    if (!aBuilder.IsDone())
      Standard_NullObject::Raise("Vector construction failed");
    aShape = aBuilder.Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_PositionDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IPosition aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == POSITION_SHAPE || aType == POSITION_SHAPE_COPY) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aRefStartLCS = aCI.GetStartLCS();
    Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS();

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aShapeStartLCS = aRefStartLCS->GetValue();
    TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue();

    if (aShapeBase.IsNull() || aShapeStartLCS.IsNull() ||
        aShapeEndLCS.IsNull() || aShapeEndLCS.ShapeType() != TopAbs_FACE)
      return 0;

    gp_Trsf aTrsf;
    gp_Ax3 aStartAx3, aDestAx3;

    // End LCS
    aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS);

    // Start LCS
    aStartAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeStartLCS);

    // Set transformation
    aTrsf.SetDisplacement(aStartAx3, aDestAx3);

    // Perform transformation
    BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
    aShape = aBRepTrsf.Shape();
  }
  else if (aType == POSITION_SHAPE_FROM_GLOBAL ||
           aType == POSITION_SHAPE_FROM_GLOBAL_COPY) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aRefEndLCS = aCI.GetEndLCS();

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aShapeEndLCS = aRefEndLCS->GetValue();

    if (aShapeBase.IsNull() || aShapeEndLCS.IsNull() ||
        aShapeEndLCS.ShapeType() != TopAbs_FACE)
      return 0;

    gp_Trsf aTrsf;
    gp_Ax3 aStartAx3, aDestAx3;

    // End LCS
    aDestAx3 = GEOMImpl_IMeasureOperations::GetPosition(aShapeEndLCS);

    // Set transformation
    aTrsf.SetDisplacement(aStartAx3, aDestAx3);

    // Perform transformation
    BRepBuilderAPI_Transform aBRepTrsf (aShapeBase, aTrsf, Standard_False);
    aShape = aBRepTrsf.Shape();
  }
  else if (aType == POSITION_ALONG_PATH) {
    Handle(GEOM_Function) aRefShape = aCI.GetShape();
    Handle(GEOM_Function) aPathShape = aCI.GetPath();
    Standard_Real aParameter = aCI.GetDistance();
    bool aReversed = aCI.GetReverse();
    if (aReversed)
      aParameter = 1 - aParameter;

    TopoDS_Shape aShapeBase = aRefShape->GetValue();
    TopoDS_Shape aPath = aPathShape->GetValue();
    TopoDS_Wire aWire;

    if (aShapeBase.IsNull() || aPath.IsNull())
      return 0;

    if ( aPath.ShapeType() == TopAbs_EDGE ) {
      TopoDS_Edge anEdge = TopoDS::Edge(aPath);
      aWire = BRepBuilderAPI_MakeWire(anEdge); 
    }
    else if ( aPath.ShapeType() == TopAbs_WIRE)
      aWire = TopoDS::Wire(aPath);
    else
      return 0;

    Handle(GeomFill_TrihedronLaw) TLaw = new GeomFill_CorrectedFrenet();
    Handle(GeomFill_CurveAndTrihedron) aLocationLaw = new GeomFill_CurveAndTrihedron( TLaw );
    Handle(BRepFill_LocationLaw) aLocation = new BRepFill_Edge3DLaw(aWire, aLocationLaw);

    aLocation->TransformInCompatibleLaw( 0.01 );

    //Calculate a Parameter
    Standard_Real aFirstParam1 = 0, aLastParam1 = 0; // Parameters of the First edge
    Standard_Real aFirstParam2 = 0, aLastParam2 = 0; // Parameters of the Last edge
    aLocation->CurvilinearBounds(aLocation->NbLaw(), aFirstParam2, aLastParam2);

    if ( aLocation->NbLaw() > 1)
      aLocation->CurvilinearBounds(1, aFirstParam1, aLastParam1);
    else if ( aLocation->NbLaw() == 1 )
      aFirstParam1 = aFirstParam2;
    else
      return 0;

    Standard_Real aParam = (aFirstParam1 + (aLastParam2 - aFirstParam1)*aParameter );

    TopoDS_Shape CopyShape = aShapeBase;
    BRepFill_SectionPlacement Place( aLocation, aShapeBase );
    TopLoc_Location Loc2(Place.Transformation()), Loc1;
    Loc1 = CopyShape.Location();
    CopyShape.Location(Loc2.Multiplied(Loc1));

    aLocation->D0( aParam, CopyShape );
    aShape = CopyShape;
  }
  else
    return 0;

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IChamfer aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShapeBase = aRefShape->GetValue();

  // Check the shape type. It have to be shell
  // or solid, or compsolid, or compound of these shapes.
  if (!isGoodForChamfer(aShapeBase)) {
    StdFail_NotDone::Raise
      ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
  }

  BRepFilletAPI_MakeChamfer fill (aShapeBase);

  if (aType == CHAMFER_SHAPE_ALL) {
    // symmetric chamfer on all edges
    double aD = aCI.GetD();
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (int i = 1; i <= M.Extent(); i++) {
      TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
      TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
      if (!BRepTools::IsReallyClosed(E, F) &&
          !BRep_Tool::Degenerated(E) &&
          M.FindFromIndex(i).Extent() == 2)
        fill.Add(aD, E, F);
    }
  }
  else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
    // chamfer on edges, common to two faces, with D1 on the first face

    TopoDS_Shape aFace1, aFace2;
    if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
        GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
    {
      TopoDS_Face F = TopoDS::Face(aFace1);

      // fill map of edges of the second face
      TopTools_MapOfShape aMap;
      TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
      for (; Exp2.More(); Exp2.Next()) {
        aMap.Add(Exp2.Current());
      }

      // find edges of the first face, common with the second face
      TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
      for (; Exp.More(); Exp.Next()) {
        if (aMap.Contains(Exp.Current())) {
          TopoDS_Edge E = TopoDS::Edge(Exp.Current());
          if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
          {
            if ( aType == CHAMFER_SHAPE_EDGE )
            {
              double aD1 = aCI.GetD1();
              double aD2 = aCI.GetD2();
              fill.Add(aD1, aD2, E, F);
            }
            else
            {
              double aD = aCI.GetD();
              double anAngle = aCI.GetAngle();
              if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
                fill.AddDA(aD, anAngle, E, F);
            }
          }
        }
      }
    }
  }
  else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
    // chamfer on all edges of the selected faces, with D1 on the selected face
    // (on first selected face, if the edge belongs to two selected faces)

    int aLen = aCI.GetLength();
    int ind = 1;
    TopTools_MapOfShape aMap;
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (; ind <= aLen; ind++)
    {
      TopoDS_Shape aShapeFace;
      if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
      {
        TopoDS_Face F = TopoDS::Face(aShapeFace);
        TopExp_Explorer Exp (F, TopAbs_EDGE);
        for (; Exp.More(); Exp.Next()) {
          if (!aMap.Contains(Exp.Current()))
          {
            TopoDS_Edge E = TopoDS::Edge(Exp.Current());
            if (!BRepTools::IsReallyClosed(E, F) &&
                !BRep_Tool::Degenerated(E) &&
                M.FindFromKey(E).Extent() == 2)
            {
              if (aType == CHAMFER_SHAPE_FACES)
              {
                double aD1 = aCI.GetD1();
                double aD2 = aCI.GetD2();
                fill.Add(aD1, aD2, E, F);
              }
              else
              {
                double aD = aCI.GetD();
                double anAngle = aCI.GetAngle();
                if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
                  fill.AddDA(aD, anAngle, E, F);
              }
            }
          }
        }
      }
    }
  }
  else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
  {
    // chamfer on selected edges with lenght param D1 & D2.

    int aLen = aCI.GetLength();
    int ind = 1;
    TopTools_MapOfShape aMap;
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (; ind <= aLen; ind++)
    {
      TopoDS_Shape aShapeEdge;
      if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
      {
        TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
        const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
        TopoDS_Face F = TopoDS::Face( aFacesList.First() );
        if (aType == CHAMFER_SHAPE_EDGES)
        {
          double aD1 = aCI.GetD1();
          double aD2 = aCI.GetD2();
          fill.Add(aD1, aD2, E, F);
        }
        else
        {
          double aD = aCI.GetD();
          double anAngle = aCI.GetAngle();
          if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
            fill.AddDA(aD, anAngle, E, F);
        }
      }
    }
  }
  else {
  }

  fill.Build();
  if (!fill.IsDone()) {
    StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
  }
  aShape = fill.Shape();

  if (aShape.IsNull()) return 0;

  // reduce tolerances
  ShapeFix_ShapeTolerance aSFT;
  aSFT.LimitTolerance(aShape, Precision::Confusion(),
                      Precision::Confusion(), TopAbs_SHAPE);
  Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
  aSfs->Perform();
  aShape = aSfs->Shape();

  // fix SameParameter flag
  BRepLib::SameParameter(aShape, 1.E-5, Standard_True);

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_PrismDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IPrism aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == PRISM_BASE_VEC_H || aType == PRISM_BASE_VEC_H_2WAYS) {
	Handle(GEOM_Function) aRefBase = aCI.GetBase();
	Handle(GEOM_Function) aRefVector = aCI.GetVector();
	TopoDS_Shape aShapeBase = aRefBase->GetValue();
	TopoDS_Shape aShapeVec = aRefVector->GetValue();
	if (aShapeVec.ShapeType() == TopAbs_EDGE) {
	  TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
	  TopoDS_Vertex V1, V2;
	  TopExp::Vertices(anE, V1, V2, Standard_True);
	  if (!V1.IsNull() && !V2.IsNull()) {
		gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
		if (Abs(aCI.GetH()) < Precision::Confusion()) {
		  Standard_ConstructionError::Raise("Absolute value of prism height is too small");
		}
		if (aV.Magnitude() > Precision::Confusion()) {
		  aV.Normalize();
          if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
            aShape = MakeScaledPrism(aShapeBase, aV * aCI.GetH(), aCI.GetScale());
          }
          else {
		  if (aType == PRISM_BASE_VEC_H_2WAYS) {
			gp_Trsf aTrsf;
			aTrsf.SetTranslation( (-aV) * aCI.GetH() );
			BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
			aShapeBase = aTransformation.Shape();
			aCI.SetH( aCI.GetH()*2 );
		  }
		  aShape = BRepPrimAPI_MakePrism(aShapeBase, aV * aCI.GetH(), Standard_False).Shape();
		}
	  }
	}
    }
  } else if (aType == PRISM_BASE_TWO_PNT || aType == PRISM_BASE_TWO_PNT_2WAYS) {
	Handle(GEOM_Function) aRefBase = aCI.GetBase();
	Handle(GEOM_Function) aRefPnt1 = aCI.GetFirstPoint();
	Handle(GEOM_Function) aRefPnt2 = aCI.GetLastPoint();
	TopoDS_Shape aShapeBase = aRefBase->GetValue();
	TopoDS_Shape aShapePnt1 = aRefPnt1->GetValue();
	TopoDS_Shape aShapePnt2 = aRefPnt2->GetValue();
	if (aShapePnt1.ShapeType() == TopAbs_VERTEX &&
		aShapePnt2.ShapeType() == TopAbs_VERTEX) {
	  TopoDS_Vertex V1 = TopoDS::Vertex(aShapePnt1);
	  TopoDS_Vertex V2 = TopoDS::Vertex(aShapePnt2);
	  if (!V1.IsNull() && !V2.IsNull()) {
		gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
		if (aV.Magnitude() > gp::Resolution()) {
          if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
            aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
          }
          else {
		  if (aType == PRISM_BASE_TWO_PNT_2WAYS) {
			gp_Trsf aTrsf;
			aTrsf.SetTranslation(-aV);
			BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
			aShapeBase = aTransformation.Shape();
			aV = aV * 2;
		  }
		  aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
		}
	  }
	}
  }
  }
  else if (aType == PRISM_BASE_VEC_H_ANG) {
	Handle(GEOM_Function) aRefBase = aCI.GetBase();
	Handle(GEOM_Function) aRefVector = aCI.GetVector();
	TopoDS_Shape aShapeBase = aRefBase->GetValue();
	TopoDS_Shape aShapeVec = aRefVector->GetValue();
	if (aShapeVec.ShapeType() == TopAbs_EDGE) {
	  TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
	  TopoDS_Vertex V1, V2;
	  TopExp::Vertices(anE, V1, V2, Standard_True);
	  if (!V1.IsNull() && !V2.IsNull()) {
		gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
		if (Abs(aCI.GetH()) < Precision::Confusion()) {
		  Standard_ConstructionError::Raise("Absolute value of prism height is too small");
		}
		if (aV.Magnitude() > Precision::Confusion()) {
		  aV.Normalize();
		  TopAbs_ShapeEnum myBaseType = aShapeBase.ShapeType();

		  if (  (myBaseType != TopAbs_EDGE) && (myBaseType != TopAbs_WIRE) &&
				(myBaseType != TopAbs_FACE) && (myBaseType != TopAbs_SHELL) )
			Standard_ConstructionError::Raise("Base shape type is not of the requested type");

		  if (myBaseType == TopAbs_EDGE)
			aShapeBase = BRepBuilderAPI_MakeWire(TopoDS::Edge(aShapeBase));

		  BRepOffsetAPI_MakeDraft aDraft(aShapeBase, aV, aCI.GetAngle());

		  if (aCI.GetAngle() < 0.)
		    aDraft.SetDraft(Standard_True);

		  aDraft.Perform(aCI.GetH());
		  aShape = aDraft.Shape();
		}
	  }
	}
  } else if (aType == PRISM_BASE_DXDYDZ || aType == PRISM_BASE_DXDYDZ_2WAYS) {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    gp_Vec aV (aCI.GetDX(), aCI.GetDY(), aCI.GetDZ());
    if (aV.Magnitude() > gp::Resolution()) {
      if (aType != PRISM_BASE_DXDYDZ_2WAYS && aCI.GetScale() > Precision::Confusion()) {
        aShape = MakeScaledPrism(aShapeBase, aV, aCI.GetScale());
      }
      else {
        if (aType == PRISM_BASE_DXDYDZ_2WAYS) {
	  gp_Trsf aTrsf;
	  aTrsf.SetTranslation(-aV);
	  BRepBuilderAPI_Transform aTransformation(aShapeBase, aTrsf, Standard_False);
	  aShapeBase = aTransformation.Shape();
	  aV = aV * 2;
	}
      aShape = BRepPrimAPI_MakePrism(aShapeBase, aV, Standard_False).Shape();
    }
    }
  }

  if (aShape.IsNull()) return 0;

  TopoDS_Shape aRes = GEOMImpl_IShapesOperations::CompsolidToCompound(aShape);
  aFunction->SetValue(aRes);

  log.SetTouched(Label()); 

  return 1;    
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ConeDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_ICone aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  gp_Pnt aP;
  gp_Vec aV;

  Standard_Real aR1 = aCI.GetR1();
  Standard_Real aR2 = aCI.GetR2();

  if (aType == CONE_R1_R2_H) {
    aP = gp::Origin();
    aV = gp::DZ();

  } else if (aType == CONE_PNT_VEC_R1_R2_H) {
    Handle(GEOM_Function) aRefPoint  = aCI.GetPoint();
    Handle(GEOM_Function) aRefVector = aCI.GetVector();
    TopoDS_Shape aShapePnt = aRefPoint->GetValue();
    TopoDS_Shape aShapeVec = aRefVector->GetValue();
    if (aShapePnt.IsNull() || aShapeVec.IsNull()) {
      Standard_NullObject::Raise
        ("Cone creation aborted: point or vector is not defined");
    }
    if (aShapePnt.ShapeType() != TopAbs_VERTEX ||
        aShapeVec.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise
        ("Cone creation aborted: point or vector shapes has wrong type");
    }

    aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));

    TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (V1.IsNull() || V2.IsNull()) {
      Standard_NullObject::Raise
        ("Cylinder creation aborted: vector is not defined");
    }
    aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));

  } else {
    return 0;
  }

  if (aCI.GetH() < 0.0) aV.Reverse();
  gp_Ax2 anAxes (aP, aV);

  double theAngle = aCI.GetAngle();
  if (theAngle == 0.)
	theAngle = PI*2.;

  TopoDS_Shape aShape;
  // Cone does not work if same radius
  if (fabs(aR1 - aR2) <= Precision::Confusion()) {
  
	BRepPrimAPI_MakeCylinder MC (anAxes, (aR1 + aR2)/2.0, Abs(aCI.GetH()), theAngle);

	MC.Build();
    if (!MC.IsDone()) {
      StdFail_NotDone::Raise("Cylinder can't be computed from the given parameters");
    }
    aShape = MC.Shape();
  } else {
    BRepPrimAPI_MakeCone MC (anAxes, aCI.GetR1(), aCI.GetR2(), Abs(aCI.GetH()), theAngle);
    MC.Build();
    if (!MC.IsDone()) {
      StdFail_NotDone::Raise("Cylinder can't be computed from the given parameters");
    }
    aShape = MC.Shape();
  }
  if (aShape.IsNull()) return 0;

  log.SetTouched(Label());

  aFunction->SetValue(aShape);
  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_PlaneDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull())  return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IPlane aPI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  double aSize = aPI.GetSize() / 2.0;
  if (aType == PLANE_PNT_VEC) {
    Handle(GEOM_Function) aRefPnt = aPI.GetPoint();
    Handle(GEOM_Function) aRefVec = aPI.GetVector();
    TopoDS_Shape aShape1 = aRefPnt->GetValue();
    TopoDS_Shape aShape2 = aRefVec->GetValue();
    if (aShape1.ShapeType() != TopAbs_VERTEX ||
        aShape2.ShapeType() != TopAbs_EDGE) return 0;
    gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
    TopoDS_Edge anE = TopoDS::Edge(aShape2);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    if (!V1.IsNull() && !V2.IsNull()) {
      gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
      gp_Pln aPln (aP, aV);
      aShape = BRepBuilderAPI_MakeFace(aPln, -aSize, +aSize, -aSize, +aSize).Shape();
    }
  } else if (aType == PLANE_THREE_PNT) {
    Handle(GEOM_Function) aRefPnt1 = aPI.GetPoint1();
    Handle(GEOM_Function) aRefPnt2 = aPI.GetPoint2();
    Handle(GEOM_Function) aRefPnt3 = aPI.GetPoint3();
    TopoDS_Shape aShape1 = aRefPnt1->GetValue();
    TopoDS_Shape aShape2 = aRefPnt2->GetValue();
    TopoDS_Shape aShape3 = aRefPnt3->GetValue();
    if (aShape1.ShapeType() != TopAbs_VERTEX ||
        aShape2.ShapeType() != TopAbs_VERTEX ||
        aShape3.ShapeType() != TopAbs_VERTEX) return 0;
    gp_Pnt aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aShape1));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aShape2));
    gp_Pnt aP3 = BRep_Tool::Pnt(TopoDS::Vertex(aShape3));
    if (aP1.Distance(aP2) < gp::Resolution() ||
        aP1.Distance(aP3) < gp::Resolution() ||
        aP2.Distance(aP3) < gp::Resolution())
      Standard_ConstructionError::Raise("Plane creation aborted: coincident points given");
    if (gp_Vec(aP1, aP2).IsParallel(gp_Vec(aP1, aP3), Precision::Angular()))
      Standard_ConstructionError::Raise("Plane creation aborted: points lay on one line");
    GC_MakePlane aMakePlane (aP1, aP2, aP3);
    aShape = BRepBuilderAPI_MakeFace(aMakePlane, -aSize, +aSize, -aSize, +aSize).Shape();
  } else if (aType == PLANE_FACE) {
    Handle(GEOM_Function) aRef = aPI.GetFace();
    TopoDS_Shape aRefShape = aRef->GetValue();
    //if (aRefShape.ShapeType() != TopAbs_FACE) return 0;
    //Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aRefShape));
    //if (!aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
    //  Standard_TypeMismatch::Raise("Plane creation aborted: non-planar face given as argument");
    //}
    //aShape = BRepBuilderAPI_MakeFace(aGS, -aSize, +aSize, -aSize, +aSize).Shape();
    gp_Ax3 anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aRefShape);
    gp_Pln aPln (anAx3);
    aShape = BRepBuilderAPI_MakeFace(aPln, -aSize, +aSize, -aSize, +aSize).Shape();
  }
  else if (aType == PLANE_TANGENT_FACE)
  {
    Handle(GEOM_Function) aRefFace = aPI.GetFace();
    TopoDS_Shape aShape1 = aRefFace->GetValue();
    if(aShape1.IsNull())
      Standard_TypeMismatch::Raise("Plane was not created.Basis face was not specified");
    TopoDS_Face aFace = TopoDS::Face(aShape1);

    Standard_Real aKoefU = aPI.GetParameterU();
    Standard_Real aKoefV = aPI.GetParameterV();
    Standard_Real aUmin,aUmax,aVmin,aVmax;
    ShapeAnalysis::GetFaceUVBounds(aFace,aUmin,aUmax,aVmin,aVmax);
    Standard_Real aDeltaU = aUmax - aUmin;
    Standard_Real aDeltaV = aVmax - aVmin;
    Standard_Real aParamU =  aUmin + aDeltaU*aKoefU;
    Standard_Real aParamV =  aVmin + aDeltaV*aKoefV;
    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
    if(aSurf.IsNull())
      Standard_TypeMismatch::Raise("Plane was not created.Base surface is absent");
    gp_Vec aVecU,aVecV;
    gp_Pnt aPLoc;
    aSurf->D1(aParamU,aParamV,aPLoc,aVecU,aVecV);
    BRepTopAdaptor_FClass2d clas(aFace,Precision::PConfusion());

    TopAbs_State stOut= clas.PerformInfinitePoint();
    gp_Pnt2d aP2d(aParamU,aParamV);
    TopAbs_State st= clas.Perform(aP2d);
    if(st == stOut)
      Standard_TypeMismatch::Raise("Plane was not created.Point lies outside the face");
    gp_Vec aNorm = aVecU^aVecV;
    gp_Ax3 anAxis(aPLoc,gp_Dir(aNorm),gp_Dir(aVecU));
    gp_Pln aPlane(anAxis);
    BRepBuilderAPI_MakeFace aTool(aPlane, -aSize, +aSize, -aSize, +aSize);
    if(aTool.IsDone())
      aShape = aTool.Shape();
  }
  else if (aType == PLANE_2_VEC) {
    Handle(GEOM_Function) aRefVec1 = aPI.GetVector1();
    Handle(GEOM_Function) aRefVec2 = aPI.GetVector2();
    TopoDS_Shape aShape1 = aRefVec1->GetValue();
    TopoDS_Shape aShape2 = aRefVec2->GetValue();
    if (aShape1.ShapeType() != TopAbs_EDGE ||
        aShape2.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge aVectX = TopoDS::Edge(aShape1);
    TopoDS_Edge aVectZ = TopoDS::Edge(aShape2);

    TopoDS_Vertex VX1, VX2, VZ1, VZ2;
    TopExp::Vertices( aVectX, VX1, VX2, Standard_True );
    TopExp::Vertices( aVectZ, VZ1, VZ2, Standard_True );

    gp_Vec aVX = gp_Vec( BRep_Tool::Pnt( VX1 ), BRep_Tool::Pnt( VX2 ) );
    gp_Vec aVZ = gp_Vec( BRep_Tool::Pnt( VZ1 ), BRep_Tool::Pnt( VZ2 ) );

    if ( aVX.Magnitude() < Precision::Confusion() || aVZ.Magnitude() < Precision::Confusion())
      Standard_TypeMismatch::Raise("Invalid vector selected");

    gp_Dir aDirX = gp_Dir( aVX.X(), aVX.Y(), aVX.Z() );
    gp_Dir aDirZ = gp_Dir( aVZ.X(), aVZ.Y(), aVZ.Z() );

    if ( aDirX.IsParallel( aDirZ, Precision::Angular() ) )
      Standard_TypeMismatch::Raise("Parallel vectors selected");

    gp_Ax3 aPlane = gp_Ax3( BRep_Tool::Pnt( VX1 ), aDirZ, aDirX );
    BRepBuilderAPI_MakeFace aTool(aPlane, -aSize, +aSize, -aSize, +aSize);
    if(aTool.IsDone())
      aShape = aTool.Shape();
  }
  else if (aType == PLANE_LCS) {
    Handle(GEOM_Function) aRef = aPI.GetLCS();
    double anOrientation = aPI.GetOrientation();    
    gp_Ax3 anAx3;
    if (aRef.IsNull()) {
      gp_Ax2 anAx2 = gp::XOY();
      anAx3 = gp_Ax3( anAx2 );
    } else {
      TopoDS_Shape aRefShape = aRef->GetValue();
      if (aRefShape.ShapeType() != TopAbs_FACE)
	return 0;
      anAx3 = GEOMImpl_IMeasureOperations::GetPosition(aRefShape);
    }

    if ( anOrientation == 2)
      anAx3 = gp_Ax3(anAx3.Location(), anAx3.XDirection(), anAx3.YDirection() );
    else if ( anOrientation == 3 )
      anAx3 = gp_Ax3(anAx3.Location(), anAx3.YDirection(), anAx3.XDirection() );

    gp_Pln aPln(anAx3);
    aShape = BRepBuilderAPI_MakeFace(aPln, -aSize, +aSize, -aSize, +aSize).Shape();
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IFillet1d aCI (aFunction);

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShape = aRefShape->GetValue();
  if (aShape.IsNull())
    return 0;
  if (aShape.ShapeType() != TopAbs_WIRE)
    Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");

  TopoDS_Wire aWire = TopoDS::Wire(aShape);

  double rad = aCI.GetR();

  if ( rad < Precision::Confusion())
    return 0;

  // collect vertices for make fillet
  TopTools_ListOfShape aVertexList;
  TopTools_MapOfShape mapShape;
  int aLen = aCI.GetLength();
  if ( aLen > 0 ) {
    for (int ind = 1; ind <= aLen; ind++) {
      TopoDS_Shape aShapeVertex;
      if (GEOMImpl_ILocalOperations::GetSubShape
          (aWire, aCI.GetVertex(ind), aShapeVertex))
        if (mapShape.Add(aShapeVertex))
          aVertexList.Append( aShapeVertex );
    }
  } else { // get all vertices from wire
    TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
    for ( ; anExp.More(); anExp.Next() ) {
      if (mapShape.Add(anExp.Current()))
        aVertexList.Append( anExp.Current() );
    }
  }
  if (aVertexList.IsEmpty())
    Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");

  //INFO: this algorithm implemented in assumption that user can select both
  //  vertices of some edges to make fillet. In this case we should remember
  //  already modified initial edges to take care in next fillet step
  TopTools_DataMapOfShapeShape anEdgeToEdgeMap;

  //iterates on vertices, and make fillet on each couple of edges
  //collect result fillet edges in list
  TopTools_ListOfShape aListOfNewEdge;
  // remember relation between initial and modified map
  TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
  TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
  TopTools_ListIteratorOfListOfShape anIt( aVertexList );
  for ( ; anIt.More(); anIt.Next() ) {
    TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
    if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
      continue;
    const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
    if ( aVertexEdges.Extent() != 2 )
      continue; // no input data to make fillet
    TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
    TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
    // check if initial edges already modified in previous fillet operation
    if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
    if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
    if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
      continue; //no input data to make fillet

    // create plane on 2 edges
    gp_Pln aPlane;
    if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
      continue; // seems edges does not belong to same plane or parallel (fillet can not be build)

    GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
    if ( !aFilletAlgo.Perform(rad) )
      continue; // can not create fillet with given radius

    // take fillet result in given vertex
    TopoDS_Edge aModifE1, aModifE2;
    TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
    if (aNewE.IsNull())
      continue; // no result found

    // add  new created edges and take modified edges
    aListOfNewEdge.Append( aNewE );

    // check if face edges modified,
    // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
    if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
    if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
  }

  if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) {
    StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
    return 0;
  }

  // create new wire instead of original
  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
    TopoDS_Shape anEdge = anExp.Current();
    if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
      aListOfNewEdge.Append( anEdge );
    else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull())
      aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
  }

  GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge );

  BRepBuilderAPI_MakeWire aWireTool;
  aWireTool.Add( aListOfNewEdge );
  aWireTool.Build();
  if (!aWireTool.IsDone())
    return 0;

  aWire = aWireTool.Wire();
  aFunction->SetValue(aWire);
  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_VectorDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull())  return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IVector aPI (aFunction);
  Standard_Integer aType = aFunction->GetType();
  if (aType != VECTOR_DX_DY_DZ && aType != VECTOR_TWO_PNT &&
      aType != VECTOR_TANGENT_CURVE_PAR && aType != VECTOR_REVERSE) return 0;

  TopoDS_Shape aShape;

  if (aType == VECTOR_DX_DY_DZ) {
    gp_Pnt P1 = gp::Origin();
    gp_Pnt P2 (aPI.GetDX(), aPI.GetDY(), aPI.GetDZ());
    if (P1.Distance(P2) < Precision::Confusion()) {
      TCollection_AsciiString aMsg ("Can not build vector with length, less than ");
      aMsg += TCollection_AsciiString(Precision::Confusion());
      Standard_ConstructionError::Raise(aMsg.ToCString());
    }
    aShape = BRepBuilderAPI_MakeEdge(P1, P2).Shape();
  }
  else if (aType == VECTOR_TWO_PNT) {
    Handle(GEOM_Function) aRefPnt1 = aPI.GetPoint1();
    Handle(GEOM_Function) aRefPnt2 = aPI.GetPoint2();
    TopoDS_Shape aShape1 = aRefPnt1->GetValue();
    TopoDS_Shape aShape2 = aRefPnt2->GetValue();
    if (aShape1.ShapeType() != TopAbs_VERTEX ||
        aShape2.ShapeType() != TopAbs_VERTEX) return 0;
    if (aShape1.IsSame(aShape2)) {
      Standard_ConstructionError::Raise("The end points must be different");
    }
    TopoDS_Vertex V1 = TopoDS::Vertex(aShape1);
    TopoDS_Vertex V2 = TopoDS::Vertex(aShape2);
    gp_Pnt P1 = BRep_Tool::Pnt(V1);
    gp_Pnt P2 = BRep_Tool::Pnt(V2);
    if (P1.Distance(P2) < Precision::Confusion()) {
      Standard_ConstructionError::Raise("The end points are too close");
    }
    aShape = BRepBuilderAPI_MakeEdge(V1, V2).Shape();
  } 
  else if (aType == VECTOR_TANGENT_CURVE_PAR) {
    Handle(GEOM_Function) aRefCurve = aPI.GetCurve();
    TopoDS_Shape aRefShape = aRefCurve->GetValue();
    if (aRefShape.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise
        ("Tangent On Curve creation aborted : curve shape is not an edge");
    }
    Standard_Real aFParam =0., aLParam =0., aParam =0.;
    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aRefShape), aFParam, aLParam);
    if(aCurve.IsNull()) {
      Standard_TypeMismatch::Raise
        ("Tangent On Curve creation aborted : curve is null");
    }

    aParam = aFParam + (aLParam - aFParam) * aPI.GetParameter();
    gp_Pnt aPoint1,aPoint2;
    gp_Vec aVec;
    aCurve->D1(aParam,aPoint1,aVec);
    if(aVec.Magnitude() < gp::Resolution())
      Standard_TypeMismatch::Raise
        ("Tangent On Curve creation aborted : invalid value of tangent");
    aPoint2.SetXYZ(aPoint1.XYZ() + aVec.XYZ());
    BRepBuilderAPI_MakeEdge aBuilder(aPoint1,aPoint2);
    if(aBuilder.IsDone())
      aShape = aBuilder.Shape();
  }
  else if (aType == VECTOR_REVERSE) {
    Handle(GEOM_Function) aRefVec = aPI.GetCurve();
    TopoDS_Shape aRefShape = aRefVec->GetValue();
    if (aRefShape.ShapeType() != TopAbs_EDGE) {
      Standard_TypeMismatch::Raise
        ("Reversed vector creation aborted : vector shape is not an edge");
    }
    TopoDS_Edge anE = TopoDS::Edge(aRefShape);
    TopoDS_Vertex V1, V2;
    TopExp::Vertices(anE, V1, V2, Standard_True);
    aShape = BRepBuilderAPI_MakeEdge(V2, V1).Shape();
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_PlateDriver::Execute(TFunction_Logbook& log) const
{
    if (Label().IsNull()) return 0;
    Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
    if(aFunction.IsNull()) return 0;

    GEOMImpl_IPlate aPI (aFunction);
    Standard_Integer aType = aFunction->GetType();

    TopoDS_Shape aShape;

    if (aType == PLATE_BY_SHAPES_LIST) {
        int ind, aLen = aPI.GetLength();

        if (aLen < 1)
            return 0;

        GeomPlate_BuildPlateSurface aPlate;
        Handle(GeomPlate_Surface) myPlateSurf;

        Handle(GEOM_Function) aRefInitialShape = aPI.GetInitialShape();
        if (!aRefInitialShape.IsNull()) {
            TopoDS_Shape anInitialShape = aRefInitialShape->GetValue();
            if (!anInitialShape.IsNull() && anInitialShape.ShapeType() == TopAbs_FACE)
            {
                aPlate.LoadInitSurface(BRep_Tool::Surface(TopoDS::Face(anInitialShape)));

                TopExp_Explorer exp (anInitialShape, TopAbs_EDGE); //in case we have an init surface we must pass all of it's edges as constrains
                for (; exp.More(); exp.Next()) {                   //otherwise exception is risen from the plate driver
                    BRepAdaptor_Curve aCurve(TopoDS::Edge(exp.Current()));
                    Handle(BRepAdaptor_HCurve) aHCurve = new BRepAdaptor_HCurve(aCurve);
                    Handle(GeomPlate_CurveConstraint) aCrvConstr = new GeomPlate_CurveConstraint(aHCurve, DEFAULT_CONTINUITY);
                    aPlate.Add(aCrvConstr);
                }
            }
        }

        for (ind = 1; ind <= aLen; ind++) {
            Handle(GEOM_Function) aRefShape = aPI.GetShape(ind);
            TopoDS_Shape aShape = aRefShape->GetValue();
            if (aShape.ShapeType() == TopAbs_VERTEX) { //case a simple point
                gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
                Handle(GeomPlate_PointConstraint) aPntConstr = new GeomPlate_PointConstraint(aP, DEFAULT_CONTINUITY);
                aPlate.Add(aPntConstr);
            }
            else {
                TopExp_Explorer exp (aShape, TopAbs_EDGE); //this case treats all cases where edges can be found
                Standard_Boolean hasEdge = Standard_False;
                for (; exp.More(); exp.Next()) {
                    BRepAdaptor_Curve aCurve(TopoDS::Edge(exp.Current()));
                    Handle(BRepAdaptor_HCurve) aHCurve = new BRepAdaptor_HCurve(aCurve);
                    Handle(GeomPlate_CurveConstraint) aCrvConstr = new GeomPlate_CurveConstraint(aHCurve, DEFAULT_CONTINUITY);
                    aPlate.Add(aCrvConstr);
                    hasEdge = Standard_True;
                }
                if (!hasEdge) { //this case treats a compound of points
                    exp.Init(aShape, TopAbs_VERTEX);
                    for (; exp.More(); exp.Next()) {
                        gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
                        Handle(GeomPlate_PointConstraint) aPntConstr = new GeomPlate_PointConstraint(aP, DEFAULT_CONTINUITY);
                        aPlate.Add(aPntConstr);
                    }
                }
            }
        }
        aPlate.Perform();
        if (!aPlate.IsDone())
            Standard_ConstructionError::Raise("Plate surface cannot be created using the specific shapes !");
        else
            myPlateSurf = aPlate.Surface();
        GeomPlate_MakeApprox aMKS( myPlateSurf, Precision::Approximation(), DEFAULT_Nbmax, DEFAULT_dgmax, DEFAULT_dmax);
        BRepBuilderAPI_MakeFace MK (aMKS.Surface(), Precision::Confusion());
        MK.Build();
        if (!MK.IsDone())
            Standard_ConstructionError::Raise("Plate topology cannot be created !");
        else {
            aShape = MK.Shape();
            BRepCheck_Analyzer ana (aShape, false);
            if (!ana.IsValid()) {
                Standard_CString anErrStr("Plate algorithm has produced an invalid shape result");
#ifdef THROW_ON_INVALID_SH
                Standard_ConstructionError::Raise(anErrStr);
#else
                MESSAGE(anErrStr);
                //further processing can be performed here
                //...
                //in case of failure of automatic treatment
                //mark the corresponding GEOM_Object as problematic
                TDF_Label aLabel = aFunction->GetOwnerEntry();
                if (!aLabel.IsRoot()) {
                    Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
                    if (!aMainObj.IsNull())
                        aMainObj->SetDirty(Standard_True);
                }
#endif
            }
        }
    }
    if (aShape.IsNull()) return 0;
    aFunction->SetValue(aShape);
    log.SetTouched(Label());
    return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_RotateDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  if (aFunction.IsNull()) return 0;

  GEOMImpl_IRotate RI(aFunction);
  gp_Trsf aTrsf;
  gp_Pnt aCP, aP1, aP2;
  Standard_Integer aType = aFunction->GetType();
  Handle(GEOM_Function) anOriginalFunction = RI.GetOriginal();
  if (anOriginalFunction.IsNull()) return 0;
  TopoDS_Shape aShape, anOriginal = anOriginalFunction->GetValue();
  if (anOriginal.IsNull()) return 0;

  if (aType == ROTATE || aType == ROTATE_COPY) {
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if (anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if (A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);

    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir aDir(gp_Vec(aP1, aP2));
    gp_Ax1 anAx1(aP1, aDir);
    Standard_Real anAngle = RI.GetAngle();
    if (fabs(anAngle) < Precision::Angular()) anAngle += 2*PI; // NPAL19665,19769
    aTrsf.SetRotation(anAx1, anAngle);

    //NPAL18620: performance problem: multiple locations are accumulated
    //           in shape and need a great time to process
    //BRepBuilderAPI_Transform aTransformation(anOriginal, aTrsf, Standard_False);
    //aShape = aTransformation.Shape();
    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();
    //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
    aTrsfOrig.PreMultiply(aTrsf);
    TopLoc_Location aLocRes (aTrsfOrig);
    aShape = anOriginal.Located(aLocRes);
  }
  else if (aType ==  ROTATE_THREE_POINTS || aType == ROTATE_THREE_POINTS_COPY) {
    Handle(GEOM_Function) aCentPoint = RI.GetCentPoint();
    Handle(GEOM_Function) aPoint1 = RI.GetPoint1();
    Handle(GEOM_Function) aPoint2 = RI.GetPoint2();
    if(aCentPoint.IsNull() || aPoint1.IsNull() || aPoint2.IsNull()) return 0;
    TopoDS_Shape aCV = aCentPoint->GetValue();
    TopoDS_Shape aV1 = aPoint1->GetValue();
    TopoDS_Shape aV2 = aPoint2->GetValue();
    if(aCV.IsNull() || aCV.ShapeType() != TopAbs_VERTEX) return 0;
    if(aV1.IsNull() || aV1.ShapeType() != TopAbs_VERTEX) return 0;
    if(aV2.IsNull() || aV2.ShapeType() != TopAbs_VERTEX) return 0;

    aCP = BRep_Tool::Pnt(TopoDS::Vertex(aCV));
    aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aV1));
    aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aV2));

    gp_Vec aVec1 (aCP, aP1);
    gp_Vec aVec2 (aCP, aP2);
    gp_Dir aDir (aVec1 ^ aVec2);
    gp_Ax1 anAx1 (aCP, aDir);
    Standard_Real anAngle = aVec1.Angle(aVec2);
    if (fabs(anAngle) < Precision::Angular()) anAngle += 2*PI; // NPAL19665
    aTrsf.SetRotation(anAx1, anAngle);
    //NPAL18620: performance problem: multiple locations are accumulated
    //           in shape and need a great time to process
    //BRepBuilderAPI_Transform aTransformation(anOriginal, aTrsf, Standard_False);
    //aShape = aTransformation.Shape();
    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();
    //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
    aTrsfOrig.PreMultiply(aTrsf);
    TopLoc_Location aLocRes (aTrsfOrig);
    aShape = anOriginal.Located(aLocRes);
  }
  else if (aType == ROTATE_1D) {
    //Get direction
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if(anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);

    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir D(gp_Vec(aP1, aP2));

    gp_Ax1 AX1(aP1, D);

    Standard_Integer nbtimes = RI.GetNbIter1();
    Standard_Real angle = 360.0/nbtimes;

    TopoDS_Compound aCompound;
    BRep_Builder B;
    B.MakeCompound( aCompound );

    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();

    for (int i = 0; i < nbtimes; i++ ) {
      if (i == 0) { // NPAL19665
        B.Add(aCompound, anOriginal);
      }
      else {
        aTrsf.SetRotation(AX1, i*angle/* * PI180 */);
        //TopLoc_Location aLocRes (aTrsf * aTrsfOrig); // gp_Trsf::Multiply() has a bug
        gp_Trsf aTrsfNew (aTrsfOrig);
        aTrsfNew.PreMultiply(aTrsf);
        TopLoc_Location aLocRes (aTrsfNew);
        B.Add(aCompound, anOriginal.Located(aLocRes));
      }
      //NPAL18620: performance problem: multiple locations are accumulated
      //           in shape and need a great time to process
      //BRepBuilderAPI_Transform aBRepTransformation(anOriginal, aTrsf, Standard_False);
      //B.Add(aCompound, aBRepTransformation.Shape());
    }

    aShape = aCompound;
  }
  else if (aType == ROTATE_2D) {
    //Get direction
    Handle(GEOM_Function) anAxis = RI.GetAxis();
    if(anAxis.IsNull()) return 0;
    TopoDS_Shape A = anAxis->GetValue();
    if(A.IsNull() || A.ShapeType() != TopAbs_EDGE) return 0;
    TopoDS_Edge anEdge = TopoDS::Edge(A);
    gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
    gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
    gp_Dir D(gp_Vec(aP1, aP2));

    gp_Ax1 AX1(aP1, D);

    gp_Trsf aTrsf1;
    gp_Trsf aTrsf2;
    gp_Trsf aTrsf3;

    gp_XYZ aDir2 = RI.GetDir2(); // can be set by previous execution
    if (aDir2.Modulus() < gp::Resolution()) {
      // Calculate direction as vector from the axis to the shape's center
    gp_Pnt P1;
    GProp_GProps System;

    if (anOriginal.ShapeType() == TopAbs_VERTEX) {
      P1 = BRep_Tool::Pnt(TopoDS::Vertex( anOriginal ));
    }
    else if ( anOriginal.ShapeType() == TopAbs_EDGE || anOriginal.ShapeType() == TopAbs_WIRE ) {
      BRepGProp::LinearProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }
    else if ( anOriginal.ShapeType() == TopAbs_FACE || anOriginal.ShapeType() == TopAbs_SHELL ) {
      BRepGProp::SurfaceProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }
    else {
      BRepGProp::VolumeProperties(anOriginal, System);
      P1 = System.CentreOfMass();
    }

    Handle(Geom_Line) Line = new Geom_Line(AX1);
    GeomAPI_ProjectPointOnCurve aPrjTool( P1, Line );
    gp_Pnt P2 = aPrjTool.NearestPoint();

    if ( P1.IsEqual(P2, Precision::Confusion() ) ) return 0;

    aDir2 = gp_XYZ(P1.X()-P2.X(), P1.Y()-P2.Y(), P1.Z()-P2.Z());

    // Attention: this abnormal action is done for good working of
    // TransformLikeOther(), used by RestoreSubShapes functionality
    RI.SetDir2(aDir2);
    }

    gp_Vec Vec (aDir2);
    Vec.Normalize();

    gp_Vec elevVec(D);
    elevVec.Normalize();

    Standard_Integer nbtimes2 = RI.GetNbIter2();
    Standard_Integer nbtimes1 = RI.GetNbIter1();
    Standard_Real step = RI.GetStep();
    Standard_Real elevationstep = RI.GetElevationStep();
    Standard_Real ang = RI.GetAngle();

    TopLoc_Location aLocOrig = anOriginal.Location();
    gp_Trsf aTrsfOrig = aLocOrig.Transformation();

    gp_Vec aVec;
    TopoDS_Compound aCompound;
    BRep_Builder B;
    B.MakeCompound( aCompound );

    Standard_Real DX, DY, DZ;

    for (int i = 0; i < nbtimes2; i++ ) {
      if (i != 0) {
        DX = i * step * Vec.X();
        DY = i * step * Vec.Y();
        DZ = i * step * Vec.Z();
        aVec.SetCoord( DX, DY, DZ );
        aTrsf1.SetTranslation(aVec);
      }
      for (int j = 0; j < nbtimes1; j++ ) {
        if (j == 0) { // NPAL19665
          TopLoc_Location aLocRes (aTrsf1 * aTrsfOrig);
          B.Add(aCompound, anOriginal.Located(aLocRes));
        }
        else {
          DX = j * elevationstep * elevVec.X();
          DY = j * elevationstep * elevVec.Y();
          DZ = j * elevationstep * elevVec.Z();
          aVec.SetCoord( DX, DY, DZ );
          aTrsf3.SetTranslation(aVec);

          aTrsf2.SetRotation(AX1, j*ang /* * PI180 */ );
          //TopLoc_Location aLocRes (aTrsf2 * aTrsf1 * aTrsfOrig); // gp_Trsf::Multiply() has a bug
          gp_Trsf aTrsfNew (aTrsfOrig);
          aTrsfNew.PreMultiply(aTrsf1);
          aTrsfNew.PreMultiply(aTrsf2);
          aTrsfNew.PreMultiply(aTrsf3);
          TopLoc_Location aLocRes (aTrsfNew);
          B.Add(aCompound, anOriginal.Located(aLocRes));
        }
        //NPAL18620: performance problem: multiple locations are accumulated
        //           in shape and need a great time to process
        //BRepBuilderAPI_Transform aBRepTrsf1 (anOriginal, aTrsf1, Standard_False);
        //BRepBuilderAPI_Transform aBRepTrsf2 (aBRepTrsf1.Shape(), aTrsf2, Standard_False);
        //B.Add(aCompound, aBRepTrsf2.Shape());
      }
    }

    aShape = aCompound;
  }
  else return 0;


  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
//=======================================================================
//function : Execute
//purpose  :
//======================================================================= 
Standard_Integer GEOMImpl_EllipseDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;    
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IEllipse aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  if (aType == ELLIPSE_PNT_VEC_RR) {
    // Center
    gp_Pnt aP = gp::Origin();
    Handle(GEOM_Function) aRefPoint = aCI.GetCenter();
    if (!aRefPoint.IsNull()) {
      TopoDS_Shape aShapePnt = aRefPoint->GetValue();
      if (aShapePnt.ShapeType() != TopAbs_VERTEX) {
        Standard_ConstructionError::Raise
          ("Ellipse creation aborted: invalid center argument, must be a point");
      }
      aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
    }
    // Normal
    gp_Vec aV = gp::DZ();
    Handle(GEOM_Function) aRefVector = aCI.GetVector();
    if (!aRefVector.IsNull()) {
      TopoDS_Shape aShapeVec = aRefVector->GetValue();
      if (aShapeVec.ShapeType() != TopAbs_EDGE) {
        Standard_ConstructionError::Raise
          ("Ellipse creation aborted: invalid normal vector argument, must be a vector or an edge");
      }
      TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
      TopoDS_Vertex V1, V2;
      TopExp::Vertices(anE, V1, V2, Standard_True);
      if (!V1.IsNull() && !V2.IsNull()) {
        aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
        if (aV.Magnitude() < gp::Resolution()) {
          Standard_ConstructionError::Raise
            ("Ellipse creation aborted: normal vector of zero length is given");
        }
      }
    }

    // Axes
    gp_Ax2 anAxes (aP, aV);

    // Main Axis vector
    Handle(GEOM_Function) aRefVectorMaj = aCI.GetVectorMajor();
    if (!aRefVectorMaj.IsNull()) {
      TopoDS_Shape aShapeVec = aRefVectorMaj->GetValue();
      if (aShapeVec.ShapeType() != TopAbs_EDGE) {
        Standard_ConstructionError::Raise
          ("Ellipse creation aborted: invalid major axis vector argument, must be a vector or an edge");
      }
      TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
      TopoDS_Vertex V1, V2;
      TopExp::Vertices(anE, V1, V2, Standard_True);
      if (!V1.IsNull() && !V2.IsNull()) {
	gp_Vec aVM (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
        if (aVM.Magnitude() < gp::Resolution()) {
          Standard_ConstructionError::Raise
            ("Ellipse creation aborted: major axis vector of zero length is given");
        }
	if (aV.IsParallel(aVM, Precision::Angular())) {
	  Standard_ConstructionError::Raise
	    ("Ellipse creation aborted: normal and major axis vectors are parallel");
	}
	// Axes defined with main axis vector
	anAxes  = gp_Ax2 (aP, aV, aVM);
      }
    }
    // Radiuses
    double radiusMaj = aCI.GetRMajor();
    double radiusMin = aCI.GetRMinor();
    if ( radiusMaj < radiusMin )
      Standard_ConstructionError::Raise
        ("Ellipse creation aborted: a major radius is less that a minor one");
    if ( radiusMin < 0.0 )
      Standard_ConstructionError::Raise
        ("Ellipse creation aborted: raduis must be positive");

    // Ellipse
    gp_Elips anEll (anAxes, radiusMaj, radiusMin);
    aShape = BRepBuilderAPI_MakeEdge(anEll).Edge();
  } 
  else if(aType == ELLIPSE_THREE_PNT) {
    Handle(GEOM_Function) aRefPoint  = aCI.GetCenter();
    Handle(GEOM_Function) aRefPMajor = aCI.GetPMajor();
    Handle(GEOM_Function) aRefPMinor = aCI.GetPMinor();
    TopoDS_Shape aShCenter = aRefPoint->GetValue();
    TopoDS_Shape aShMajor = aRefPMajor->GetValue();
    TopoDS_Shape aShMinor = aRefPMinor->GetValue();
    if (aShCenter.ShapeType() == TopAbs_VERTEX &&
        aShMajor.ShapeType() == TopAbs_VERTEX && 
        aShMinor.ShapeType() == TopAbs_VERTEX ) {
      gp_Pnt aCenter = BRep_Tool::Pnt(TopoDS::Vertex(aShCenter));
      gp_Pnt aMajor = BRep_Tool::Pnt(TopoDS::Vertex(aShMajor));
      gp_Pnt aMinor = BRep_Tool::Pnt(TopoDS::Vertex(aShMinor));
      GC_MakeEllipse aEllipse( aMajor, aMinor, aCenter );
   	  if (!aEllipse.IsDone()) {
		StdFail_NotDone::Raise("Ellipse operation can not be performed on the given vertices");
	  }
      Handle_Geom_TrimmedCurve aCurve = new Geom_TrimmedCurve(aEllipse.Value(), .0, 2*PI, Standard_True);
      aShape = BRepBuilderAPI_MakeEdge( aCurve ).Edge();
    }
  }
  else {
  }

  if (aShape.IsNull()) return 0;

  aFunction->SetValue(aShape);

  log.SetTouched(Label()); 

  return 1;    
}