0022018: Select3D_SensitiveCircle::Matches(): DMin parameter left uninitialized
authorAAA <>
Fri, 18 Nov 2011 08:46:13 +0000 (08:46 +0000)
committerbugmaster <bugmaster@opencascade.com>
Mon, 5 Mar 2012 15:31:07 +0000 (19:31 +0400)
src/Select3D/Select3D_SensitiveCircle.cdl
src/Select3D/Select3D_SensitiveCircle.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx

index 5f9fc17..7da072d 100755 (executable)
@@ -22,7 +22,10 @@ uses
     HArray1OfPnt    from TColgp,
     Array1OfPnt2d   from TColgp,
     Box2d           from Bnd,
-    Location        from TopLoc
+    Location        from TopLoc,
+    Pnt             from Select3D, 
+    Pnt2d           from Select3D, 
+    Projector       from Select3D
 
 is
     Create (OwnerId      : EntityOwner from SelectBasics;
@@ -57,7 +60,8 @@ is
         -- owner OwnerId, the array of triangles apolyg3d, and the Boolean FilledCircle.
         -- apolyg3d is an array of consecutive triangles on the
         -- circle. The triangle i+1 lies on the intersection of the
-        -- tangents to the circle of i and i+2.
+        -- tangents to the circle of i and i+2. Note, that the first point of apolyg3d 
+        -- must be equal to the last point of apolyg3d. 
 
     Create(OwnerId  : EntityOwner from SelectBasics;
            apolyg3d : Array1OfPnt   from TColgp;
@@ -65,6 +69,8 @@ is
     returns mutable SensitiveCircle;
         ---Purpose: Constructs the sensitive circle object defined by the
         -- owner OwnerId, the array of points apolyg3d, and the Boolean FilledCircle.
+        -- If the length of apolyg3d is more then 1, the first point of apolyg3d 
+        -- must be equal to the last point of apolyg3d. 
 
     Matches(me  :mutable; 
             X,Y : Real from Standard;
@@ -98,10 +104,18 @@ is
 
     Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
 
+    Project(me: mutable;aProjector: Projector from Select3D) is redefined virtual;
+
+    ComputeCenter3D(me: mutable); 
+        ---Level: Internal 
+        ---Purpose: Computes myCenter3D as the barycenter of points from mypolyg3d
+
 fields
 
     myFillStatus    : Boolean;
     myDetectedIndex : Integer from Standard; -- used for depth...
+    myCenter2D      : Pnt2d from Select3D; -- used for Matches()
+    myCenter3D      : Pnt from Select3D; -- used for Matches()
     
 end SensitiveCircle;
 
index 21b1da0..1478e44 100755 (executable)
@@ -13,6 +13,7 @@
 #include <ElCLib.hxx>
 #include <Select3D_Pnt.hxx>
 #include <Select3D_Pnt2d.hxx>
+#include <Select3D_Projector.hxx>
 
 //=======================================================================
 //function : Select3D_SensitiveCircle (constructeur)
@@ -64,11 +65,18 @@ myDetectedIndex(-1)
       rank++;
       curu+=du;
     }
-    ((Select3D_Pnt*)mypolyg3d)[NbPoints*2] = ((Select3D_Pnt*)mypolyg3d)[0];
+    ((Select3D_Pnt*)mypolyg3d)[NbPoints*2] = ((Select3D_Pnt*)mypolyg3d)[0]; 
+    // Get myCenter3D 
+    myCenter3D = TheCircle->Location();
   }
   // Radius = 0.0
   else
+  {
     ((Select3D_Pnt*)mypolyg3d)[0] = TheCircle->Location();
+    // Get myCenter3D
+    myCenter3D = ((Select3D_Pnt*)mypolyg3d)[0];
+  }
+    
 }
 
 //=======================================================================
@@ -117,10 +125,16 @@ myDetectedIndex(-1)
       curu+=du;
     }
     TheCircle->D0(uend,p1);
-    ((Select3D_Pnt*)mypolyg3d)[NbPoints*2-2] = p1;            
+    ((Select3D_Pnt*)mypolyg3d)[NbPoints*2-2] = p1; 
+    // Get myCenter3D 
+    myCenter3D = TheCircle->Location();
   }
   else
-    ((Select3D_Pnt*)mypolyg3d)[0] = TheCircle->Location();                
+  {
+    ((Select3D_Pnt*)mypolyg3d)[0] = TheCircle->Location();  
+    // Get myCenter3D
+    myCenter3D = ((Select3D_Pnt*)mypolyg3d)[0];
+  }
 }
 
 //=======================================================================
@@ -134,15 +148,23 @@ Select3D_SensitivePoly(OwnerId, Thepolyg3d),
 myFillStatus(FilledCircle),
 myDetectedIndex(-1)
 {
-  
+  if (mynbpoints > 1) 
+    ComputeCenter3D();
+  else 
+    myCenter3D = ((Select3D_Pnt*)mypolyg3d)[0];
 }
+
 Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
                            const TColgp_Array1OfPnt& Thepolyg3d,
                            const Standard_Boolean FilledCircle):
 Select3D_SensitivePoly(OwnerId, Thepolyg3d),
 myFillStatus(FilledCircle),
 myDetectedIndex(-1)
-{
+{ 
+  if (mynbpoints > 1) 
+    ComputeCenter3D();
+  else 
+    myCenter3D = ((Select3D_Pnt*)mypolyg3d)[0];
 }
 
 Standard_Boolean Select3D_SensitiveCircle::
@@ -151,63 +173,53 @@ Matches(const Standard_Real X,
     const Standard_Real aTol, 
     Standard_Real& DMin)
 {
-  
 
-  // in case of Edge (for the face it is only checked if 
-  // the mouse point X,Y is found inside the triangle
-  // pi,pi+1,pi+2 with close tolerance... if yes, finish...
-  if(mynbpoints>1){
-    Standard_Boolean Found =Standard_False;
+  if(mynbpoints>1)
+  {
+    Standard_Boolean Found = Standard_False;
     Standard_Integer i = 0;
-    //gp_Pnt2d p1,p2,p3,pg;
     
-    if(!myFillStatus){
-      while(i < mynbpoints-2 && !Found) {
-    Standard_Integer TheStat = 
-      Select3D_SensitiveTriangle::Status(((Select3D_Pnt2d*)mypolyg2d)[i],
+    if(!myFillStatus)
+    {
+      while(i < mynbpoints-2 && !Found) 
+      { 
+        Standard_Integer TheStat = 
+          Select3D_SensitiveTriangle::Status(((Select3D_Pnt2d*)mypolyg2d)[i],
                          ((Select3D_Pnt2d*)mypolyg2d)[i+1],
                          ((Select3D_Pnt2d*)mypolyg2d)[i+2],
-                         gp_XY(X,Y),aTol,DMin);
-    Found = (TheStat!=2);
-    if(Found) myDetectedIndex=i;
-    i+=2;
-    
+                         gp_XY(X,Y),aTol,DMin); 
+        Found = (TheStat != 2); 
+        if(Found) myDetectedIndex = i; 
+        i += 2;
       }
     }
-    else {
+    else 
+    {
       myDetectedIndex =-1;
-#ifndef DEB
-      Standard_Real DMin2 = 0.;
-#else
-      Standard_Real DMin2;
-#endif
       Standard_Real Xmin,Ymin,Xmax,Ymax;
-      Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
-      if(!Bnd_Box2d(mybox2d).IsVoid())
-        DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus();
-      TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mynbpoints);
-      Points2D(aArrayOf2dPnt);
-      CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
-      Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,Y));
-      Standard_Real aTol2 = aTol*aTol;
-      if(TheStat!=1) {
-       for(Standard_Integer I=0;i<mynbpoints-1;i+=2){
-         gp_XY V1(((Select3D_Pnt2d*)mypolyg2d)[I+1]),V(X,Y);
-         V1-=((Select3D_Pnt2d*)mypolyg2d)[I];
-         V-=((Select3D_Pnt2d*)mypolyg2d)[I];
-         Standard_Real Vector = V1^V;
-         Standard_Real V1V1 = V1.SquareModulus();
-         DMin2 = 
-           (V1V1 <=aTol2) ? 
-             Min(DMin2,V.SquareModulus()): // if the segment is too small...
-               Min(DMin2,Vector*Vector/V1V1);
-         
-       }
-       Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-       return Standard_True;
-      }
-      return Standard_False;
+
+      // Get coordinates of the bounding box
+      Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax); 
+      TColgp_Array1OfPnt2d anArrayOf2dPnt(1, mynbpoints); 
+      
+      // Fill anArrayOf2dPnt with points from mypolig2d
+      Points2D(anArrayOf2dPnt); 
       
+      CSLib_Class2d anInOutTool(anArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
+
+      // Method SiDans returns the status :
+      //  1 - the point is inside the circle 
+      //  0 - the point is on the circle
+      // -1 - the point is outside the circle
+      Standard_Integer aStat = anInOutTool.SiDans(gp_Pnt2d(X,Y));
+      if(aStat != -1) 
+      {
+        // Compute DMin (a distance between the center and the point)
+        DMin = gp_XY(myCenter2D.x - X, myCenter2D.y - Y).Modulus();
+        Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); 
+        return Standard_True;
+      }
+      return Standard_False;  
     }
     if(!Found) 
       myDetectedIndex=-1;
@@ -219,6 +231,7 @@ Matches(const Standard_Real X,
   return Standard_True;
 
 }
+
 Standard_Boolean Select3D_SensitiveCircle::
 Matches(const Standard_Real XMin,
     const Standard_Real YMin,
@@ -343,3 +356,40 @@ Standard_Real Select3D_SensitiveCircle::ComputeDepth(const gp_Lin& EyeLine) cons
   return  ElCLib::Parameter(EyeLine,CDG);
   
 }
+
+void Select3D_SensitiveCircle::Project(const Handle_Select3D_Projector &aProjector) 
+{
+  Select3D_SensitivePoly::Project(aProjector); 
+  // Project the center of the circle 
+  gp_Pnt2d aCenter;
+  aProjector->Project(myCenter3D, aCenter);
+  myCenter2D = aCenter;
+}
+
+void Select3D_SensitiveCircle::ComputeCenter3D() 
+{
+  gp_XYZ aCenter(0., 0., 0.);
+  if (mynbpoints > 1) 
+  {
+    // The mass of points system
+    Standard_Integer aMass = mynbpoints - 1; 
+    // Find the circle barycenter
+    for (Standard_Integer i = 0; i < mynbpoints-1; ++i) 
+    {
+      aCenter += ((Select3D_Pnt*)mypolyg3d)[i];
+    }
+    myCenter3D = aCenter / aMass;
+  }
+  else if (mynbpoints == 1) 
+  {
+    myCenter3D = ((Select3D_Pnt*)mypolyg3d)[0];
+  }
+  // bad case! there are no points in mypolyg3d 
+  // It can lead to incorrect computation of 
+  // parameter DMin in method Matches. 
+  // In spite of this myCenter3D isn't left uninitialized
+  else 
+  { 
+    myCenter3D = aCenter;
+  }
+}
index 98f06a7..83cacf0 100755 (executable)
 #include <Graphic3d_Group.hxx>
 #include <Standard_Real.hxx>
 
+#include <AIS_Circle.hxx>
+#include <AIS_Drawer.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <Geom_Circle.hxx>
+#include <GC_MakeCircle.hxx>
+#include <Prs3d_Presentation.hxx>
+#include <Select3D_SensitiveCircle.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <StdFail_NotDone.hxx>
+#include <StdPrs_ShadedShape.hxx>
+#include <TopoDS_Wire.hxx>
+
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
 #endif
@@ -1656,6 +1671,107 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
   return 0;
 }
 
+//==============================================================================
+// class   : FilledCircle
+// purpose : creates filled circle based on AIS_InteractiveObject 
+//           and Geom_Circle.
+//           This class is used to check method Matches() of class 
+//           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
+//           because none of AIS classes provides creation of 
+//           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
+//           (look method ComputeSelection() )
+//============================================================================== 
+
+Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
+{
+  gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
+  gp_Circ aCirc(anAxes, theRadius);
+  Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
+  return aCircle;
+}
+
+DEFINE_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
+
+class FilledCircle : public AIS_InteractiveObject 
+{
+public:
+    // CASCADE RTTI
+    DEFINE_STANDARD_RTTI(FilledCircle); 
+
+    FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
+    FilledCircle(Handle(Geom_Circle) theCircle);
+
+private:
+    TopoDS_Face ComputeFace();
+
+    // Virtual methods implementation
+    void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
+                  const Handle(Prs3d_Presentation)& thePresentation,
+                  const Standard_Integer theMode);
+
+    void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
+                           const Standard_Integer theMode);
+
+protected:
+    Handle(Geom_Circle) myCircle;
+    Standard_Boolean myFilledStatus;
+
+}; 
+
+IMPLEMENT_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
+IMPLEMENT_STANDARD_RTTIEXT(FilledCircle, AIS_InteractiveObject)
+
+FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
+{
+  myCircle = CreateCircle(theCenter, theRadius);
+  myFilledStatus = Standard_True;
+}
+
+FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
+{
+  myCircle = theCircle;
+  myFilledStatus = Standard_True;
+}
+
+TopoDS_Face FilledCircle::ComputeFace() 
+{
+  // Create edge from myCircle 
+  BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
+  TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
+
+  // Create wire from anEdge 
+  BRepBuilderAPI_MakeWire aWireMaker(anEdge);
+  TopoDS_Wire aWire = aWireMaker.Wire();
+
+  // Create face from aWire
+  BRepBuilderAPI_MakeFace aFaceMaker(aWire);
+  TopoDS_Face aFace = aFaceMaker.Face();
+
+  return aFace;
+}
+
+void FilledCircle::Compute(const Handle_PrsMgr_PresentationManager3d &thePresentationManager, 
+                           const Handle_Prs3d_Presentation &thePresentation, 
+                           const Standard_Integer theMode) 
+{
+  thePresentation->Clear();
+
+  TopoDS_Face aFace = ComputeFace();
+
+  if (aFace.IsNull()) return;
+  if (theMode != 0) return;
+
+  StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
+}
+
+void FilledCircle::ComputeSelection(const Handle_SelectMgr_Selection &theSelection, 
+                                    const Standard_Integer theMode)
+{
+  Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
+  Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
+      myCircle, myFilledStatus);
+  theSelection->Add(aSensitiveCircle);
+}
 
 //==============================================================================
 // Fonction  vcircle
@@ -1665,260 +1781,378 @@ static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char*
 //==============================================================================
 //function : VCircleBuilder
 //purpose  : Build an AIS_Circle
-//Draw arg : vcircle CircleName PlaneName PointName Radius
-//                              PointName PointName PointName
+//Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
+//                              PointName PointName PointName IsFilled
 //==============================================================================
-#include <Geom_CartesianPoint.hxx>
-#include <Geom_Circle.hxx>
-#include <AIS_Circle.hxx>
-#include <GC_MakeCircle.hxx>
-#include <Geom_Plane.hxx>
-#include <gp_Pln.hxx>
+
+void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
+                    TCollection_AsciiString theName, 
+                    Standard_Boolean isFilled) 
+{
+  Handle(AIS_InteractiveObject) aCircle;
+  if (isFilled) 
+  {
+    aCircle = new FilledCircle(theGeomCircle);
+  }
+  else
+  {
+    aCircle = new AIS_Circle(theGeomCircle);
+  }
+
+  // Check if there is an object with given name
+  // and remove it from context
+  if (GetMapOfAIS().IsBound2(theName)) 
+  {
+    Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
+    Handle(AIS_InteractiveObject) anInterObj = 
+         Handle(AIS_InteractiveObject)::DownCast(anObj);
+    TheAISContext()->Remove(anInterObj, Standard_False);
+    GetMapOfAIS().UnBind2(theName);
+   }
+
+   // Bind the circle to its name
+   GetMapOfAIS().Bind(aCircle, theName);
+
+   // Display the circle
+   TheAISContext()->Display(aCircle);
+  
+}
 
 static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
   Standard_Integer myCurrentIndex;
-  // verification of the arguments
-  if (argc>5 ||  argc<2 ) {di<<"vcircle error: expect 3 arguments."<<"\n";return 1; }
+  // Verification of the arguments
+  if (argc>6 || argc<2) 
+  { 
+    std::cout << "vcircle error: expect 4 arguments.\n"; 
+    return 1; // TCL_ERROR 
+  }
   TheAISContext()->CloseAllContexts();
 
-  // Il y a des arguments
-  if (argc==5 ) {
+  // There are all arguments
+  if (argc == 6) 
+  {
+    // Get arguments
+    TCollection_AsciiString aName(argv[1]);
+    Standard_Boolean isFilled = (Standard_Boolean)atoi(argv[5]);
+
     Handle(AIS_InteractiveObject) theShapeA;
     Handle(AIS_InteractiveObject) theShapeB;
 
-    theShapeA=
-      Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
-    theShapeB=
-      Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
+    theShapeA =
+      Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
+    theShapeB =
+      Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
+
 
     // Arguments: AIS_Point AIS_Point AIS_Point
     // ========================================
-    if (!theShapeA.IsNull() && theShapeB.IsNull() &&
+    if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
     {
-      if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) {
-        di<<"vcircle error: 2de argument is unexpected to be a point."<<"\n";
-        return 1;
+      if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
+      {
+        std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
+        return 1; // TCL_ERROR 
       }
-      // Le troisieme objet doit etre un point
+      // The third object must be a point
       Handle(AIS_InteractiveObject) theShapeC =
-        Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
+        Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
       if (theShapeC.IsNull() ||
-        theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) {
-          di<<"vcircle error: 3de argument is unexpected to be a point."<<"\n";
-          return 1;
-        }
+        theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
+      {
+        std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
+        return 1; // TCL_ERROR 
+      }
         // tag
-        // On verifie que les 3 points sont differents.
-        Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA;
-        Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB;
-        Handle(AIS_Point) theAISPointC= *(Handle(AIS_Point)*)& theShapeC;
-
-        Handle(Geom_Point ) myGeomPointA=  theAISPointA->Component();
-        Handle(Geom_CartesianPoint ) myCartPointA= *((Handle(Geom_CartesianPoint)*)&  myGeomPointA);
-
-        Handle(Geom_Point ) myGeomPointB =  theAISPointB->Component();
-        Handle(Geom_CartesianPoint ) myCartPointB= *((Handle(Geom_CartesianPoint)*)&  theAISPointB);
-
-        Handle(Geom_Point ) myGeomPointBC=  theAISPointC->Component();
-        Handle(Geom_CartesianPoint ) myCartPointC= *((Handle(Geom_CartesianPoint)*)&  theAISPointC);
+        // Verify that the three points are different
+        Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
+        Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
+        Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
+        
+        Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
+        Handle(Geom_CartesianPoint) myCartPointA = 
+          Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
+
+        Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
+        Handle(Geom_CartesianPoint) myCartPointB =
+          Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
+
+        Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
+        Handle(Geom_CartesianPoint) myCartPointC =
+          Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
 
         // Test A=B
-        if (myCartPointA->X()==myCartPointB->X() && myCartPointA->Y()==myCartPointB->Y() && myCartPointA->Z()==myCartPointB->Z()  ) {
-          di<<"vcircle error: Same points."<<"\n";return 1;
+        if (abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
+          abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
+          abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
+        {
+          std::cout << "vcircle error: Same points.\n"; 
+          return 1; // TCL_ERROR 
         }
         // Test A=C
-        if (myCartPointA->X()==myCartPointC->X() && myCartPointA->Y()==myCartPointC->Y() && myCartPointA->Z()==myCartPointC->Z()  ) {
-          di<<"vcircle error: Same points."<<"\n";return 1;
+        if (abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
+          abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
+          abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
+        {
+          std::cout << "vcircle error: Same points.\n"; 
+          return 1; // TCL_ERROR 
         }
         // Test B=C
-        if (myCartPointB->X()==myCartPointC->X() && myCartPointB->Y()==myCartPointC->Y() && myCartPointB->Z()==myCartPointC->Z()  ) {
-          di<<"vcircle error: Same points."<<"\n";return 1;
+        if (abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
+          abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
+          abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
+        {
+          std::cout << "vcircle error: Same points.\n"; 
+          return 1;// TCL_ERROR 
         }
-        // Construction du cercle
-        GC_MakeCircle Cir=GC_MakeCircle (myCartPointA->Pnt(),myCartPointB->Pnt(),myCartPointC->Pnt() );
-        Handle (Geom_Circle) theGeomCircle=Cir.Value();
-        Handle(AIS_Circle) theAISCircle=new AIS_Circle(theGeomCircle );
-        GetMapOfAIS().Bind(theAISCircle,argv[1] );
-        TheAISContext()->Display(theAISCircle );
-
+        // Construction of the circle
+        GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
+          myCartPointB->Pnt(), myCartPointC->Pnt() );
+        Handle (Geom_Circle) theGeomCircle;
+        try 
+        {
+          theGeomCircle = Cir.Value();
+        }
+        catch (StdFail_NotDone)
+        {
+          std::cout << "vcircle error: can't create circle\n";
+          return -1; // TCL_ERROR
+        }
+        
+        DisplayCircle(theGeomCircle, aName, isFilled);
     }
 
-    // Arguments: ASI_Plane AIS_Point Real
+    // Arguments: AIS_Plane AIS_Point Real
     // ===================================
-    else if (theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==7 ) {
-      if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) {
-        di<<"vcircle error: 2de element is a unexpected to be a point."<<"\n";return 1;
+    else if (theShapeA->Type() == AIS_KOI_Datum && 
+      theShapeA->Signature() == 7 ) 
+    {
+      if (theShapeB->Type() != AIS_KOI_Datum || 
+        theShapeB->Signature() != 1 ) 
+      {
+        std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
+        return 1; // TCL_ERROR 
+      }
+      // Ñheck that the radius is >= 0
+      if (atof(argv[4]) <= 0 ) 
+      {
+        std::cout << "vcircle error: the radius must be >=0.\n"; 
+        return 1; // TCL_ERROR 
       }
-      // On verifie que le rayon est bien >=0
-      if (atof(argv[4])<=0 ) {di<<"vcircle error: the radius must be >=0."<<"\n";return 1;  }
-
-      // On recupere la normale au Plane.
-      Handle(AIS_Plane) theAISPlane= *(Handle(AIS_Plane)*)& theShapeA;
-      Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB;
 
+      // Recover the normal to the plane
+      Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
+      Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
 
-      //      Handle(Geom_Plane ) myGeomPlane= *(Handle(Geom_Plane)*)& (theAISPlane->Component() );
-      Handle(Geom_Plane ) myGeomPlane= theAISPlane->Component();
-      Handle(Geom_Point ) myGeomPointB =  theAISPointB->Component();
-      Handle(Geom_CartesianPoint ) myCartPointB= *((Handle(Geom_CartesianPoint)*)&  theAISPointB);
+      Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
+      Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
+      Handle(Geom_CartesianPoint) myCartPointB = 
+        Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
 
       gp_Pln mygpPlane = myGeomPlane->Pln();
       gp_Ax1 thegpAxe = mygpPlane.Axis();
       gp_Dir theDir = thegpAxe.Direction();
-      gp_Pnt theCenter=myCartPointB->Pnt();
+      gp_Pnt theCenter = myCartPointB->Pnt();
       Standard_Real TheR = atof(argv[4]);
-      GC_MakeCircle Cir=GC_MakeCircle (theCenter, theDir ,TheR);
-      Handle (Geom_Circle) theGeomCircle=Cir.Value();
-      Handle(AIS_Circle) theAISCircle=new AIS_Circle(theGeomCircle );
-      GetMapOfAIS().Bind(theAISCircle,argv[1] );
-      TheAISContext()->Display(theAISCircle );
+      GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
+      Handle (Geom_Circle) theGeomCircle;
+      try 
+      {
+        theGeomCircle = Cir.Value();
+      }
+      catch (StdFail_NotDone)
+      {
+        std::cout << "vcircle error: can't create circle\n";
+        return -1; // TCL_ERROR
+      }
+
+      DisplayCircle(theGeomCircle, aName, isFilled);
 
     }
 
     // Error
-    else{
-      di<<"vcircle error: !st argument is a unexpected type."<<"\n";return 1;
+    else
+    {
+      std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
+      return 1; // TCL_ERROR 
     }
 
   }
-  // Pas d'arguments: selection dans le viewer
+  // No arguments: selection in the viewer
   // =========================================
-  else {
+  else 
+  {
+    // Get the name of the circle 
+    TCollection_AsciiString aName(argv[1]);
 
     TheAISContext()->OpenLocalContext();
-    myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
+    myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
 
-    // Active le mode Vertex et face.
+    // Activate selection mode for vertices and faces
     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
-    di<<" Select a vertex or a face."<<"\n";
+    std::cout << " Select a vertex or a face.\n";
 
-    // Boucle d'attente waitpick.
+    // Wait for picking
     Standard_Integer argcc = 5;
     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
     const char **argvv = (const char **) buff;
     while (ViewerMainLoop( argcc, argvv) ) { }
-    // fin de la boucle
+    // end of the loop
 
     TopoDS_Shape ShapeA;
-    for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
+    for(TheAISContext()->InitSelected(); 
+      TheAISContext()->MoreSelected(); 
+      TheAISContext()->NextSelected() ) 
+    {
       ShapeA = TheAISContext()->SelectedShape();
     }
 
-    // ShapeA est un Vertex
-    if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
+    // ShapeA is a Vertex
+    if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
+    {
       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
-      di<<" Select a different vertex."<<"\n";
+      std::cout << " Select a different vertex.\n";
 
       TopoDS_Shape ShapeB;
-      do {
-
-        // Boucle d'attente waitpick.
+      do 
+      {
+        // Wait for picking
         Standard_Integer argccc = 5;
         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
         const char **argvvv = (const char **) bufff;
         while (ViewerMainLoop( argccc, argvvv) ) { }
-        // fin de la boucle
+        // end of the loop
 
-        for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
+        for(TheAISContext()->InitSelected(); 
+          TheAISContext()->MoreSelected(); 
+          TheAISContext()->NextSelected() ) 
+        {
           ShapeB = TheAISContext()->SelectedShape();
         }
-
-
       } while(ShapeB.IsSame(ShapeA) );
 
-      // Selection de ShapeC
-      di<<" Select the last vertex."<<"\n";
+      // Selection of ShapeC
+      std::cout << " Select the last vertex.\n";
       TopoDS_Shape ShapeC;
-      do {
-
-        // Boucle d'attente waitpick.
+      do 
+      {
+        // Wait for picking
         Standard_Integer argcccc = 5;
         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
         const char **argvvvv = (const char **) buffff;
         while (ViewerMainLoop( argcccc, argvvvv) ) { }
-        // fin de la boucle
+        // end of the loop
 
-        for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
+        for(TheAISContext()->InitSelected(); 
+          TheAISContext()->MoreSelected(); 
+          TheAISContext()->NextSelected() ) 
+        {
           ShapeC = TheAISContext()->SelectedShape();
         }
-
-
       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
+      
+      // Get isFilled
+      Standard_Boolean isFilled;
+      std::cout << "Enter filled status (0 or 1)\n";
+      cin >> isFilled;
 
-      // Fermeture du context local
+      // Close the local context
       TheAISContext()->CloseLocalContext(myCurrentIndex);
 
-      // Construction du cercle
-      gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
-      gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
-      gp_Pnt   C=BRep_Tool::Pnt(TopoDS::Vertex(ShapeC)  );
+      // Construction of the circle
+      gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
+      gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
+      gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
+
+      GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
+      Handle (Geom_Circle) theGeomCircle;
+      try 
+      {
+        theGeomCircle = Cir.Value();
+      }
+      catch (StdFail_NotDone)
+      {
+        std::cout << "vcircle error: can't create circle\n";
+        return -1; // TCL_ERROR
+      }
 
-      GC_MakeCircle Cir=GC_MakeCircle (A,B,C );
-      Handle (Geom_Circle) theGeomCircle=Cir.Value();
-      Handle(AIS_Circle) theAISCircle=new AIS_Circle(theGeomCircle );
-      GetMapOfAIS().Bind(theAISCircle,argv[1] );
-      TheAISContext()->Display(theAISCircle );
+      DisplayCircle(theGeomCircle, aName, isFilled);
 
     }
-    // ShapeA est une face.
-    else  {
-      di<<" Select a vertex (in your face)."<<"\n";
+    // Shape is a face
+    else  
+    {
+      std::cout << " Select a vertex (in your face).\n";
       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
 
       TopoDS_Shape ShapeB;
-      // Boucle d'attente waitpick.
+      // Wait for picking
       Standard_Integer argccc = 5;
       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
       const char **argvvv = (const char **) bufff;
       while (ViewerMainLoop( argccc, argvvv) ) { }
-      // fin de la boucle
+      // end of the loop
 
-      for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
+      for(TheAISContext()->InitSelected(); 
+        TheAISContext()->MoreSelected(); 
+        TheAISContext()->NextSelected() ) 
+      {
         ShapeB = TheAISContext()->SelectedShape();
       }
 
-      // Recuperation du rayon.
-      Standard_Integer theRad;
-      do {
-        di<<" Enter the value of the radius:"<<"\n";
-        cin>>theRad;
-      } while (theRad<=0);
+      // Recover the radius 
+      Standard_Real theRad;
+      do 
+      {
+        std::cout << " Enter the value of the radius:\n";
+        cin >> theRad;
+      } while (theRad <= 0);
+      
+      // Get filled status
+      Standard_Boolean isFilled;
+      std::cout << "Enter filled status (0 or 1)\n";
+      cin >> isFilled;
 
-      // Fermeture du context local
+      // Close the local context
       TheAISContext()->CloseLocalContext(myCurrentIndex);
-      // Construction du cercle.
+      // Construction of the circle
 
-      // On recupere la normale au Plane. tag
-      TopoDS_Face myFace=TopoDS::Face(ShapeA);
-      BRepAdaptor_Surface mySurface (myFace, Standard_False );
-      gp_Pln myPlane=mySurface.Plane();
-      Handle(Geom_Plane) theGeomPlane=new Geom_Plane (myPlane );
+      // Recover the normal to the plane. tag
+      TopoDS_Face myFace = TopoDS::Face(ShapeA);
+      BRepAdaptor_Surface mySurface (myFace, Standard_False);
+      gp_Pln myPlane = mySurface.Plane();
+      Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
       gp_Pln mygpPlane = theGeomPlane->Pln();
       gp_Ax1 thegpAxe = mygpPlane.Axis();
       gp_Dir theDir = thegpAxe.Direction();
 
-      // On recupere le centre.
-      gp_Pnt   theCenter=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
+      // Recover the center
+      gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
 
-      // On construit l'AIS_Circle
-      GC_MakeCircle Cir=GC_MakeCircle (theCenter, theDir ,theRad  );
-      Handle (Geom_Circle) theGeomCircle=Cir.Value();
-      Handle(AIS_Circle) theAISCircle=new AIS_Circle(theGeomCircle );
-      GetMapOfAIS().Bind(theAISCircle,argv[1] );
-      TheAISContext()->Display(theAISCircle );
+      // Ñonstruct the circle
+      GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
+      Handle (Geom_Circle) theGeomCircle;
+      try 
+      {
+        theGeomCircle = Cir.Value();
+      }
+      catch (StdFail_NotDone)
+      {
+        std::cout << "vcircle error: can't create circle\n";
+        return -1; // TCL_ERROR
+      }
 
+      DisplayCircle(theGeomCircle, aName, isFilled);
+      
     }
 
-
   }
 
   return 0;
 }
 
-
 //===============================================================================================
 //function : VDrawText
 //author   : psn
@@ -1941,12 +2175,9 @@ static int VCircleBuilder(Draw_Interpretor& di, Standard_Integer argc, const cha
 
 #include <Standard_DefineHandle.hxx>
 
-#include <AIS_Drawer.hxx>
-
 #include <Prs3d_Root.hxx>
 #include <Prs3d_Text.hxx>
 #include <Prs3d_TextAspect.hxx>
-#include <Prs3d_Presentation.hxx>
 #include <Prs3d_ShadingAspect.hxx>
 #include <PrsMgr_PresentationManager3d.hxx>
 
@@ -2178,7 +2409,6 @@ static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char**
 #include <TColgp_Array1OfDir.hxx>
 #include <Graphic3d_GraphicDriver.hxx>
 
-#include <AIS_Drawer.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 #include <Prs3d_ShadingAspect.hxx>
@@ -3312,7 +3542,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     __FILE__,VLineBuilder,group);
 
   theCommands.Add("vcircle",
-    "vcircle CircleName [PointName/PlaneName] [PointName] [Radius] ",
+    "vcircle CircleName [PointName PointName PointName IsFilled]\n\t\t\t\t\t[PlaneName PointName Radius IsFilled]",
     __FILE__,VCircleBuilder,group);
 
   theCommands.Add("vdrawtext",