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