0027764: Visualization - add functionality for animation of 3D camera and interactive...
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
1 // Created on: 1998-11-12
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ViewerTest.hxx>
18
19 #include <Quantity_NameOfColor.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <Draw.hxx>
22 #include <Draw_Appli.hxx>
23 #include <DBRep.hxx>
24
25 #include <Font_BRepFont.hxx>
26 #include <Font_BRepTextBuilder.hxx>
27 #include <Font_FontMgr.hxx>
28 #include <OSD_Chronometer.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <V3d_Viewer.hxx>
31 #include <V3d_View.hxx>
32 #include <V3d.hxx>
33
34 #include <AIS_Shape.hxx>
35 #include <AIS_DisplayMode.hxx>
36 #include <AIS_PointCloud.hxx>
37 #include <TColStd_MapOfInteger.hxx>
38 #include <AIS_MapOfInteractive.hxx>
39 #include <ViewerTest_AutoUpdater.hxx>
40 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
41 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
42 #include <ViewerTest_EventManager.hxx>
43
44 #include <TopoDS_Solid.hxx>
45 #include <BRepTools.hxx>
46 #include <BRep_Builder.hxx>
47 #include <TopAbs_ShapeEnum.hxx>
48
49 #include <TopoDS.hxx>
50 #include <BRep_Tool.hxx>
51 #include <TopExp_Explorer.hxx>
52
53 #include <BRepAdaptor_Curve.hxx>
54 #include <BRepAdaptor_Surface.hxx>
55
56 #include <TopAbs.hxx>
57 #include <TopExp.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Face.hxx>
61
62 #include <Draw_Window.hxx>
63 #include <AIS_ListIteratorOfListOfInteractive.hxx>
64 #include <AIS_ListOfInteractive.hxx>
65 #include <AIS_DisplayMode.hxx>
66 #include <AIS_Shape.hxx>
67
68 #include <AIS_InteractiveContext.hxx>
69 #include <Geom_Plane.hxx>
70 #include <gp_Pln.hxx>
71 #include <TCollection_ExtendedString.hxx>
72 #include <TCollection_HAsciiString.hxx>
73 #include <GC_MakePlane.hxx>
74 #include <gp_Circ.hxx>
75 #include <AIS_Axis.hxx>
76 #include <Geom_Axis2Placement.hxx>
77 #include <Geom_Axis1Placement.hxx>
78 #include <AIS_Trihedron.hxx>
79 #include <AIS_Axis.hxx>
80 #include <gp_Trsf.hxx>
81 #include <gp_Quaternion.hxx>
82 #include <TopLoc_Location.hxx>
83
84 #include <HLRAlgo_Projector.hxx>
85 #include <HLRBRep_PolyAlgo.hxx>
86 #include <HLRBRep_PolyHLRToShape.hxx>
87 #include <Aspect_Window.hxx>
88
89 #include <Graphic3d_ArrayOfPoints.hxx>
90 #include <Graphic3d_ArrayOfSegments.hxx>
91 #include <Graphic3d_ArrayOfPolylines.hxx>
92 #include <Graphic3d_ArrayOfTriangles.hxx>
93 #include <Graphic3d_ArrayOfTriangleFans.hxx>
94 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
95 #include <Graphic3d_ArrayOfQuadrangles.hxx>
96 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
97 #include <Graphic3d_ArrayOfPolygons.hxx>
98 #include <Graphic3d_AspectMarker3d.hxx>
99 #include <Graphic3d_Group.hxx>
100 #include <Standard_Real.hxx>
101
102 #include <AIS_Circle.hxx>
103 #include <BRepBuilderAPI_MakeEdge.hxx>
104 #include <BRepBuilderAPI_MakeFace.hxx>
105 #include <BRepBuilderAPI_MakeWire.hxx>
106 #include <Geom_Circle.hxx>
107 #include <GC_MakeCircle.hxx>
108 #include <Prs3d_Presentation.hxx>
109 #include <Select3D_SensitiveCircle.hxx>
110 #include <SelectMgr_EntityOwner.hxx>
111 #include <SelectMgr_Selection.hxx>
112 #include <StdFail_NotDone.hxx>
113 #include <StdPrs_ShadedShape.hxx>
114 #include <TopoDS_Wire.hxx>
115
116 #include <AIS_MultipleConnectedInteractive.hxx>
117 #include <AIS_ConnectedInteractive.hxx>
118 #include <AIS_TextLabel.hxx>
119 #include <TopLoc_Location.hxx>
120 #include <TColStd_ListOfInteger.hxx>
121 #include <TColStd_ListIteratorOfListOfInteger.hxx>
122
123 #include <Select3D_SensitiveTriangle.hxx>
124 #include <Select3D_SensitiveCurve.hxx>
125 #include <Select3D_SensitivePoint.hxx>
126 #include <BRepAdaptor_Curve.hxx>
127 #include <StdPrs_Curve.hxx>
128
129 #include <BRepExtrema_ExtPC.hxx>
130 #include <BRepExtrema_ExtPF.hxx>
131
132 #include <Prs3d_DatumAspect.hxx>
133 #include <Prs3d_Drawer.hxx>
134 #include <Prs3d_VertexDrawMode.hxx>
135 #include <Prs3d_LineAspect.hxx>
136 #include <Prs3d_PointAspect.hxx>
137 #include <Prs3d_TextAspect.hxx>
138
139 #include <Image_AlienPixMap.hxx>
140 #include <TColStd_HArray1OfAsciiString.hxx>
141 #include <TColStd_HSequenceOfAsciiString.hxx>
142
143 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
144 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
145                                            const Handle(AIS_InteractiveObject)& theAISObj,
146                                            Standard_Boolean theReplaceIfExists = Standard_True);
147 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
148 extern Handle(AIS_InteractiveContext)& TheAISContext();
149
150
151 //==============================================================================
152 //function : Vtrihedron 2d
153 //purpose  : Create a plane with a 2D  trihedron from a faceselection
154 //Draw arg : vtri2d  name
155 //==============================================================================
156 #include <AIS_PlaneTrihedron.hxx>
157
158
159
160 static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
161
162 {
163   // Verification des arguments
164   if ( argc!=2) {di<<argv[0]<<" error\n"; return 1;}
165
166   // Declarations
167   Standard_Integer myCurrentIndex;
168   // Fermeture des contextes
169   TheAISContext()->CloseAllContexts();
170   // Ouverture d'un contexte local et recuperation de son index.
171   TheAISContext()->OpenLocalContext();
172   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
173   // On active les modes de selections faces.
174   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
175   di<<" Select a face .\n";
176
177   // Boucle d'attente waitpick.
178   Standard_Integer argccc = 5;
179   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
180   const char **argvvv = (const char **) bufff;
181   while (ViewerMainLoop( argccc, argvvv) ) { }
182   // fin de la boucle
183
184   TopoDS_Shape ShapeB;
185   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
186     ShapeB = TheAISContext()->SelectedShape();
187   }
188
189   TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
190
191   // Construction du Plane
192   // recuperation des edges des faces.
193   TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
194
195   TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
196   // declarations
197   gp_Pnt A,B,C;
198
199   // si il y a plusieurs edges
200   if (FaceExpB.More() ) {
201     FaceExpB.Next();
202     TopoDS_Edge EdgeC=TopoDS::Edge(FaceExpB.Current() );
203     BRepAdaptor_Curve theCurveB(EdgeB);
204     BRepAdaptor_Curve theCurveC(EdgeC);
205     A=theCurveC.Value(0.1);
206     B=theCurveC.Value(0.9);
207     C=theCurveB.Value(0.5);
208   }
209   else {
210     // FaceB a 1 unique edge courbe
211     BRepAdaptor_Curve theCurveB(EdgeB);
212     A=theCurveB.Value(0.1);
213     B=theCurveB.Value(0.9);
214     C=theCurveB.Value(0.5);
215   }
216   // Construction du Geom_Plane
217   GC_MakePlane MkPlane(A,B,C);
218   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
219
220   // Construction de l'AIS_PlaneTrihedron
221   Handle(AIS_PlaneTrihedron) theAISPlaneTri= new AIS_PlaneTrihedron(theGeomPlane );
222
223   // Fermeture du contexte local.
224   TheAISContext()->CloseLocalContext(myCurrentIndex);
225
226   // on le display & bind
227   TheAISContext()->Display(theAISPlaneTri );
228   GetMapOfAIS().Bind ( theAISPlaneTri ,argv[1]);
229
230   return 0;
231 }
232
233
234
235 //==============================================================================
236 //function : VTriherdron
237 //purpose  : Create a trihedron. If no arguments are set, the default
238 //           trihedron (Oxyz) is created.
239 //Draw arg : vtrihedron  name  [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw]
240 //==============================================================================
241
242 static int VTrihedron (Draw_Interpretor& /*theDi*/,
243                        Standard_Integer  theArgsNb,
244                        const char**      theArgVec)
245 {
246   if (theArgsNb < 2 || theArgsNb > 11)
247   {
248     std::cout << theArgVec[0] << " syntax error\n";
249     return 1;
250   }
251
252   // Parse parameters
253   NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
254   TCollection_AsciiString aParseKey;
255   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
256   {
257     TCollection_AsciiString anArg (theArgVec [anArgIt]);
258
259     if (anArg.Value (1) == '-' && !anArg.IsRealValue())
260     {
261       aParseKey = anArg;
262       aParseKey.Remove (1);
263       aParseKey.LowerCase();
264       aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString);
265       continue;
266     }
267
268     if (aParseKey.IsEmpty())
269     {
270       continue;
271     }
272
273     aMapOfArgs(aParseKey)->Append (anArg);
274   }
275
276   // Check parameters
277   if ( (aMapOfArgs.IsBound ("xaxis") && !aMapOfArgs.IsBound ("zaxis"))
278     || (!aMapOfArgs.IsBound ("xaxis") && aMapOfArgs.IsBound ("zaxis")) )
279   {
280     std::cout << theArgVec[0] << " error: -xaxis and -yaxis parameters are to set together.\n";
281     return 1;
282   }
283
284   for (NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)>::Iterator aMapIt (aMapOfArgs);
285        aMapIt.More(); aMapIt.Next())
286   {
287     const TCollection_AsciiString& aKey = aMapIt.Key();
288     const Handle(TColStd_HSequenceOfAsciiString)& anArgs = aMapIt.Value();
289
290     // Bool key, without arguments
291     if (aKey.IsEqual ("hidelabels") && anArgs->IsEmpty())
292     {
293       continue;
294     }
295
296     if ( (aKey.IsEqual ("xaxis") || aKey.IsEqual ("zaxis") || aKey.IsEqual ("origin")) && anArgs->Length() == 3
297       && anArgs->Value(1).IsRealValue() && anArgs->Value(2).IsRealValue() && anArgs->Value(3).IsRealValue() )
298     {
299       continue;
300     }
301   }
302
303   // Process parameters
304   gp_Pnt anOrigin (0.0, 0.0, 0.0);
305   gp_Dir aDirZ = gp::DZ();
306   gp_Dir aDirX = gp::DX();
307
308   Handle(TColStd_HSequenceOfAsciiString) aValues;
309
310   if (aMapOfArgs.Find ("origin", aValues))
311   {
312     anOrigin.SetX (aValues->Value(1).RealValue());
313     anOrigin.SetY (aValues->Value(2).RealValue());
314     anOrigin.SetZ (aValues->Value(3).RealValue());
315   }
316
317   Handle(TColStd_HSequenceOfAsciiString) aValues2;
318   if (aMapOfArgs.Find ("xaxis", aValues) && aMapOfArgs.Find ("zaxis", aValues2))
319   {
320     Standard_Real aX = aValues->Value(1).RealValue();
321     Standard_Real aY = aValues->Value(2).RealValue();
322     Standard_Real aZ = aValues->Value(3).RealValue();
323     aDirX.SetCoord (aX, aY, aZ);
324
325     aX = aValues->Value(1).RealValue();
326     aY = aValues->Value(2).RealValue();
327     aZ = aValues->Value(3).RealValue();
328     aDirZ.SetCoord (aX, aY, aZ);
329   }
330
331   if (!aDirZ.IsNormal (aDirX, M_PI / 180.0))
332   {
333     std::cout << theArgVec[0] << " error - VectorX is not normal to VectorZ\n";
334     return 1;
335   }
336
337   Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (anOrigin, aDirZ, aDirX);
338   Handle(AIS_Trihedron) aShape = new AIS_Trihedron (aPlacement);
339
340   if (aMapOfArgs.Find ("hidelabels", aValues))
341   {
342     const Handle(Prs3d_Drawer)& aDrawer = aShape->Attributes();
343
344     if(!aDrawer->HasOwnDatumAspect())
345     {
346       Handle(Prs3d_DatumAspect) aDefAspect = ViewerTest::GetAISContext()->DefaultDrawer()->DatumAspect();
347
348       Handle(Prs3d_DatumAspect) aDatumAspect = new Prs3d_DatumAspect();
349       aDatumAspect->FirstAxisAspect()->SetAspect (aDefAspect->FirstAxisAspect()->Aspect());
350       aDatumAspect->SecondAxisAspect()->SetAspect (aDefAspect->SecondAxisAspect()->Aspect());
351       aDatumAspect->ThirdAxisAspect()->SetAspect (aDefAspect->ThirdAxisAspect()->Aspect());
352       aDatumAspect->SetAxisLength (aDefAspect->FirstAxisLength(),
353                                    aDefAspect->SecondAxisLength(),
354                                    aDefAspect->ThirdAxisLength());
355
356       aDrawer->SetDatumAspect (aDatumAspect);
357     }
358
359     aDrawer->DatumAspect()->SetToDrawLabels (Standard_False);
360   }
361
362   VDisplayAISObject (theArgVec[1], aShape);
363   return 0;
364 }
365
366 //==============================================================================
367 //function : VSize
368 //author   : ege
369 //purpose  : Change the size of a named or selected trihedron
370 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
371 //           if no value, the value is set at 100 by default
372 //Draw arg : vsize [name] [size]
373 //==============================================================================
374
375 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
376
377 {
378   // Declaration de booleens
379   Standard_Boolean             ThereIsName;
380   Standard_Boolean             ThereIsCurrent;
381   Standard_Real                value;
382   Standard_Boolean             hascol;
383
384   Quantity_NameOfColor         col = Quantity_NOC_BLACK ;
385
386   // Verification des arguments
387   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error\n"; return 1;}
388
389   // Verification du nombre d'arguments
390   if (argc==1)      {ThereIsName=Standard_False;value=100;}
391   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
392   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
393
394   // On ferme le contexte local pour travailler dans le contexte global
395   if(TheAISContext()->HasOpenedContext())
396     TheAISContext()->CloseLocalContext();
397
398   // On set le booleen ThereIsCurrent
399   if (TheAISContext() -> NbSelected() > 0) {ThereIsCurrent=Standard_True;}
400   else {ThereIsCurrent=Standard_False;}
401
402
403
404   //===============================================================
405   // Il n'y a pas de nom  mais des objets selectionnes
406   //===============================================================
407   if (!ThereIsName && ThereIsCurrent)
408   {
409
410     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
411       it (GetMapOfAIS());
412
413     while ( it.More() ) {
414
415       Handle(AIS_InteractiveObject) aShape=
416         Handle(AIS_InteractiveObject)::DownCast(it.Key1());
417
418       if (!aShape.IsNull() &&  TheAISContext()->IsSelected(aShape) )
419       {
420
421         // On verifie que l'AIS InteraciveObject selectionne est bien
422         // un AIS_Trihedron
423         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
424
425           if (aShape->HasColor()) {
426             hascol=Standard_True;
427
428             // On recupere la couleur de aShape
429             col=aShape->Color();}
430
431           else hascol=Standard_False;
432
433           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
434           // pour lui appliquer la methode SetSize()
435           Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
436
437           // C'est bien un triedre,on chage sa valeur!
438           aTrihedron->SetSize(value);
439
440           // On donne la couleur au Trihedron
441           if(hascol)   aTrihedron->SetColor(col);
442           else         aTrihedron->UnsetColor();
443
444
445           // The trihedron hasn't be errased from the map
446           // so you just have to redisplay it
447           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
448
449         }
450
451       }
452
453       it.Next();
454     }
455
456     TheAISContext() ->UpdateCurrentViewer();
457   }
458
459   //===============================================================
460   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
461   //===============================================================
462
463
464
465   //===============================================================
466   // Il y a un nom de triedre passe en argument
467   //===============================================================
468   if (ThereIsName) {
469     TCollection_AsciiString name=argv[1];
470
471     // on verifie que ce nom correspond bien a une shape
472     Standard_Boolean IsBound= GetMapOfAIS().IsBound2(name);
473
474     if (IsBound) {
475
476       // on recupere la shape dans la map des objets displayes
477       Handle(AIS_InteractiveObject) aShape =
478         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
479
480       // On verifie que l'AIS InteraciveObject est bien
481       // un AIS_Trihedron
482       if (!aShape.IsNull() &&
483         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
484       {
485
486         if (aShape->HasColor()) {
487           hascol=Standard_True;
488
489           // On recupere la couleur de aShape
490           col=aShape->Color();}
491
492         else hascol=Standard_False;
493
494         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
495         // pour lui appliquer la methode SetSize()
496         Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
497
498         // C'est bien un triedre,on chage sa valeur
499         aTrihedron->SetSize(value);
500
501         // On donne la couleur au Trihedron
502         if(hascol)   aTrihedron->SetColor(col);
503         else         aTrihedron->UnsetColor();
504
505         // The trihedron hasn't be errased from the map
506         // so you just have to redisplay it
507         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
508
509         TheAISContext() ->UpdateCurrentViewer();
510       }
511     }
512   }
513   return 0;
514 }
515
516
517 //==============================================================================
518
519 //==============================================================================
520 //function : VPlaneTrihedron
521 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
522 //Draw arg : vplanetri  name
523 //==============================================================================
524 #include <AIS_Plane.hxx>
525
526
527
528 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
529
530 {
531   // Verification des arguments
532   if ( argc!=2) {di<<argv[0]<<" error\n"; return 1;}
533
534   // Declarations
535   Standard_Integer myCurrentIndex;
536   // Fermeture des contextes locaux
537   TheAISContext()->CloseAllContexts();
538
539   // On recupere tous les trihedrons de la GetMapOfAIS()
540   // et on active le mode de selection par face.
541   // =================================================
542
543   // Ouverture d'un contexte local et recuperation de son index.
544   TheAISContext()->OpenLocalContext(Standard_False);
545   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
546
547   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
548     it (GetMapOfAIS());
549   while(it.More()){
550     Handle(AIS_InteractiveObject) ShapeA =
551       Handle(AIS_InteractiveObject)::DownCast(it.Key1());
552     // On verifie que c'est bien un trihedron
553     if (!ShapeA.IsNull() &&
554       ShapeA->Type()==AIS_KOI_Datum  && ShapeA->Signature()==3  ) {
555         // on le downcast
556         Handle(AIS_Trihedron) TrihedronA =(Handle(AIS_Trihedron)::DownCast (ShapeA));
557         // on le charge dans le contexte et on active le mode Plane.
558         TheAISContext()->Load(TrihedronA,0,Standard_False);
559         TheAISContext()->Activate(TrihedronA,3);
560       }
561       it.Next();
562   }
563
564   di<<" Select a plane.\n";
565   // Boucle d'attente waitpick.
566   Standard_Integer argccc = 5;
567   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
568   const char **argvvv = (const char **) bufff;
569   while (ViewerMainLoop( argccc, argvvv) ) { }
570   // fin de la boucle
571
572   Handle(AIS_InteractiveObject) theIOB;
573   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
574     theIOB = TheAISContext()->SelectedInteractive();
575   }
576   // on le downcast
577   Handle(AIS_Plane) PlaneB =(Handle(AIS_Plane)::DownCast (theIOB));
578
579   // Fermeture du contexte local.
580   TheAISContext()->CloseLocalContext(myCurrentIndex);
581
582   // on le display & bind
583   TheAISContext()->Display(PlaneB );
584   GetMapOfAIS().Bind ( PlaneB ,argv[1]);
585
586   return 0;
587 }
588
589
590
591 //==============================================================================
592 // Fonction        First click      2de click
593 //
594 // vaxis           vertex           vertex
595 //                 edge             None
596 // vaxispara       edge             vertex
597 // vaxisortho      edge             Vertex
598 // vaxisinter      Face             Face
599 //==============================================================================
600
601 //==============================================================================
602 //function : VAxisBuilder
603 //purpose  :
604 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
605 //==============================================================================
606 #include <TopoDS_Edge.hxx>
607 #include <TopoDS_Vertex.hxx>
608 #include <TopExp.hxx>
609 #include <Geom_Line.hxx>
610
611 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
612 {
613   // Declarations
614   Standard_Boolean HasArg;
615   TCollection_AsciiString name;
616   Standard_Integer MyCurrentIndex;
617
618   // Verification
619   if (argc<2 || argc>8 ) {di<<" Syntaxe error\n";return 1;}
620   if (argc==8) HasArg=Standard_True;
621   else HasArg=Standard_False;
622
623   name=argv[1];
624   // Fermeture des contextes
625   TheAISContext()->CloseAllContexts();
626
627   // Cas ou il y a des arguments
628   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
629   if (HasArg) {
630     Standard_Real coord[6];
631     for(Standard_Integer i=0;i<=5;i++){
632       coord[i]=Draw::Atof(argv[2+i]);
633     }
634     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
635
636     gp_Vec myVect (p1,p2);
637     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
638     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
639     GetMapOfAIS().Bind (TheAxis,name);
640     TheAISContext()->Display(TheAxis);
641   }
642
643   // Pas d'arguments
644   else {
645     // fonction vaxis
646     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
647     if ( !strcasecmp(argv[0], "vaxis")) {
648       TheAISContext()->OpenLocalContext();
649       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
650
651       // Active le mode edge et le mode vertex
652       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
653       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
654       di<<" Select an edge or a vertex.\n";
655
656       // Boucle d'attente waitpick.
657       Standard_Integer argcc = 5;
658       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
659       const char **argvv = (const char **) buff;
660       while (ViewerMainLoop( argcc, argvv) ) { }
661       // fin de la boucle
662
663       // recuperation de la shape.
664       TopoDS_Shape ShapeA;
665       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
666         ShapeA = TheAISContext()->SelectedShape();
667       }
668       // recuperation de l'AIS_InteractiveObject
669       //Handle(AIS_InteractiveObject) myAISio=TheAISContext()->Current();
670       // down cast en AIS_Point si sig et type
671       // AIS_Point -> Geom_Pnt ....
672
673       if (ShapeA.ShapeType()==TopAbs_VERTEX) {
674         // on desactive le mode edge
675         TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
676         di<<" Select a different vertex.\n";
677
678         TopoDS_Shape ShapeB;
679         do {
680           // Boucle d'attente waitpick.
681           Standard_Integer argccc = 5;
682           const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
683           const char **argvvv = (const char **) bufff;
684           while (ViewerMainLoop( argccc, argvvv) ) { }
685           // fin de la boucle
686           for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
687             ShapeB = TheAISContext()->SelectedShape();
688           }
689
690
691         } while(ShapeB.IsSame(ShapeA) );
692
693         // Fermeture du context local
694         TheAISContext()->CloseLocalContext(MyCurrentIndex);
695
696         // Construction de l'axe
697         gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
698         gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
699         gp_Vec   V (A,B);
700         gp_Dir   D (V);
701         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
702         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
703         GetMapOfAIS().Bind (TheAxis,name);
704         TheAISContext()->Display(TheAxis);
705       }
706       else {
707         // Un unique edge (ShapeA) a ete picke
708         // Fermeture du context local
709         TheAISContext()->CloseLocalContext(MyCurrentIndex);
710         // Constuction de l'axe
711         TopoDS_Edge    ed =TopoDS::Edge(ShapeA);
712         TopoDS_Vertex  Va,Vb;
713         TopExp::Vertices(ed,Va,Vb );
714         gp_Pnt A=BRep_Tool::Pnt(Va);
715         gp_Pnt B=BRep_Tool::Pnt(Vb);
716         gp_Vec  V (A,B);
717         gp_Dir   D (V);
718         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
719         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
720         GetMapOfAIS().Bind (TheAxis,name);
721         TheAISContext()->Display(TheAxis);
722       }
723
724     }
725
726     // Fonction axispara
727     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
728     else if ( !strcasecmp(argv[0], "vaxispara")) {
729
730       TheAISContext()->OpenLocalContext();
731       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
732
733       // Active le mode edge
734       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
735       di<<" Select an edge.\n";
736
737       // Boucle d'attente waitpick.
738       Standard_Integer argcc = 5;
739       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
740       const char **argvv = (const char **) buff;
741       while (ViewerMainLoop( argcc, argvv) ) { }
742       // fin de la boucle
743
744       TopoDS_Shape ShapeA;
745       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
746         ShapeA = TheAISContext()->SelectedShape();
747       }
748       // Active le mode vertex et deactive edges
749       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
750       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
751       di<<" Select a vertex.\n";
752
753       // Boucle d'attente waitpick.
754       Standard_Integer argccc = 5;
755       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
756       const char **argvvv = (const char **) bufff;
757       while (ViewerMainLoop( argccc, argvvv) ) { }
758       // fin de la boucle
759
760       // On peut choisir un pnt sur l'edge
761       TopoDS_Shape ShapeB;
762       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
763         ShapeB = TheAISContext()->SelectedShape();
764       }
765       // Fermeture du context local
766       TheAISContext()->CloseLocalContext(MyCurrentIndex);
767
768       // Construction de l'axe
769       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
770       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
771       TopoDS_Vertex  Va,Vc;
772       TopExp::Vertices(ed,Va,Vc );
773       gp_Pnt A=BRep_Tool::Pnt(Va);
774       gp_Pnt C=BRep_Tool::Pnt(Vc);
775       gp_Vec  V (A,C);
776       gp_Dir   D (V);
777       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
778       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
779       GetMapOfAIS().Bind (TheAxis,name);
780       TheAISContext()->Display(TheAxis);
781
782     }
783
784     // Fonction axisortho
785     else  {
786       TheAISContext()->OpenLocalContext();
787       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
788
789       // Active le mode edge
790       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
791       di<<" Select an edge.\n";
792
793       // Boucle d'attente waitpick.
794       Standard_Integer argcc = 5;
795       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
796       const char **argvv = (const char **) buff;
797       while (ViewerMainLoop( argcc, argvv) ) { }
798       // fin de la boucle
799
800       TopoDS_Shape ShapeA;
801       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
802         ShapeA = TheAISContext()->SelectedShape();
803       }
804       // Active le mode vertex et deactive edges
805       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
806       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
807       di<<" Slect a vertex.\n";
808
809       // Boucle d'attente waitpick.
810       Standard_Integer argccc = 5;
811       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
812       const char **argvvv = (const char **) bufff;
813       while (ViewerMainLoop( argccc, argvvv) ) { }
814       // fin de la boucle
815
816       // On peut choisir un pnt sur l'edge
817       TopoDS_Shape ShapeB;
818       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
819         ShapeB = TheAISContext()->SelectedShape();
820       }
821       // Fermeture du context local
822       TheAISContext()->CloseLocalContext(MyCurrentIndex);
823
824       // Construction de l'axe
825       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
826       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
827       TopoDS_Vertex  Va,Vc;
828       TopExp::Vertices(ed,Va,Vc );
829       gp_Pnt A=BRep_Tool::Pnt(Va);
830       gp_Pnt C=BRep_Tool::Pnt(Vc);
831       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
832       gp_Vec  V (A,E);
833       gp_Dir   D (V);
834       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
835       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
836       GetMapOfAIS().Bind (TheAxis,name);
837       TheAISContext()->Display(TheAxis);
838
839     }
840
841   }
842   return 0;
843 }
844
845
846 //==============================================================================
847 // Fonction        First click      Result
848 //
849 // vpoint          vertex           AIS_Point=Vertex
850 //                 edge             AIS_Point=Middle of the edge
851 //==============================================================================
852
853 //==============================================================================
854 //function : VPointBuilder
855 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
856 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
857 //==============================================================================
858 #include <TopoDS_Edge.hxx>
859 #include <TopoDS_Vertex.hxx>
860 #include <TopExp.hxx>
861 #include <AIS_Point.hxx>
862 #include <Geom_CartesianPoint.hxx>
863
864 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
865 {
866   // Declarations
867   Standard_Boolean HasArg;
868   TCollection_AsciiString name;
869   Standard_Integer myCurrentIndex;
870
871   // Verification
872   if (argc<2 || argc>5 ) {di<<" Syntaxe error\n";return 1;}
873   if (argc==5) HasArg=Standard_True;
874   else HasArg=Standard_False;
875
876   name=argv[1];
877   // Fermeture des contextes
878   TheAISContext()->CloseAllContexts();
879
880   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
881   if (HasArg) {
882     Standard_Real thecoord[3];
883     for(Standard_Integer i=0;i<=2;i++)
884       thecoord[i]=Draw::Atof(argv[2+i]);
885     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
886     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
887     GetMapOfAIS().Bind (myAISPoint,name);
888     TheAISContext()->Display(myAISPoint);
889   }
890
891   // Il n'a pas d'arguments
892   else {
893     TheAISContext()->OpenLocalContext();
894     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
895
896     // Active le mode Vertex et Edges
897     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
898     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
899     di<<" Select a vertex or an edge(build the middle)\n";
900
901     // Boucle d'attente waitpick.
902     Standard_Integer argcc = 5;
903     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
904     const char **argvv = (const char **) buff;
905     while (ViewerMainLoop( argcc, argvv) ) { }
906     // fin de la boucle
907
908     TopoDS_Shape ShapeA;
909     for (TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
910       ShapeA= TheAISContext()->SelectedShape();
911     }
912
913     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
914       // Un vertex a ete selectionne
915       // Fermeture du context local
916       TheAISContext()->CloseLocalContext(myCurrentIndex);
917
918       // Construction du point
919       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) );
920       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
921       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
922       GetMapOfAIS().Bind(myAISPoint,name);
923       TheAISContext()->Display(myAISPoint);
924     }
925     else {
926       // Un Edge a ete selectionne
927       // Fermeture du context local
928       TheAISContext()->CloseLocalContext(myCurrentIndex);
929
930       // Construction du point milieu de l'edge
931       TopoDS_Edge myEdge=TopoDS::Edge(ShapeA);
932       TopoDS_Vertex myVertexA,myVertexB;
933       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
934       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
935       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
936       // M est le milieu de [AB]
937       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
938       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
939       GetMapOfAIS().Bind(myAISPointM,name);
940       TheAISContext()->Display(myAISPointM);
941     }
942
943   }
944   return 0;
945
946 }
947
948 //==============================================================================
949 // Function        1st click   2de click  3de click
950 // vplane          Vertex      Vertex     Vertex
951 //                 Vertex      Edge
952 //                 Edge        Vertex
953 //                 Face
954 // vplanepara      Face        Vertex
955 //                 Vertex      Face
956 // vplaneortho     Face        Edge
957 //                 Edge        Face
958 //==============================================================================
959
960 //==============================================================================
961 //function : VPlaneBuilder
962 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
963 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
964 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
965 //                            [PlaneName] [PointName] [TypeOfSensitivity]
966 //==============================================================================
967
968 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
969                                        Standard_Integer argc,
970                                        const char** argv)
971 {
972   // Declarations
973   Standard_Boolean hasArg;
974   TCollection_AsciiString aName;
975   Standard_Integer aCurrentIndex;
976
977   // Verification
978   if (argc<2 || argc>6 )
979   {
980     std::cout<<" Syntax error\n";
981     return 1;
982   }
983   if (argc == 6 || argc==5 || argc==4)
984     hasArg=Standard_True;
985   else 
986     hasArg=Standard_False;
987
988   aName=argv[1];
989   // Close all contexts
990   TheAISContext()->CloseAllContexts();
991
992   // There are some arguments
993   if (hasArg)
994   {
995     if (!GetMapOfAIS().IsBound2(argv[2] ))
996     {
997       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
998       return 1;
999     }
1000     // Get shape from map
1001     Handle(AIS_InteractiveObject) aShapeA =
1002       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2] ));
1003
1004     // The first argument is an AIS_Point
1005     if (!aShapeA.IsNull() &&
1006         aShapeA->Type()==AIS_KOI_Datum &&
1007         aShapeA->Signature()==1)
1008     {
1009         // The second argument must also be an AIS_Point
1010         if (argc<5 || !GetMapOfAIS().IsBound2(argv[3]))
1011         {
1012           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
1013           return 1;
1014         }
1015         // Get shape from map
1016         Handle(AIS_InteractiveObject) aShapeB =
1017           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1018         // If B is not an AIS_Point
1019         if (aShapeB.IsNull() ||
1020           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1021         {
1022           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
1023           return 1;
1024         }
1025         // The third object is an AIS_Point
1026         if (!GetMapOfAIS().IsBound2(argv[4]) ) 
1027         {
1028           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
1029           return 1; 
1030         }
1031         // Get shape from map
1032         Handle(AIS_InteractiveObject) aShapeC =
1033           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
1034         // If C is not an AIS_Point
1035         if (aShapeC.IsNull() ||
1036           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
1037         {
1038           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
1039           return 1;
1040         }
1041
1042         // Treatment of objects A, B, C
1043         // Downcast an AIS_IO to AIS_Point
1044         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
1045         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
1046         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
1047
1048         Handle(Geom_CartesianPoint ) aCartPointA = 
1049           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
1050
1051         Handle(Geom_CartesianPoint ) aCartPointB = 
1052           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
1053
1054         Handle(Geom_CartesianPoint ) aCartPointC = 
1055           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
1056
1057         // Verification that the three points are different
1058         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
1059            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1060            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
1061         {
1062           // B=A
1063           std::cout<<"vplane error: same points\n";return 1;
1064         }
1065         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
1066            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1067            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
1068         {
1069           // C=A
1070           std::cout<<"vplane error: same points\n";return 1;
1071         }
1072         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
1073            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
1074            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
1075         {
1076           // C=B
1077           std::cout<<"vplane error: same points\n";return 1;
1078         }
1079
1080         gp_Pnt A = aCartPointA->Pnt();
1081         gp_Pnt B = aCartPointB->Pnt();
1082         gp_Pnt C = aCartPointC->Pnt();
1083
1084         // Construction of AIS_Plane
1085         GC_MakePlane MkPlane (A,B,C);
1086         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1087         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1088         GetMapOfAIS().Bind (anAISPlane,aName );
1089         if (argc == 6)
1090         {
1091           Standard_Integer aType = Draw::Atoi (argv[5]);
1092           if (aType != 0 && aType != 1)
1093           {
1094             std::cout << "vplane error: wrong type of sensitivity!\n"
1095                       << "Should be one of the following values:\n"
1096                       << "0 - Interior\n"
1097                       << "1 - Boundary"
1098                       << std::endl;
1099             return 1;
1100           }
1101           else
1102           {
1103             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1104           }
1105         }
1106         TheAISContext()->Display(anAISPlane);
1107       }
1108
1109       // The first argument is an AIS_Axis
1110       // Creation of a plane orthogonal to the axis through a point
1111     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1112       // The second argument should be an AIS_Point
1113       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3] ) )
1114       {
1115         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1116         return 1;
1117       }
1118       // Get shape from map
1119       Handle(AIS_InteractiveObject) aShapeB =
1120         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1121       // If B is not an AIS_Point
1122       if (aShapeB.IsNull() ||
1123         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1124       {
1125         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1126         return 1;
1127       }
1128
1129       // Treatment of objects A and B
1130       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1131       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1132
1133       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1134       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1135
1136       gp_Ax1 anAxis = aGeomLineA->Position();
1137       Handle(Geom_CartesianPoint) aCartPointB = 
1138         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1139
1140       gp_Dir D =anAxis.Direction();
1141       gp_Pnt B = aCartPointB->Pnt();
1142
1143       // Construction of AIS_Plane
1144       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1145       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1146       GetMapOfAIS().Bind (anAISPlane,aName );
1147       if (argc == 5)
1148       {
1149         Standard_Integer aType = Draw::Atoi (argv[4]);
1150         if (aType != 0 && aType != 1)
1151         {
1152           std::cout << "vplane error: wrong type of sensitivity!\n"
1153                     << "Should be one of the following values:\n"
1154                     << "0 - Interior\n"
1155                     << "1 - Boundary"
1156                     << std::endl;
1157           return 1;
1158         }
1159         else
1160         {
1161           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1162         }
1163       }
1164       TheAISContext()->Display(anAISPlane);
1165
1166     }
1167     // The first argumnet is an AIS_Plane
1168     // Creation of a plane parallel to the plane passing through the point
1169     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1170     {
1171       // The second argument should be an AIS_Point
1172       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3]))
1173       {
1174         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1175         return 1;
1176       }
1177       // Get shape from map
1178       Handle(AIS_InteractiveObject) aShapeB =
1179         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1180       // B should be an AIS_Point
1181       if (aShapeB.IsNull() ||
1182          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1183       {
1184         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1185         return 1;
1186       }
1187
1188       // Treatment of objects A and B
1189       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1190       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1191
1192       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1193       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1194
1195       Handle(Geom_CartesianPoint) aCartPointB = 
1196         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1197       gp_Pnt B= aCartPointB->Pnt();
1198
1199       // Construction of an AIS_Plane
1200       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1201       GetMapOfAIS().Bind (anAISPlane, aName);
1202       if (argc == 5)
1203       {
1204         Standard_Integer aType = Draw::Atoi (argv[4]);
1205         if (aType != 0 && aType != 1)
1206         {
1207           std::cout << "vplane error: wrong type of sensitivity!\n"
1208                     << "Should be one of the following values:\n"
1209                     << "0 - Interior\n"
1210                     << "1 - Boundary"
1211                     << std::endl;
1212           return 1;
1213         }
1214         else
1215         {
1216           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1217         }
1218       }
1219       TheAISContext()->Display(anAISPlane);
1220     }
1221     // Error
1222     else
1223     {
1224       std::cout<<"vplane: error 1st object is not an AIS\n";
1225       return 1;
1226     }
1227   }
1228   // There are no arguments
1229   else 
1230   {
1231     // Function vplane
1232     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1233     if (!strcasecmp(argv[0], "vplane"))
1234     {
1235       TheAISContext()->OpenLocalContext();
1236       aCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1237
1238       // Active modes Vertex, Edge and Face
1239       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1240       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1241       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1242       std::cout<<"Select a vertex, a face or an edge\n";
1243
1244       // Wait for picking
1245       Standard_Integer argcc = 5;
1246       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1247       const char **argvv = (const char **) buff;
1248       while (ViewerMainLoop( argcc, argvv) ) { }
1249       // end of the loop
1250
1251       TopoDS_Shape aShapeA;
1252       for (TheAISContext()->InitSelected();
1253            TheAISContext()->MoreSelected();
1254            TheAISContext()->NextSelected())
1255       {
1256         aShapeA = TheAISContext()->SelectedShape();
1257       }
1258
1259       // aShapeA is a Vertex
1260       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1261       {
1262         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1263         std::cout<<" Select an edge or a different vertex\n";
1264
1265         // Wait for picking
1266         Standard_Integer argccc = 5;
1267         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1268         const char **argvvv = (const char **) bufff;
1269         while (ViewerMainLoop( argccc, argvvv) ) { }
1270         // end of the loop
1271
1272         TopoDS_Shape aShapeB;
1273         for (TheAISContext()->InitSelected();
1274           TheAISContext()->MoreSelected();
1275           TheAISContext()->NextSelected())
1276         {
1277           aShapeB = TheAISContext()->SelectedShape();
1278         }
1279         // aShapeB is a Vertex
1280         if (aShapeB.ShapeType()==TopAbs_VERTEX)
1281         {
1282           // A and B are the same
1283           if (aShapeB.IsSame(aShapeA))
1284           {
1285             std::cout<<" vplane: error, same points selected\n";
1286             return 1;
1287           }
1288           TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1289           std::cout<<" Select a different vertex\n";
1290
1291           // Wait for picking
1292           Standard_Integer argcccc = 5;
1293           const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1294           const char **argvvvv = (const char **) buffff;
1295           while (ViewerMainLoop( argcccc, argvvvv) ) { }
1296           // end of the loop
1297
1298           TopoDS_Shape aShapeC;
1299           for (TheAISContext()->InitSelected();
1300                TheAISContext()->MoreSelected();
1301                TheAISContext()->NextSelected())
1302           {
1303             aShapeC = TheAISContext()->SelectedShape();
1304           }
1305           // aShapeC is the same as A or B
1306           if (aShapeC.IsSame(aShapeA)||aShapeC.IsSame(aShapeB))
1307           {
1308             std::cout<<" vplane: error, same points selected\n";
1309             return 1;
1310           }
1311
1312           // Close the local context
1313           TheAISContext()->CloseLocalContext(aCurrentIndex);
1314
1315           // Construction of plane
1316           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1317           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1318           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1319           GC_MakePlane MkPlane(A, B, C);
1320           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1321           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1322           GetMapOfAIS().Bind (anAISPlane, aName);
1323           TheAISContext()->Display(anAISPlane);
1324         }
1325         // ShapeB is an edge
1326         else
1327         {
1328           // Verify that the vertex is not on the edge ShapeB
1329           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1330           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1331
1332           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1333           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1334           {
1335             // The vertex is on the edge
1336             std::cout<<" vplane: error point is on the edge\n";
1337             return 1;
1338           }
1339           else
1340           {
1341             // Close the local context
1342             TheAISContext()->CloseLocalContext(aCurrentIndex);
1343             // Construction of plane
1344             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1345             TopoDS_Vertex aVBa, aVBb;
1346             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1347             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1348             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1349             GC_MakePlane MkPlane (A, aBa, aBb);
1350             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1351             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1352             GetMapOfAIS().Bind (anAISPlane, aName);
1353             TheAISContext()->Display(anAISPlane);
1354           }
1355         }
1356       }
1357       // aShapeA is an edge
1358       else if (aShapeA.ShapeType()==TopAbs_EDGE)
1359       {
1360         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1361         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1362         std::cout<<" Select a vertex that don't belong to the edge\n";
1363
1364         // Wait for picking
1365         Standard_Integer argccc = 5;
1366         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1367         const char **argvvv = (const char **) bufff;
1368         while (ViewerMainLoop( argccc, argvvv) ) { }
1369         // end of the loop
1370
1371         TopoDS_Shape aShapeB;
1372         for (TheAISContext()->InitSelected();
1373              TheAISContext()->MoreSelected();
1374              TheAISContext()->NextSelected())
1375         {
1376           aShapeB = TheAISContext()->SelectedShape();
1377         }
1378         // aShapeB should be a Vertex
1379         // Check that the vertex aShapeB is not on the edge
1380         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1381         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1382
1383         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1384         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1385         {
1386           // The vertex is on the edge
1387           std::cout<<" vplane: error point is on the edge\n";
1388           return 1;
1389         }
1390         else
1391         {
1392           // Close the local context
1393           TheAISContext()->CloseLocalContext(aCurrentIndex);
1394           // Construction of plane
1395           gp_Pnt B = BRep_Tool::Pnt(aVertB);
1396           TopoDS_Vertex aVAa, aVAb;
1397           TopExp::Vertices(anEdgeA, aVAa, aVAb);
1398           gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1399           gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1400           GC_MakePlane MkPlane (B,Aa,Ab);
1401           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1402           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1403           GetMapOfAIS().Bind (anAISPlane ,aName);
1404           TheAISContext()->Display(anAISPlane);
1405         }
1406       }
1407       // aShapeA is a Face
1408       else
1409       {
1410         // Close the local context: nothing to select
1411         TheAISContext()->CloseLocalContext(aCurrentIndex);
1412         // Construction of plane
1413         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1414         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1415         if (aSurface.GetType()==GeomAbs_Plane)
1416         {
1417           gp_Pln aPlane = aSurface.Plane();
1418           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1419           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1420           GetMapOfAIS().Bind (anAISPlane, aName);
1421           TheAISContext()->Display(anAISPlane);
1422         }
1423         else
1424         {
1425           std::cout<<" vplane: error\n";
1426           return 1;
1427         }
1428       }
1429     }
1430
1431     // Function vPlanePara
1432     // ===================
1433     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1434     else if (!strcasecmp(argv[0], "vplanepara"))
1435     {
1436       TheAISContext()->OpenLocalContext();
1437       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1438
1439       // Activate modes Vertex and Face
1440       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1441       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1442       std::cout<<" Select a vertex or a face\n";
1443
1444       // Wait for picking
1445       Standard_Integer argcc = 5;
1446       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1447       const char **argvv = (const char **) buff;
1448       while (ViewerMainLoop( argcc, argvv) ) { }
1449       // end of the loop
1450
1451       TopoDS_Shape aShapeA;
1452       for (TheAISContext()->InitSelected();
1453            TheAISContext()->MoreSelected();
1454            TheAISContext()->NextSelected())
1455       {
1456         aShapeA = TheAISContext()->SelectedShape();
1457       }
1458
1459       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1460       {
1461         // aShapeA is a vertex
1462         // Deactivate the mode Vertex
1463         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1));
1464         std::cout<<" Select a face\n";
1465
1466         // Wait for picking
1467         Standard_Integer argccc = 5;
1468         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1469         const char **argvvv = (const char **) bufff;
1470         while (ViewerMainLoop( argccc, argvvv) ) { }
1471         // end of the loop
1472
1473         TopoDS_Shape aShapeB;
1474         for (TheAISContext()->InitSelected();
1475              TheAISContext()->MoreSelected();
1476              TheAISContext()->NextSelected())
1477         {
1478           // A vertex ShapeA can be on Face ShapeB
1479           aShapeB = TheAISContext()->SelectedShape();
1480         }
1481
1482         // Close the local context
1483         TheAISContext()->CloseLocalContext(aCurrentIndex);
1484
1485         // Construction of plane
1486         gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1487
1488         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1489         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1490         if (aSurface.GetType()==GeomAbs_Plane )
1491         {
1492           gp_Pln aPlane = aSurface.Plane();
1493           // Construct a plane parallel to aGeomPlane through A
1494           aPlane.SetLocation(A);
1495           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1496           Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1497           GetMapOfAIS().Bind (aAISPlane ,aName);
1498           TheAISContext()->Display(aAISPlane);
1499         }
1500         else
1501         {
1502           std::cout<<" vplanepara: error\n";
1503           return 1;
1504         }
1505       }
1506       else
1507       {
1508         // ShapeA is a Face
1509         // Deactive the mode Face
1510         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1511         std::cout<<" Select a vertex\n";
1512
1513         // Wait for picking
1514         Standard_Integer argccc = 5;
1515         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1516         const char **argvvv = (const char **) bufff;
1517         while (ViewerMainLoop( argccc, argvvv) ) { }
1518         // end of the loop
1519
1520         TopoDS_Shape aShapeB;
1521         for (TheAISContext()->InitSelected();
1522              TheAISContext()->MoreSelected();
1523              TheAISContext()->NextSelected())
1524         {
1525           // A vertex ShapeB can be on Face ShapeA
1526           aShapeB = TheAISContext()->SelectedShape();
1527         }
1528         // Close the local context
1529         TheAISContext()->CloseLocalContext(aCurrentIndex);
1530
1531         // Construction of plane
1532         gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1533
1534         TopoDS_Face aFace=TopoDS::Face(aShapeA);
1535         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1536         if (aSurface.GetType()==GeomAbs_Plane )
1537         {
1538           gp_Pln aPlane = aSurface.Plane();
1539           aPlane.SetLocation(B);
1540           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1541           // Construct a plane parallel to aGeomPlane through B
1542           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, B);
1543           GetMapOfAIS().Bind (anAISPlane, aName);
1544           TheAISContext()->Display(anAISPlane);
1545         }
1546         else
1547         {
1548           std::cout<<" vplanepara: error\n";return 1;
1549         }
1550       }
1551     }
1552
1553     // Function vplaneortho
1554     // ====================
1555     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1556     else
1557     {
1558       TheAISContext()->OpenLocalContext();
1559       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1560
1561       // Activate the modes Edge and Face
1562       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1563       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1564       std::cout<<" Select a face and an edge coplanar\n";
1565
1566       // Wait for picking
1567       Standard_Integer argcc = 5;
1568       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1569       const char **argvv = (const char **) buff;
1570       while (ViewerMainLoop( argcc, argvv) ) { }
1571       // end of the loop
1572
1573       TopoDS_Shape aShapeA;
1574       for (TheAISContext()->InitSelected();
1575            TheAISContext()->MoreSelected();
1576            TheAISContext()->NextSelected())
1577       {
1578         aShapeA = TheAISContext()->SelectedShape();
1579       }
1580
1581       if (aShapeA.ShapeType()==TopAbs_EDGE )
1582       {
1583         // ShapeA is an edge, deactivate the mode Edge...
1584         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1585         std::cout<<" Select a face\n";
1586
1587         // Wait for picking
1588         Standard_Integer argccc = 5;
1589         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1590         const char **argvvv = (const char **) bufff;
1591         while (ViewerMainLoop( argccc, argvvv) ) { }
1592         // end of the loop
1593
1594         TopoDS_Shape aShapeB;
1595         for (TheAISContext()->InitSelected();
1596              TheAISContext()->MoreSelected();
1597              TheAISContext()->NextSelected())
1598         {
1599           // Edge ShapeA can be on Face ShapeB
1600           aShapeB = TheAISContext()->SelectedShape();
1601         }
1602
1603         // Close the local context
1604         TheAISContext()->CloseLocalContext(aCurrentIndex);
1605
1606         // Construction of plane
1607         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1608         TopoDS_Vertex aVAa, aVAb;
1609         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1610         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1611         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1612         gp_Vec ab (Aa,Ab);
1613
1614         gp_Dir Dab (ab);
1615         // Creation of rotation axis
1616         gp_Ax1 aRotAxis (Aa,Dab);
1617
1618         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1619         // The edge must be parallel to the face
1620         BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1621         BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1622         // Compare to heights
1623         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1624             >Precision::Confusion())
1625         {
1626           // the edge is not parallel to the face
1627           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1628           return 1;
1629         }
1630         // the edge is OK
1631         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1632         if (aSurface.GetType()==GeomAbs_Plane)
1633         {
1634           gp_Pln aPlane = aSurface.Plane();
1635           // It rotates a half turn round the axis of rotation
1636           aPlane.Rotate(aRotAxis , M_PI/2);
1637
1638           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1639           // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1640           gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1641           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1642           GetMapOfAIS().Bind (anAISPlane, aName);
1643           TheAISContext()->Display(anAISPlane);
1644         }
1645         else
1646         {
1647           std::cout<<" vplaneortho: error\n";
1648           return 1;
1649         }
1650       }
1651       else
1652       {
1653         // ShapeA is a Face, deactive the mode Face.
1654         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1655         std::cout<<" Select an edge\n";
1656
1657         // Wait for picking
1658         Standard_Integer argccc = 5;
1659         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1660         const char **argvvv = (const char **) bufff;
1661         while (ViewerMainLoop( argccc, argvvv) ) { }
1662         // end of the loop
1663
1664         TopoDS_Shape aShapeB;
1665         for (TheAISContext()->InitSelected();
1666              TheAISContext()->MoreSelected();
1667              TheAISContext()->NextSelected())
1668         {
1669           // Edge ShapeB can be on Face ShapeA
1670           aShapeB = TheAISContext()->SelectedShape();
1671         }
1672         // Close the local context
1673         TheAISContext()->CloseLocalContext(aCurrentIndex);
1674
1675         // Construction of plane
1676         TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1677         TopoDS_Vertex aVBa, aVBb;
1678         TopExp::Vertices(anEdgeB, aVBa, aVBb);
1679         gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1680         gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1681         gp_Vec ab (aBa,aBb);
1682         gp_Dir Dab (ab);
1683         // Creation of rotation axe
1684         gp_Ax1 aRotAxis (aBa,Dab);
1685
1686         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1687         // The edge must be parallel to the face
1688         BRepExtrema_ExtPF aHeightA (aVBa, aFace);
1689         BRepExtrema_ExtPF aHeightB (aVBb, aFace);
1690         // Comparing the two heights
1691         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1692             >Precision::Confusion())
1693         {
1694           // the edge is not parallel to the face
1695           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1696           return 1;
1697         }
1698         // The edge is OK
1699         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1700         if (aSurface.GetType()==GeomAbs_Plane)
1701         {
1702           gp_Pln aPlane = aSurface.Plane();
1703           // It rotates a half turn round the axis of rotation
1704           aPlane.Rotate(aRotAxis , M_PI/2);
1705           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1706           // constructed aGeomPlane parallel to a plane containing the edge theGeomPlane (center mid-edge)
1707           gp_Pnt aMiddle ((aBa.X()+aBb.X() )/2 , (aBa.Y()+aBb.Y() )/2 , (aBa.Z()+aBb.Z() )/2 );
1708           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1709           GetMapOfAIS().Bind (anAISPlane ,aName);
1710           TheAISContext()->Display(anAISPlane);
1711         }
1712         else
1713         {
1714           std::cout<<" vplaneortho: error\n";
1715           return 1;
1716         }
1717       }
1718     }
1719   }
1720   return 0;
1721 }
1722
1723 //===============================================================================================
1724 //function : VChangePlane
1725 //purpose  :
1726 //===============================================================================================
1727 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1728 {
1729   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1730   if (aContextAIS.IsNull())
1731   {
1732     std::cout << theArgVec[0] << "AIS context is not available.\n";
1733     return 1;
1734   }
1735
1736   if (theArgsNb < 3 || theArgsNb > 11)
1737   {
1738     std::cerr << theArgVec[0] 
1739               << ": incorrect number of command arguments.\n"
1740               << "Type help for more information.\n";
1741     return 1;
1742   }
1743
1744   TCollection_AsciiString aName (theArgVec[1]);
1745
1746   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1747     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1748     : NULL;
1749
1750   if ( aPlane.IsNull() )
1751   {
1752     std::cout << theArgVec[0] 
1753               << ": there is no interactive plane with the given name."
1754               << "Type help for more information.\n";
1755     return 1;
1756   }
1757
1758   Standard_Real aCenterX = aPlane->Center().X();
1759   Standard_Real aCenterY = aPlane->Center().Y();
1760   Standard_Real aCenterZ = aPlane->Center().Z();
1761
1762   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1763   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1764   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1765
1766   Standard_Real aSizeX = 0.0;
1767   Standard_Real aSizeY = 0.0;
1768   aPlane->Size (aSizeX, aSizeY);
1769   Standard_Boolean isUpdate = Standard_True;
1770
1771   TCollection_AsciiString aPName, aPValue;
1772   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1773   {
1774     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1775     TCollection_AsciiString anArgCase = anArg;
1776     anArgCase.UpperCase();
1777     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1778     {
1779       aPName.UpperCase();
1780       if (aPName.IsEqual ("X"))
1781       {
1782         aCenterX = aPValue.RealValue();
1783       }
1784       else if (aPName.IsEqual ("Y"))
1785       {
1786         aCenterY = aPValue.RealValue();
1787       }
1788       else if (aPName.IsEqual ("Z"))
1789       {
1790         aCenterZ = aPValue.RealValue();
1791       }
1792       else if (aPName.IsEqual ("DX"))
1793       {
1794         aDirX = aPValue.RealValue();
1795       }
1796       else if (aPName.IsEqual ("DY"))
1797       {
1798         aDirY = aPValue.RealValue();
1799       }
1800       else if (aPName.IsEqual ("DZ"))
1801       {
1802         aDirZ = aPValue.RealValue();
1803       }
1804       else if (aPName.IsEqual ("SX"))
1805       {
1806         aSizeX = aPValue.RealValue();
1807       }
1808       else if (aPName.IsEqual ("SY"))
1809       {
1810         aSizeY = aPValue.RealValue();
1811       }
1812     }
1813     else if (anArg.IsEqual ("NOUPDATE"))
1814     {
1815       isUpdate = Standard_False;
1816     }
1817   }
1818
1819   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1820   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1821   aPlane->SetCenter (aCenterPnt);
1822   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1823   aPlane->SetSize (aSizeX, aSizeY);
1824
1825   aContextAIS->Update (aPlane, isUpdate);
1826
1827   return 0;
1828 }
1829
1830 //==============================================================================
1831 // Fonction  vline
1832 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1833 //==============================================================================
1834
1835 //==============================================================================
1836 //function : VLineBuilder
1837 //purpose  : Build an AIS_Line
1838 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1839 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1840 //==============================================================================
1841 #include <Geom_CartesianPoint.hxx>
1842 #include <AIS_Line.hxx>
1843
1844
1845 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1846 {
1847   Standard_Integer myCurrentIndex;
1848   // Verifications
1849   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct \n";return 1; }
1850   // Fermeture des contextes
1851   TheAISContext()->CloseAllContexts();
1852
1853   // On recupere les parametres
1854   Handle(AIS_InteractiveObject) theShapeA;
1855   Handle(AIS_InteractiveObject) theShapeB;
1856
1857   // Parametres: AIS_Point AIS_Point
1858   // ===============================
1859   if (argc==4) {
1860     theShapeA=
1861       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
1862     // On verifie que c'est bien une AIS_Point
1863     if (!theShapeA.IsNull() &&
1864       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1865         // on recupere le deuxieme AIS_Point
1866         theShapeB=
1867           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1868         if (theShapeA.IsNull() ||
1869           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1870         {
1871           di <<"vline error: wrong type of 2de argument.\n";
1872           return 1;
1873         }
1874       }
1875     else {di <<"vline error: wrong type of 1st argument.\n";return 1; }
1876     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1877     Handle(AIS_Point) theAISPointA= Handle(AIS_Point)::DownCast (theShapeA);
1878     Handle(AIS_Point) theAISPointB= Handle(AIS_Point)::DownCast (theShapeB);
1879
1880     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1881     Handle(Geom_CartesianPoint ) myCartPointA= Handle(Geom_CartesianPoint)::DownCast (myGeomPointBA);
1882     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1883
1884     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1885     Handle(Geom_CartesianPoint ) myCartPointB= Handle(Geom_CartesianPoint)::DownCast (myGeomPointB);
1886     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1887
1888     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1889       // B=A
1890       di<<"vline error: same points\n";return 1;
1891     }
1892     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1893     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1894     GetMapOfAIS().Bind(theAISLine,argv[1] );
1895     TheAISContext()->Display(theAISLine );
1896
1897   }
1898
1899   // Parametres 6 Reals
1900   // ==================
1901
1902   else if (argc==8) {
1903     // On verifie que les deux points ne sont pas confondus
1904
1905     Standard_Real coord[6];
1906     for(Standard_Integer i=0;i<=2;i++){
1907       coord[i]=Draw::Atof(argv[2+i]);
1908       coord[i+3]=Draw::Atof(argv[5+i]);
1909     }
1910
1911     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1912     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1913
1914     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1915     GetMapOfAIS().Bind(theAISLine,argv[1] );
1916     TheAISContext()->Display(theAISLine );
1917
1918   }
1919
1920   // Pas de parametres: Selection dans le viewer.
1921   // ============================================
1922
1923   else {
1924     TheAISContext()->OpenLocalContext();
1925     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1926
1927     // Active le mode Vertex.
1928     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1929     di<<" Select a vertex \n";
1930
1931     // Boucle d'attente waitpick.
1932     Standard_Integer argcc = 5;
1933     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1934     const char **argvv = (const char **) buff;
1935     while (ViewerMainLoop( argcc, argvv) ) { }
1936     // fin de la boucle
1937
1938     TopoDS_Shape ShapeA;
1939     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1940       ShapeA = TheAISContext()->SelectedShape();
1941     }
1942
1943     // ShapeA est un Vertex
1944     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
1945
1946       di<<" Select a different vertex.\n";
1947
1948       TopoDS_Shape ShapeB;
1949       do {
1950
1951         // Boucle d'attente waitpick.
1952         Standard_Integer argccc = 5;
1953         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1954         const char **argvvv = (const char **) bufff;
1955         while (ViewerMainLoop( argccc, argvvv) ) { }
1956         // fin de la boucle
1957
1958         for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1959           ShapeB = TheAISContext()->SelectedShape();
1960         }
1961
1962
1963       } while(ShapeB.IsSame(ShapeA) );
1964
1965       // Fermeture du context local
1966       TheAISContext()->CloseLocalContext(myCurrentIndex);
1967
1968       // Construction de la line
1969       gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
1970       gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
1971
1972       Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1973       Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1974
1975       Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1976       GetMapOfAIS().Bind(theAISLine,argv[1] );
1977       TheAISContext()->Display(theAISLine );
1978
1979     }
1980     else  {
1981       di<<"vline error.\n";
1982     }
1983
1984   }
1985
1986   return 0;
1987 }
1988
1989 //==============================================================================
1990 // class   : FilledCircle
1991 // purpose : creates filled circle based on AIS_InteractiveObject 
1992 //           and Geom_Circle.
1993 //           This class is used to check method Matches() of class 
1994 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1995 //           because none of AIS classes provides creation of 
1996 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1997 //           (look method ComputeSelection() )
1998 //============================================================================== 
1999
2000 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
2001 {
2002   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
2003   gp_Circ aCirc(anAxes, theRadius);
2004   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
2005   return aCircle;
2006 }
2007
2008 class FilledCircle : public AIS_InteractiveObject 
2009 {
2010 public:
2011     // CASCADE RTTI
2012     DEFINE_STANDARD_RTTI_INLINE(FilledCircle,AIS_InteractiveObject); 
2013
2014     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
2015     FilledCircle(Handle(Geom_Circle) theCircle);
2016
2017 private:
2018     TopoDS_Face ComputeFace();
2019
2020     // Virtual methods implementation
2021     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
2022                   const Handle(Prs3d_Presentation)& thePresentation,
2023                   const Standard_Integer theMode) Standard_OVERRIDE;
2024
2025     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
2026                            const Standard_Integer theMode) Standard_OVERRIDE;
2027
2028 protected:
2029     Handle(Geom_Circle) myCircle;
2030     Standard_Boolean myFilledStatus;
2031
2032 }; 
2033
2034
2035 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
2036 {
2037   myCircle = CreateCircle(theCenter, theRadius);
2038   myFilledStatus = Standard_True;
2039 }
2040
2041 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
2042 {
2043   myCircle = theCircle;
2044   myFilledStatus = Standard_True;
2045 }
2046
2047 TopoDS_Face FilledCircle::ComputeFace() 
2048 {
2049   // Create edge from myCircle 
2050   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
2051   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
2052
2053   // Create wire from anEdge 
2054   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
2055   TopoDS_Wire aWire = aWireMaker.Wire();
2056
2057   // Create face from aWire
2058   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
2059   TopoDS_Face aFace = aFaceMaker.Face();
2060
2061   return aFace;
2062 }
2063
2064 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
2065                            const Handle(Prs3d_Presentation) &thePresentation, 
2066                            const Standard_Integer theMode) 
2067 {
2068   thePresentation->Clear();
2069
2070   TopoDS_Face aFace = ComputeFace();
2071
2072   if (aFace.IsNull()) return;
2073   if (theMode != 0) return;
2074
2075   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
2076 }
2077
2078 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2079                                     const Standard_Integer /*theMode*/)
2080 {
2081   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2082   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2083       myCircle, myFilledStatus);
2084   theSelection->Add(aSensitiveCircle);
2085 }
2086
2087 //==============================================================================
2088 // Fonction  vcircle
2089 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2090 //==============================================================================
2091
2092 //==============================================================================
2093 //function : VCircleBuilder
2094 //purpose  : Build an AIS_Circle
2095 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2096 //                              PointName PointName PointName IsFilled
2097 //==============================================================================
2098
2099 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2100                     TCollection_AsciiString theName, 
2101                     Standard_Boolean isFilled) 
2102 {
2103   Handle(AIS_InteractiveObject) aCircle;
2104   if (isFilled) 
2105   {
2106     aCircle = new FilledCircle(theGeomCircle);
2107   }
2108   else
2109   {
2110     aCircle = new AIS_Circle(theGeomCircle);
2111     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2112   }
2113
2114   // Check if there is an object with given name
2115   // and remove it from context
2116   if (GetMapOfAIS().IsBound2(theName)) 
2117   {
2118     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
2119     Handle(AIS_InteractiveObject) anInterObj = 
2120          Handle(AIS_InteractiveObject)::DownCast(anObj);
2121     TheAISContext()->Remove(anInterObj, Standard_False);
2122     GetMapOfAIS().UnBind2(theName);
2123    }
2124
2125    // Bind the circle to its name
2126    GetMapOfAIS().Bind(aCircle, theName);
2127
2128    // Display the circle
2129    TheAISContext()->Display(aCircle);
2130   
2131 }
2132
2133 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2134 {
2135   Standard_Integer myCurrentIndex;
2136   // Verification of the arguments
2137   if (argc>6 || argc<2) 
2138   { 
2139     std::cout << "vcircle error: expect 4 arguments.\n"; 
2140     return 1; // TCL_ERROR 
2141   }
2142   TheAISContext()->CloseAllContexts();
2143
2144   // There are all arguments
2145   if (argc == 6) 
2146   {
2147     // Get arguments
2148     TCollection_AsciiString aName(argv[1]);
2149     Standard_Boolean isFilled = Draw::Atoi(argv[5]) != 0;
2150
2151     Handle(AIS_InteractiveObject) theShapeA;
2152     Handle(AIS_InteractiveObject) theShapeB;
2153
2154     theShapeA =
2155       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2156     theShapeB =
2157       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2158
2159
2160     // Arguments: AIS_Point AIS_Point AIS_Point
2161     // ========================================
2162     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2163       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2164     {
2165       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2166       {
2167         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2168         return 1; // TCL_ERROR 
2169       }
2170       // The third object must be a point
2171       Handle(AIS_InteractiveObject) theShapeC =
2172         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2173       if (theShapeC.IsNull() ||
2174         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2175       {
2176         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2177         return 1; // TCL_ERROR 
2178       }
2179         // tag
2180         // Verify that the three points are different
2181         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2182         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2183         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2184         
2185         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2186         Handle(Geom_CartesianPoint) myCartPointA = 
2187           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2188
2189         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2190         Handle(Geom_CartesianPoint) myCartPointB =
2191           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2192
2193         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2194         Handle(Geom_CartesianPoint) myCartPointC =
2195           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2196
2197         // Test A=B
2198         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2199             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2200             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2201         {
2202           std::cout << "vcircle error: Same points.\n"; 
2203           return 1; // TCL_ERROR 
2204         }
2205         // Test A=C
2206         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2207             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2208             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2209         {
2210           std::cout << "vcircle error: Same points.\n"; 
2211           return 1; // TCL_ERROR 
2212         }
2213         // Test B=C
2214         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2215             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2216             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2217         {
2218           std::cout << "vcircle error: Same points.\n"; 
2219           return 1;// TCL_ERROR 
2220         }
2221         // Construction of the circle
2222         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2223           myCartPointB->Pnt(), myCartPointC->Pnt() );
2224         Handle (Geom_Circle) theGeomCircle;
2225         try 
2226         {
2227           theGeomCircle = Cir.Value();
2228         }
2229         catch (StdFail_NotDone)
2230         {
2231           std::cout << "vcircle error: can't create circle\n";
2232           return -1; // TCL_ERROR
2233         }
2234         
2235         DisplayCircle(theGeomCircle, aName, isFilled);
2236     }
2237
2238     // Arguments: AIS_Plane AIS_Point Real
2239     // ===================================
2240     else if (theShapeA->Type() == AIS_KOI_Datum && 
2241       theShapeA->Signature() == 7 ) 
2242     {
2243       if (theShapeB->Type() != AIS_KOI_Datum || 
2244         theShapeB->Signature() != 1 ) 
2245       {
2246         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2247         return 1; // TCL_ERROR 
2248       }
2249       // Check that the radius is >= 0
2250       if (Draw::Atof(argv[4]) <= 0 ) 
2251       {
2252         std::cout << "vcircle error: the radius must be >=0.\n"; 
2253         return 1; // TCL_ERROR 
2254       }
2255
2256       // Recover the normal to the plane
2257       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2258       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2259
2260       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2261       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2262       Handle(Geom_CartesianPoint) myCartPointB = 
2263         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2264
2265       gp_Pln mygpPlane = myGeomPlane->Pln();
2266       gp_Ax1 thegpAxe = mygpPlane.Axis();
2267       gp_Dir theDir = thegpAxe.Direction();
2268       gp_Pnt theCenter = myCartPointB->Pnt();
2269       Standard_Real TheR = Draw::Atof(argv[4]);
2270       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2271       Handle (Geom_Circle) theGeomCircle;
2272       try 
2273       {
2274         theGeomCircle = Cir.Value();
2275       }
2276       catch (StdFail_NotDone)
2277       {
2278         std::cout << "vcircle error: can't create circle\n";
2279         return -1; // TCL_ERROR
2280       }
2281
2282       DisplayCircle(theGeomCircle, aName, isFilled);
2283
2284     }
2285
2286     // Error
2287     else
2288     {
2289       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2290       return 1; // TCL_ERROR 
2291     }
2292
2293   }
2294   // No arguments: selection in the viewer
2295   // =========================================
2296   else 
2297   {
2298     // Get the name of the circle 
2299     TCollection_AsciiString aName(argv[1]);
2300
2301     TheAISContext()->OpenLocalContext();
2302     myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
2303
2304     // Activate selection mode for vertices and faces
2305     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2306     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2307     std::cout << " Select a vertex or a face\n";
2308
2309     // Wait for picking
2310     Standard_Integer argcc = 5;
2311     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2312     const char **argvv = (const char **) buff;
2313     while (ViewerMainLoop( argcc, argvv) ) { }
2314     // end of the loop
2315
2316     TopoDS_Shape ShapeA;
2317     for(TheAISContext()->InitSelected(); 
2318       TheAISContext()->MoreSelected(); 
2319       TheAISContext()->NextSelected() ) 
2320     {
2321       ShapeA = TheAISContext()->SelectedShape();
2322     }
2323
2324     // ShapeA is a Vertex
2325     if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
2326     {
2327       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2328       std::cout << " Select a different vertex\n";
2329
2330       TopoDS_Shape ShapeB;
2331       do 
2332       {
2333         // Wait for picking
2334         Standard_Integer argccc = 5;
2335         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2336         const char **argvvv = (const char **) bufff;
2337         while (ViewerMainLoop( argccc, argvvv) ) { }
2338         // end of the loop
2339
2340         for(TheAISContext()->InitSelected(); 
2341           TheAISContext()->MoreSelected(); 
2342           TheAISContext()->NextSelected() ) 
2343         {
2344           ShapeB = TheAISContext()->SelectedShape();
2345         }
2346       } while(ShapeB.IsSame(ShapeA) );
2347
2348       // Selection of ShapeC
2349       std::cout << " Select the last vertex\n";
2350       TopoDS_Shape ShapeC;
2351       do 
2352       {
2353         // Wait for picking
2354         Standard_Integer argcccc = 5;
2355         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2356         const char **argvvvv = (const char **) buffff;
2357         while (ViewerMainLoop( argcccc, argvvvv) ) { }
2358         // end of the loop
2359
2360         for(TheAISContext()->InitSelected(); 
2361           TheAISContext()->MoreSelected(); 
2362           TheAISContext()->NextSelected() ) 
2363         {
2364           ShapeC = TheAISContext()->SelectedShape();
2365         }
2366       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
2367       
2368       // Get isFilled
2369       Standard_Boolean isFilled;
2370       std::cout << "Enter filled status (0 or 1)\n";
2371       cin >> isFilled;
2372
2373       // Close the local context
2374       TheAISContext()->CloseLocalContext(myCurrentIndex);
2375
2376       // Construction of the circle
2377       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
2378       gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2379       gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
2380
2381       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2382       Handle (Geom_Circle) theGeomCircle;
2383       try 
2384       {
2385         theGeomCircle = Cir.Value();
2386       }
2387       catch (StdFail_NotDone)
2388       {
2389         std::cout << "vcircle error: can't create circle\n";
2390         return -1; // TCL_ERROR
2391       }
2392
2393       DisplayCircle(theGeomCircle, aName, isFilled);
2394
2395     }
2396     // Shape is a face
2397     else
2398     {
2399       std::cout << " Select a vertex (in your face)\n";
2400       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2401
2402       TopoDS_Shape ShapeB;
2403       // Wait for picking
2404       Standard_Integer argccc = 5;
2405       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2406       const char **argvvv = (const char **) bufff;
2407       while (ViewerMainLoop( argccc, argvvv) ) { }
2408       // end of the loop
2409
2410       for(TheAISContext()->InitSelected(); 
2411         TheAISContext()->MoreSelected(); 
2412         TheAISContext()->NextSelected() ) 
2413       {
2414         ShapeB = TheAISContext()->SelectedShape();
2415       }
2416
2417       // Recover the radius 
2418       Standard_Real theRad;
2419       do 
2420       {
2421         std::cout << " Enter the value of the radius:\n";
2422         cin >> theRad;
2423       } while (theRad <= 0);
2424       
2425       // Get filled status
2426       Standard_Boolean isFilled;
2427       std::cout << "Enter filled status (0 or 1)\n";
2428       cin >> isFilled;
2429
2430       // Close the local context
2431       TheAISContext()->CloseLocalContext(myCurrentIndex);
2432       // Construction of the circle
2433
2434       // Recover the normal to the plane. tag
2435       TopoDS_Face myFace = TopoDS::Face(ShapeA);
2436       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2437       gp_Pln myPlane = mySurface.Plane();
2438       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2439       gp_Pln mygpPlane = theGeomPlane->Pln();
2440       gp_Ax1 thegpAxe = mygpPlane.Axis();
2441       gp_Dir theDir = thegpAxe.Direction();
2442
2443       // Recover the center
2444       gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2445
2446       // Construct the circle
2447       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2448       Handle (Geom_Circle) theGeomCircle;
2449       try 
2450       {
2451         theGeomCircle = Cir.Value();
2452       }
2453       catch (StdFail_NotDone)
2454       {
2455         std::cout << "vcircle error: can't create circle\n";
2456         return -1; // TCL_ERROR
2457       }
2458
2459       DisplayCircle(theGeomCircle, aName, isFilled);
2460       
2461     }
2462
2463   }
2464
2465   return 0;
2466 }
2467
2468 //=======================================================================
2469 //function : VDrawText
2470 //purpose  :
2471 //=======================================================================
2472 static int VDrawText (Draw_Interpretor& theDI,
2473                       Standard_Integer  theArgsNb,
2474                       const char**      theArgVec)
2475 {
2476   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2477   if (theArgsNb < 3)
2478   {
2479     std::cout << "Error: wrong number of arguments! See usage:\n";
2480     theDI.PrintHelp (theArgVec[0]);
2481     return 1;
2482   }
2483   else if (aContext.IsNull())
2484   {
2485     std::cout << "Error: no active view!\n";
2486     return 1;
2487   }
2488
2489   Standard_Integer           anArgIt = 1;
2490   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2491   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2492   Handle(AIS_TextLabel)      aTextPrs;
2493   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2494
2495   Standard_Boolean isNewPrs = Standard_False;
2496   if (GetMapOfAIS().IsBound2 (aName))
2497   {
2498     aTextPrs = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2499   }
2500
2501   if (aTextPrs.IsNull())
2502   {
2503     isNewPrs = Standard_True;
2504     aTextPrs = new AIS_TextLabel();
2505     aTextPrs->SetFont ("Courier");
2506   }
2507
2508   aTextPrs->SetText (aText);
2509
2510   Handle(Graphic3d_TransformPers) aTrsfPers;
2511   Aspect_TypeOfDisplayText aDisplayType = Aspect_TODT_NORMAL;
2512
2513   Standard_Boolean aHasPlane = Standard_False;
2514   gp_Dir           aNormal;
2515   gp_Dir           aDirection;
2516   gp_Pnt           aPos;
2517
2518   for (; anArgIt < theArgsNb; ++anArgIt)
2519   {
2520     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2521     aParam.LowerCase();
2522
2523     if (anAutoUpdater.parseRedrawMode (aParam))
2524     {
2525       continue;
2526     }
2527     else if (aParam == "-pos"
2528           || aParam == "-position")
2529     {
2530       if (anArgIt + 3 >= theArgsNb)
2531       {
2532         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2533         return 1;
2534       }
2535
2536       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2537       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2538       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2539       aTextPrs->SetPosition (aPos);
2540     }
2541     else if (aParam == "-color")
2542     {
2543       if (anArgIt + 1 >= theArgsNb)
2544       {
2545         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2546         return 1;
2547       }
2548
2549       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2550       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2551       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2552       {
2553         anArgIt += 1;
2554         aTextPrs->SetColor (aNameOfColor);
2555         continue;
2556       }
2557       else if (anArgIt + 3 >= theArgsNb)
2558       {
2559         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2560         return 1;
2561       }
2562
2563       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2564       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2565       if (!aColor.IsRealValue()
2566        || !aGreen.IsRealValue()
2567        || !aBlue.IsRealValue())
2568       {
2569         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2570         return 1;
2571       }
2572
2573       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2574                                    aGreen.RealValue(),
2575                                    aBlue.RealValue());
2576
2577       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2578       anArgIt += 3;
2579     }
2580     else if (aParam == "-halign")
2581     {
2582       if (++anArgIt >= theArgsNb)
2583       {
2584         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2585         return 1;
2586       }
2587
2588       TCollection_AsciiString aType (theArgVec[anArgIt]);
2589       aType.LowerCase();
2590       if (aType == "left")
2591       {
2592         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2593       }
2594       else if (aType == "center")
2595       {
2596         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2597       }
2598       else if (aType == "right")
2599       {
2600         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2601       }
2602       else
2603       {
2604         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2605         return 1;
2606       }
2607     }
2608     else if (aParam == "-valign")
2609     {
2610       if (++anArgIt >= theArgsNb)
2611       {
2612         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2613         return 1;
2614       }
2615
2616       TCollection_AsciiString aType (theArgVec[anArgIt]);
2617       aType.LowerCase();
2618       if (aType == "top")
2619       {
2620         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2621       }
2622       else if (aType == "center")
2623       {
2624         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2625       }
2626       else if (aType == "bottom")
2627       {
2628         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2629       }
2630       else if (aType == "topfirstline")
2631       {
2632         aTextPrs->SetVJustification (Graphic3d_VTA_TOPFIRSTLINE);
2633       }
2634       else
2635       {
2636         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2637         return 1;
2638       }
2639     }
2640     else if (aParam == "-angle")
2641     {
2642       if (++anArgIt >= theArgsNb)
2643       {
2644         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2645         return 1;
2646       }
2647
2648       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2649     }
2650     else if (aParam == "-zoom")
2651     {
2652       if (++anArgIt >= theArgsNb)
2653       {
2654         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2655         return 1;
2656       }
2657
2658       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2659     }
2660     else if (aParam == "-height")
2661     {
2662       if (++anArgIt >= theArgsNb)
2663       {
2664         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2665         return 1;
2666       }
2667
2668       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2669     }
2670     else if (aParam == "-aspect")
2671     {
2672       if (++anArgIt >= theArgsNb)
2673       {
2674         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2675         return 1;
2676       }
2677
2678       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2679       anOption.LowerCase();
2680       if (anOption.IsEqual ("regular"))
2681       {
2682         aTextPrs->SetFontAspect (Font_FA_Regular);
2683       }
2684       else if (anOption.IsEqual ("bold"))
2685       {
2686         aTextPrs->SetFontAspect (Font_FA_Bold);
2687       }
2688       else if (anOption.IsEqual ("italic"))
2689       {
2690         aTextPrs->SetFontAspect (Font_FA_Italic);
2691       }
2692       else if (anOption.IsEqual ("bolditalic"))
2693       {
2694         aTextPrs->SetFontAspect (Font_FA_BoldItalic);
2695       }
2696     }
2697     else if (aParam == "-font")
2698     {
2699       if (++anArgIt >= theArgsNb)
2700       {
2701         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2702         return 1;
2703       }
2704
2705       aTextPrs->SetFont (theArgVec[anArgIt]);
2706     }
2707     else if (aParam == "-plane")
2708     {
2709       if (anArgIt + 6 >= theArgsNb)
2710       {
2711         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2712         return 1;
2713       }
2714
2715       Standard_Real aX = Draw::Atof (theArgVec[++anArgIt]);
2716       Standard_Real aY = Draw::Atof (theArgVec[++anArgIt]);
2717       Standard_Real aZ = Draw::Atof (theArgVec[++anArgIt]);
2718       aNormal.SetCoord (aX, aY, aZ);
2719
2720       aX = Draw::Atof (theArgVec[++anArgIt]);
2721       aY = Draw::Atof (theArgVec[++anArgIt]);
2722       aZ = Draw::Atof (theArgVec[++anArgIt]);
2723       aDirection.SetCoord (aX, aY, aZ);
2724
2725       aHasPlane = Standard_True;
2726     }
2727     else if (aParam == "-flipping")
2728     {
2729       aTextPrs->SetFlipping (Standard_True);
2730     }
2731     else if (aParam == "-disptype"
2732           || aParam == "-displaytype")
2733     {
2734       if (++anArgIt >= theArgsNb)
2735       {
2736         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2737         return 1;
2738       }
2739       TCollection_AsciiString aType (theArgVec[anArgIt]);
2740       aType.LowerCase();
2741       if (aType == "subtitle")
2742         aDisplayType = Aspect_TODT_SUBTITLE;
2743       else if (aType == "decal")
2744         aDisplayType = Aspect_TODT_DEKALE;
2745       else if (aType == "blend")
2746         aDisplayType = Aspect_TODT_BLEND;
2747       else if (aType == "dimension")
2748         aDisplayType = Aspect_TODT_DIMENSION;
2749       else if (aType == "normal")
2750         aDisplayType = Aspect_TODT_NORMAL;
2751       else
2752       {
2753         std::cout << "Error: wrong display type '" << aType << "'.\n";
2754         return 1;
2755       }
2756     }
2757     else if (aParam == "-subcolor"
2758           || aParam == "-subtitlecolor")
2759     {
2760       if (anArgIt + 1 >= theArgsNb)
2761       {
2762         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2763         return 1;
2764       }
2765
2766       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2767       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2768       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2769       {
2770         anArgIt += 1;
2771         aTextPrs->SetColorSubTitle (aNameOfColor);
2772         continue;
2773       }
2774       else if (anArgIt + 3 >= theArgsNb)
2775       {
2776         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2777         return 1;
2778       }
2779
2780       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2781       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2782       if (!aColor.IsRealValue()
2783        || !aGreen.IsRealValue()
2784        || !aBlue.IsRealValue())
2785       {
2786         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2787         return 1;
2788       }
2789
2790       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2791                                    aGreen.RealValue(),
2792                                    aBlue.RealValue());
2793
2794       aTextPrs->SetColorSubTitle (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2795       anArgIt += 3;
2796     }
2797     else if (aParam == "-2d")
2798     {
2799       aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_2d);
2800     }
2801     else if (aParam == "-trsfperspos"
2802           || aParam == "-perspos")
2803     {
2804       if (anArgIt + 2 >= theArgsNb)
2805       {
2806         std::cerr << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2807         return 1;
2808       }
2809
2810       TCollection_AsciiString aX (theArgVec[++anArgIt]);
2811       TCollection_AsciiString aY (theArgVec[++anArgIt]);
2812       TCollection_AsciiString aZ = "0";
2813       if (!aX.IsIntegerValue()
2814        || !aY.IsIntegerValue())
2815       {
2816         std::cerr << "Error: wrong syntax at '" << aParam << "'.\n";
2817         return 1;
2818       }
2819       if (anArgIt + 1 < theArgsNb)
2820       {
2821         TCollection_AsciiString aTemp = theArgVec[anArgIt + 1];
2822         if (aTemp.IsIntegerValue())
2823         {
2824           aZ = aTemp;
2825           ++anArgIt;
2826         }
2827       }
2828
2829       aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (Graphic3d_TMF_2d, gp_Pnt (aX.IntegerValue(), aY.IntegerValue(), aZ.IntegerValue()));
2830     }
2831     else
2832     {
2833       std::cout << "Error: unknown argument '" << aParam << "'\n";
2834       return 1;
2835     }
2836   }
2837
2838   if (aHasPlane)
2839   {
2840     aTextPrs->SetOrientation3D (gp_Ax2 (aPos, aNormal, aDirection));
2841   }
2842
2843   aTextPrs->SetDisplayType (aDisplayType);
2844
2845   if (!aTrsfPers.IsNull())
2846   {
2847     aContext->SetTransformPersistence (aTextPrs, aTrsfPers);
2848     aTextPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
2849     if (aTextPrs->Position().Z() != 0)
2850     {
2851       aTextPrs->SetPosition (gp_Pnt(aTextPrs->Position().X(), aTextPrs->Position().Y(), 0));
2852     }
2853   }
2854   else if (!aTextPrs->TransformPersistence().IsNull())
2855   {
2856     aContext->SetTransformPersistence (aTextPrs, Handle(Graphic3d_TransformPers)());
2857   }
2858
2859   if (isNewPrs)
2860   {
2861     ViewerTest::Display (aName, aTextPrs, Standard_False);
2862   }
2863   else
2864   {
2865     aContext->Redisplay (aTextPrs, Standard_False, Standard_True);
2866   }
2867   return 0;
2868 }
2869
2870 #include <math.h>
2871 #include <gp_Pnt.hxx>
2872 #include <Graphic3d_ArrayOfPoints.hxx>
2873 #include <Graphic3d_ArrayOfPrimitives.hxx>
2874 #include <Graphic3d_ArrayOfTriangles.hxx>
2875 #include <Poly_Array1OfTriangle.hxx>
2876 #include <Poly_Triangle.hxx>
2877 #include <Poly_Triangulation.hxx>
2878 #include <TColgp_Array1OfPnt.hxx>
2879 #include <TShort_Array1OfShortReal.hxx>
2880 #include <TShort_HArray1OfShortReal.hxx>
2881
2882 #include <AIS_Triangulation.hxx>
2883 #include <StdPrs_ToolTriangulatedShape.hxx>
2884 #include <Poly_Connect.hxx>
2885 #include <TColgp_Array1OfDir.hxx>
2886 #include <Graphic3d_GraphicDriver.hxx>
2887
2888 #include <TColStd_Array1OfInteger.hxx>
2889 #include <TColStd_HArray1OfInteger.hxx>
2890 #include <Prs3d_ShadingAspect.hxx>
2891 #include <Graphic3d_MaterialAspect.hxx>
2892 #include <Graphic3d_AspectFillArea3d.hxx>
2893
2894 #include <BRepPrimAPI_MakeCylinder.hxx>
2895 #include <TopoDS_Shape.hxx>
2896 #include <TopExp_Explorer.hxx>
2897 #include <TopAbs.hxx>
2898 #include <StdSelect_ShapeTypeFilter.hxx>
2899 #include <AIS_InteractiveObject.hxx>
2900
2901
2902 //===============================================================================================
2903 //function : CalculationOfSphere
2904 //author   : psn
2905 //purpose  : Create a Sphere
2906 //===============================================================================================
2907
2908 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2909                                                   int res ,
2910                                                   double Radius ){
2911   double mRadius = Radius;
2912   double mCenter[3] = {X,Y,Z};
2913   int mThetaResolution;
2914   int mPhiResolution;
2915   double mStartTheta = 0;//StartTheta;
2916   double mEndTheta = 360;//EndTheta;
2917   double mStartPhi = 0;//StartPhi;
2918   double mEndPhi = 180;//EndPhi;
2919   res = res < 4 ? 4 : res;
2920
2921   mThetaResolution = res;
2922   mPhiResolution = res;
2923
2924   int i, j;
2925   int jStart, jEnd, numOffset;
2926   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2927   double startTheta, endTheta, startPhi, endPhi;
2928   int base, numPoles=0, thetaResolution, phiResolution;
2929
2930   int pts[3];
2931   int piece = -1;
2932   int numPieces = 1;
2933   if ( numPieces > mThetaResolution ) {
2934     numPieces = mThetaResolution;
2935   }
2936
2937   int localThetaResolution =  mThetaResolution;
2938   double localStartTheta =  mStartTheta;
2939   double localEndTheta =  mEndTheta;
2940
2941   while ( localEndTheta < localStartTheta ) {
2942     localEndTheta += 360.0;
2943   }
2944
2945   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2946
2947   // Change the ivars based on pieces.
2948   int start, end;
2949   start = piece * localThetaResolution / numPieces;
2950   end = (piece+1) * localThetaResolution / numPieces;
2951   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2952   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2953   localThetaResolution = end - start;
2954
2955   // Create north pole if needed
2956   int number_point = 0;
2957   int number_pointArray = 0;
2958
2959   if ( mStartPhi <= 0.0 ) {
2960     number_pointArray++;
2961     numPoles++;
2962   }
2963   if ( mEndPhi >= 180.0 ) {
2964     number_pointArray++;
2965     numPoles++;
2966   }
2967
2968   // Check data, determine increments, and convert to radians
2969   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2970   startTheta *= M_PI  / 180.0;
2971   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2972   endTheta *= M_PI  / 180.0;
2973
2974
2975   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2976   startPhi *= M_PI  / 180.0;
2977   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2978   endPhi *= M_PI  / 180.0;
2979
2980   phiResolution =  mPhiResolution - numPoles;
2981   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2982   thetaResolution = localThetaResolution;
2983   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2984     ++localThetaResolution;
2985   }
2986   deltaTheta = (endTheta - startTheta) / thetaResolution;
2987
2988   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2989   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2990
2991   // Create intermediate points
2992   for ( i = 0; i < localThetaResolution; i++ ) {
2993     for ( j = jStart; j < jEnd; j++ ) {
2994         number_pointArray++;
2995     }
2996   }
2997
2998   //Generate mesh connectivity
2999   base = phiResolution * localThetaResolution;
3000
3001   int number_triangle = 0 ;
3002   if ( mStartPhi <= 0.0 ) { // around north pole
3003     number_triangle += localThetaResolution;
3004   }
3005
3006   if ( mEndPhi >= 180.0 ) { // around south pole
3007     number_triangle += localThetaResolution;
3008   }
3009
3010   // bands in-between poles
3011   for ( i=0; i < localThetaResolution; i++){
3012     for ( j=0; j < (phiResolution-1); j++){
3013        number_triangle +=2;
3014     }
3015   }
3016
3017   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
3018   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
3019   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
3020
3021   if (  mStartPhi <= 0.0 ){
3022       x[0] =  mCenter[0];
3023       x[1] =  mCenter[1];
3024       x[2] =  mCenter[2] +  mRadius;
3025       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
3026   }
3027
3028   // Create south pole if needed
3029   if (  mEndPhi >= 180.0 ){
3030       x[0] =  mCenter[0];
3031       x[1] =  mCenter[1];
3032       x[2] =  mCenter[2] -  mRadius;
3033       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
3034   }
3035
3036   number_point = 3;
3037   for ( i=0; i < localThetaResolution; i++){
3038     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
3039     for ( j = jStart; j < jEnd; j++){
3040         phi = startPhi + j*deltaPhi;
3041         radius =  mRadius * sin((double)phi);
3042         n[0] = radius * cos((double)theta);
3043         n[1] = radius * sin((double)theta);
3044         n[2] =  mRadius * cos((double)phi);
3045         x[0] = n[0] +  mCenter[0];
3046         x[1] = n[1] +  mCenter[1];
3047         x[2] = n[2] +  mCenter[2];
3048         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
3049         number_point++;
3050       }
3051     }
3052
3053   numPoles = 3;
3054   number_triangle = 1;
3055   if ( mStartPhi <= 0.0 ){// around north pole
3056     for (i=0; i < localThetaResolution; i++){
3057         pts[0] = phiResolution*i + numPoles;
3058         pts[1] = (phiResolution*(i+1) % base) + numPoles;
3059         pts[2] = 1;
3060         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
3061         number_triangle++;
3062       }
3063     }
3064
3065   if (  mEndPhi >= 180.0 ){ // around south pole
3066     numOffset = phiResolution - 1 + numPoles;
3067     for (i=0; i < localThetaResolution; i++){
3068         pts[0] = phiResolution*i + numOffset;
3069         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
3070         pts[1] = numPoles - 1;
3071         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
3072         number_triangle++;
3073       }
3074     }
3075
3076   // bands in-between poles
3077
3078   for (i=0; i < localThetaResolution; i++){
3079     for (j=0; j < (phiResolution-1); j++){
3080         pts[0] = phiResolution*i + j + numPoles;
3081         pts[1] = pts[0] + 1;
3082         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
3083         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
3084         number_triangle++;
3085         pts[1] = pts[2];
3086         pts[2] = pts[1] - 1;
3087         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
3088         number_triangle++;
3089       }
3090     }
3091
3092   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
3093
3094   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
3095
3096   Standard_Integer index[3];
3097   Standard_Real Tol = Precision::Confusion();
3098
3099   gp_Dir Nor;
3100   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
3101       gp_XYZ eqPlan(0, 0, 0);
3102       for ( pc->Initialize(i); pc->More(); pc->Next()) {
3103         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
3104         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
3105         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
3106         gp_XYZ vv = v1^v2;
3107         Standard_Real mod = vv.Modulus();
3108         if(mod < Tol) continue;
3109         eqPlan += vv/mod;
3110       }
3111
3112       Standard_Real modmax = eqPlan.Modulus();
3113
3114       if(modmax > Tol)
3115         Nor = gp_Dir(eqPlan);
3116       else
3117         Nor = gp_Dir(0., 0., 1.);
3118       
3119       Standard_Integer k = (i - PointsOfArray.Lower()) * 3;
3120       Normals->SetValue(k + 1, (Standard_ShortReal)Nor.X());
3121       Normals->SetValue(k + 2, (Standard_ShortReal)Nor.Y());
3122       Normals->SetValue(k + 3, (Standard_ShortReal)Nor.Z());
3123   }
3124
3125   delete pc;
3126   polyTriangulation->SetNormals(Normals);
3127
3128   return polyTriangulation;
3129 }
3130
3131 //===============================================================================================
3132 //function : VDrawSphere
3133 //author   : psn
3134 //purpose  : Create an AIS shape.
3135 //===============================================================================================
3136 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
3137 {
3138   // check for errors
3139   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3140   if (aContextAIS.IsNull())
3141   {
3142     std::cout << "Call vinit before!\n";
3143     return 1;
3144   }
3145   else if (argc < 3)
3146   {
3147     std::cout << "Use: " << argv[0]
3148               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
3149     return 1;
3150   }
3151
3152   // read the arguments
3153   TCollection_AsciiString aShapeName (argv[1]);
3154   Standard_Integer aResolution = Draw::Atoi (argv[2]);
3155   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
3156   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
3157   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
3158   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
3159   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
3160   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
3161
3162   // remove AIS object with given name from map
3163   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
3164
3165   if (toPrintInfo)
3166     std::cout << "Compute Triangulation...\n";
3167   Handle(AIS_Triangulation) aShape
3168     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
3169                                                   aResolution,
3170                                                   aRadius));
3171   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
3172   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
3173
3174   // stupid initialization of Green color in RGBA space as integer
3175   // probably wrong for big-endian CPUs
3176   const Graphic3d_Vec4ub aColor (0, 255, 0, 0);
3177
3178   // setup colors array per vertex
3179   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
3180   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
3181   {
3182     aColorArray->SetValue (aNodeId, *reinterpret_cast<const Standard_Integer*> (&aColor));
3183   }
3184   aShape->SetColors (aColorArray);
3185
3186   // show statistics
3187   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
3188   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
3189   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
3190   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
3191   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
3192   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
3193   aTotalSize >>= 20; //MB
3194   aNormalsSize >>= 20;
3195   aColorsSize >>= 20;
3196   aTrianglesSize >>= 20;
3197   aPolyConnectSize >>= 20;
3198   if (toPrintInfo)
3199   {
3200     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
3201       << "NumberOfTriangles: " << aNumberTriangles << "\n"
3202       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
3203       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
3204       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
3205       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
3206   }
3207
3208   // Setting material properties, very important for desirable visual result!
3209   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
3210   aMat.SetAmbient (0.2);
3211   aMat.SetSpecular (0.5);
3212   Handle(Graphic3d_AspectFillArea3d) anAspect
3213     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
3214                                       Quantity_NOC_RED,
3215                                       Quantity_NOC_YELLOW,
3216                                       Aspect_TOL_SOLID,
3217                                       1.0,
3218                                       aMat,
3219                                       aMat);
3220   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
3221   if (toShowEdges)
3222   {
3223     anAspect->SetEdgeOn();
3224   }
3225   else
3226   {
3227     anAspect->SetEdgeOff();
3228   }
3229   aShAsp->SetAspect (anAspect);
3230   aShape->Attributes()->SetShadingAspect (aShAsp);
3231
3232   VDisplayAISObject (aShapeName, aShape);
3233   return 0;
3234 }
3235
3236 //=============================================================================
3237 //function : VComputeHLR
3238 //purpose  :
3239 //=============================================================================
3240
3241 static int VComputeHLR (Draw_Interpretor& di,
3242                         Standard_Integer argc,
3243                         const char** argv)
3244 {
3245   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3246
3247   if (aContextAIS.IsNull ())
3248   {
3249     di << "Please call vinit before\n";
3250     return 1;
3251   }
3252
3253   if ( argc != 3 &&  argc != 12 )
3254   {
3255     di << "Usage: " << argv[0] << " ShapeName HlrName "
3256        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]\n"
3257        << "                    ShapeName - name of the initial shape\n"
3258        << "                    HlrName - result hlr object from initial shape\n"
3259        << "                    eye, dir are eye position and look direction\n"
3260        << "                    up is the look up direction vector\n"
3261        << "                    Use vtop to see projected hlr shape\n";
3262     return 1;
3263   }
3264
3265   // shape and new object name
3266   TCollection_AsciiString aShapeName (argv[1]);
3267   TCollection_AsciiString aHlrName (argv[2]);
3268
3269   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3270   if (aSh.IsNull()) 
3271   {
3272     BRep_Builder aBrepBuilder;
3273     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3274     if (aSh.IsNull ())
3275     {
3276       di << "No shape with name " << argv[1] << " found\n";
3277       return 1;
3278     }
3279   }
3280
3281   if (GetMapOfAIS ().IsBound2 (aHlrName))
3282   {
3283     di << "Presentable object with name " << argv[2] << " already exists\n";
3284     return 1;
3285   }
3286
3287   // close local context
3288   if (aContextAIS->HasOpenedContext ())
3289     aContextAIS->CloseLocalContext ();
3290
3291   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3292   HLRBRep_PolyHLRToShape aHLRToShape;
3293
3294   gp_Pnt anEye;
3295   gp_Dir aDir;
3296   gp_Ax2 aProjAx;
3297   if (argc == 9)
3298   {
3299     gp_Dir anUp;
3300
3301     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3302     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3303     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3304     aProjAx.SetLocation (anEye);
3305     aProjAx.SetDirection (aDir);
3306     aProjAx.SetYDirection (anUp);
3307   }
3308   else
3309   {
3310     gp_Dir aRight;
3311
3312     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3313     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3314     Standard_Integer aWidth, aHeight;
3315     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3316     Standard_Real aRightX, aRightY, aRightZ;
3317     aView->Window()->Size (aWidth, aHeight);
3318
3319     aView->ConvertWithProj (aWidth, aHeight/2, 
3320                             aRightX, aRightY, aRightZ,
3321                             aDirX, aDirY, aDirZ);
3322
3323     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3324                             aCentX, aCentY, aCentZ,
3325                             aDirX, aDirY, aDirZ);
3326
3327     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3328     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3329     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3330     aProjAx.SetLocation (anEye);
3331     aProjAx.SetDirection (aDir);
3332     aProjAx.SetXDirection (aRight);
3333   }
3334
3335   HLRAlgo_Projector aProjector (aProjAx);
3336   aPolyAlgo->Projector (aProjector);
3337   aPolyAlgo->Load (aSh);
3338   aPolyAlgo->Update ();
3339
3340   aHLRToShape.Update (aPolyAlgo);
3341
3342   // make hlr shape from input shape
3343   TopoDS_Compound aHlrShape;
3344   BRep_Builder aBuilder;
3345   aBuilder.MakeCompound (aHlrShape);
3346
3347   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3348   if (!aCompound.IsNull ())
3349   {
3350     aBuilder.Add (aHlrShape, aCompound);
3351   }
3352   
3353   // extract visible outlines
3354   aCompound = aHLRToShape.OutLineVCompound();
3355   if (!aCompound.IsNull ())
3356   {
3357     aBuilder.Add (aHlrShape, aCompound);
3358   }
3359
3360   // create an AIS shape and display it
3361   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3362   GetMapOfAIS().Bind (anObject, aHlrName);
3363   aContextAIS->Display (anObject);
3364
3365   aContextAIS->UpdateCurrentViewer ();
3366
3367   return 0;
3368 }
3369
3370 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3371 // manipulating and displaying such an array with AIS context
3372
3373 class MyPArrayObject : public AIS_InteractiveObject
3374 {
3375
3376 public:
3377
3378   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3379                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3380   {
3381     myArrayDescription = theArrayDescription;
3382     myMarkerAspect = theMarkerAspect;
3383   }
3384
3385   DEFINE_STANDARD_RTTI_INLINE(MyPArrayObject,AIS_InteractiveObject);
3386
3387 private:
3388
3389   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3390                 const Handle(Prs3d_Presentation)& aPresentation,
3391                 const Standard_Integer aMode) Standard_OVERRIDE;
3392
3393   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3394                          const Standard_Integer /*theMode*/) Standard_OVERRIDE;
3395
3396   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3397                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3398                           Standard_Integer &theArgIndex,
3399                           Standard_Integer theArgCount,
3400                           Standard_Integer theMaxArgs);
3401
3402 protected:
3403