0026029: Visualization - Poor performance of connected objects
[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_FontMgr.hxx>
27 #include <OSD_Chronometer.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <Visual3d_View.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_Drawer.hxx>
132 #include <Prs3d_VertexDrawMode.hxx>
133 #include <Prs3d_LineAspect.hxx>
134 #include <Prs3d_PointAspect.hxx>
135
136 #include <Image_AlienPixMap.hxx>
137 #include <TColStd_HArray1OfAsciiString.hxx>
138
139 #ifdef _WIN32
140 # define _CRT_SECURE_NO_DEPRECATE
141 # pragma warning (disable:4996)
142 #endif
143
144 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
145 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
146                                            const Handle(AIS_InteractiveObject)& theAISObj,
147                                            Standard_Boolean theReplaceIfExists = Standard_True);
148 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
149 extern Handle(AIS_InteractiveContext)& TheAISContext();
150
151
152 //==============================================================================
153 //function : Vtrihedron 2d
154 //purpose  : Create a plane with a 2D  trihedron from a faceselection
155 //Draw arg : vtri2d  name
156 //==============================================================================
157 #include <AIS_PlaneTrihedron.hxx>
158
159
160
161 static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
162
163 {
164   // Verification des arguments
165   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
166
167   // Declarations
168   Standard_Integer myCurrentIndex;
169   // Fermeture des contextes
170   TheAISContext()->CloseAllContexts();
171   // Ouverture d'un contexte local et recuperation de son index.
172   TheAISContext()->OpenLocalContext();
173   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
174   // On active les modes de selections faces.
175   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
176   di<<" Select a face ."<<"\n";
177
178   // Boucle d'attente waitpick.
179   Standard_Integer argccc = 5;
180   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
181   const char **argvvv = (const char **) bufff;
182   while (ViewerMainLoop( argccc, argvvv) ) { }
183   // fin de la boucle
184
185   TopoDS_Shape ShapeB;
186   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
187     ShapeB = TheAISContext()->SelectedShape();
188   }
189
190   TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
191
192   // Construction du Plane
193   // recuperation des edges des faces.
194   TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
195
196   TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
197   // declarations
198   gp_Pnt A,B,C;
199
200   // si il y a plusieurs edges
201   if (FaceExpB.More() ) {
202     FaceExpB.Next();
203     TopoDS_Edge EdgeC=TopoDS::Edge(FaceExpB.Current() );
204     BRepAdaptor_Curve theCurveB(EdgeB);
205     BRepAdaptor_Curve theCurveC(EdgeC);
206     A=theCurveC.Value(0.1);
207     B=theCurveC.Value(0.9);
208     C=theCurveB.Value(0.5);
209   }
210   else {
211     // FaceB a 1 unique edge courbe
212     BRepAdaptor_Curve theCurveB(EdgeB);
213     A=theCurveB.Value(0.1);
214     B=theCurveB.Value(0.9);
215     C=theCurveB.Value(0.5);
216   }
217   // Construction du Geom_Plane
218   GC_MakePlane MkPlane(A,B,C);
219   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
220
221   // Construction de l'AIS_PlaneTrihedron
222   Handle(AIS_PlaneTrihedron) theAISPlaneTri= new AIS_PlaneTrihedron(theGeomPlane );
223
224   // Fermeture du contexte local.
225   TheAISContext()->CloseLocalContext(myCurrentIndex);
226
227   // on le display & bind
228   TheAISContext()->Display(theAISPlaneTri );
229   GetMapOfAIS().Bind ( theAISPlaneTri ,argv[1]);
230
231   return 0;
232 }
233
234
235
236 //==============================================================================
237 //function : VTriherdron
238 //purpose  : Create a trihedron. If no arguments are set, the default
239 //           trihedron (Oxyz) is created.
240 //Draw arg : vtrihedron  name  [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw]
241 //==============================================================================
242
243 static int VTrihedron (Draw_Interpretor& theDi,
244                        Standard_Integer  theArgsNb,
245                        const char**      theArgVec)
246 {
247   if (theArgsNb != 2 && theArgsNb != 5 && theArgsNb != 11)
248   {
249     theDi << theArgVec[0] << " Syntax error\n";
250     return 1;
251   }
252
253   gp_Pnt anOrigin (0.0, 0.0, 0.0);
254   gp_Dir aDirZ = gp::DZ();
255   gp_Dir aDirX = gp::DX();
256   Standard_Integer anArgIter = 2; // 1st is an IO name
257   if (anArgIter < theArgsNb)
258   {
259     anOrigin.SetX (Draw::Atof (theArgVec[anArgIter++]));
260     anOrigin.SetY (Draw::Atof (theArgVec[anArgIter++]));
261     anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter++]));
262     if (anArgIter < theArgsNb)
263     {
264       Standard_Real aX = Draw::Atof (theArgVec[anArgIter++]);
265       Standard_Real aY = Draw::Atof (theArgVec[anArgIter++]);
266       Standard_Real aZ = Draw::Atof (theArgVec[anArgIter++]);
267       aDirZ.SetCoord (aX, aY, aZ);
268
269       aX = Draw::Atof (theArgVec[anArgIter++]);
270       aY = Draw::Atof (theArgVec[anArgIter++]);
271       aZ = Draw::Atof (theArgVec[anArgIter++]);
272       aDirX.SetCoord (aX, aY, aZ);
273     }
274   }
275
276   if (!aDirZ.IsNormal (aDirX, M_PI / 180.0))
277   {
278     theDi << theArgVec[0] << " - VectorX is not normal to VectorZ\n";
279     return 1;
280   }
281
282   Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (anOrigin, aDirZ, aDirX);
283   Handle(AIS_Trihedron) aShape = new AIS_Trihedron (aPlacement);
284   VDisplayAISObject (theArgVec[1], aShape);
285   return 0;
286 }
287
288 //==============================================================================
289 //function : VSize
290 //author   : ege
291 //purpose  : Change the size of a named or selected trihedron
292 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
293 //           if no value, the value is set at 100 by default
294 //Draw arg : vsize [name] [size]
295 //==============================================================================
296
297 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
298
299 {
300   // Declaration de booleens
301   Standard_Boolean             ThereIsName;
302   Standard_Boolean             ThereIsCurrent;
303   Standard_Real                value;
304   Standard_Boolean             hascol;
305
306   Quantity_NameOfColor         col = Quantity_NOC_BLACK ;
307
308   // Verification des arguments
309   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error"<<"\n"; return 1;}
310
311   // Verification du nombre d'arguments
312   if (argc==1)      {ThereIsName=Standard_False;value=100;}
313   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
314   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
315
316   // On ferme le contexte local pour travailler dans le contexte global
317   if(TheAISContext()->HasOpenedContext())
318     TheAISContext()->CloseLocalContext();
319
320   // On set le booleen ThereIsCurrent
321   if (TheAISContext() -> NbCurrents() > 0) {ThereIsCurrent=Standard_True;}
322   else {ThereIsCurrent=Standard_False;}
323
324
325
326   //===============================================================
327   // Il n'y a pas de nom  mais des objets selectionnes
328   //===============================================================
329   if (!ThereIsName && ThereIsCurrent)
330   {
331
332     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
333       it (GetMapOfAIS());
334
335     while ( it.More() ) {
336
337       Handle(AIS_InteractiveObject) aShape=
338         Handle(AIS_InteractiveObject)::DownCast(it.Key1());
339
340       if (!aShape.IsNull() &&  TheAISContext()->IsCurrent(aShape) )
341       {
342
343         // On verifie que l'AIS InteraciveObject selectionne est bien
344         // un AIS_Trihedron
345         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
346
347           if (aShape->HasColor()) {
348             hascol=Standard_True;
349
350             // On recupere la couleur de aShape
351             col=aShape->Color();}
352
353           else hascol=Standard_False;
354
355           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
356           // pour lui appliquer la methode SetSize()
357           Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
358
359           // C'est bien un triedre,on chage sa valeur!
360           aTrihedron->SetSize(value);
361
362           // On donne la couleur au Trihedron
363           if(hascol)   aTrihedron->SetColor(col);
364           else         aTrihedron->UnsetColor();
365
366
367           // The trihedron hasn't be errased from the map
368           // so you just have to redisplay it
369           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
370
371         }
372
373       }
374
375       it.Next();
376     }
377
378     TheAISContext() ->UpdateCurrentViewer();
379   }
380
381   //===============================================================
382   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
383   //===============================================================
384
385
386
387   //===============================================================
388   // Il y a un nom de triedre passe en argument
389   //===============================================================
390   if (ThereIsName) {
391     TCollection_AsciiString name=argv[1];
392
393     // on verifie que ce nom correspond bien a une shape
394     Standard_Boolean IsBound= GetMapOfAIS().IsBound2(name);
395
396     if (IsBound) {
397
398       // on recupere la shape dans la map des objets displayes
399       Handle(AIS_InteractiveObject) aShape =
400         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
401
402       // On verifie que l'AIS InteraciveObject est bien
403       // un AIS_Trihedron
404       if (!aShape.IsNull() &&
405         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
406       {
407
408         if (aShape->HasColor()) {
409           hascol=Standard_True;
410
411           // On recupere la couleur de aShape
412           col=aShape->Color();}
413
414         else hascol=Standard_False;
415
416         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
417         // pour lui appliquer la methode SetSize()
418         Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
419
420         // C'est bien un triedre,on chage sa valeur
421         aTrihedron->SetSize(value);
422
423         // On donne la couleur au Trihedron
424         if(hascol)   aTrihedron->SetColor(col);
425         else         aTrihedron->UnsetColor();
426
427         // The trihedron hasn't be errased from the map
428         // so you just have to redisplay it
429         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
430
431         TheAISContext() ->UpdateCurrentViewer();
432       }
433     }
434   }
435   return 0;
436 }
437
438
439 //==============================================================================
440
441 //==============================================================================
442 //function : VPlaneTrihedron
443 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
444 //Draw arg : vplanetri  name
445 //==============================================================================
446 #include <AIS_Plane.hxx>
447
448
449
450 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
451
452 {
453   // Verification des arguments
454   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
455
456   // Declarations
457   Standard_Integer myCurrentIndex;
458   // Fermeture des contextes locaux
459   TheAISContext()->CloseAllContexts();
460
461   // On recupere tous les trihedrons de la GetMapOfAIS()
462   // et on active le mode de selection par face.
463   // =================================================
464
465   // Ouverture d'un contexte local et recuperation de son index.
466   TheAISContext()->OpenLocalContext(Standard_False);
467   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
468
469   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
470     it (GetMapOfAIS());
471   while(it.More()){
472     Handle(AIS_InteractiveObject) ShapeA =
473       Handle(AIS_InteractiveObject)::DownCast(it.Key1());
474     // On verifie que c'est bien un trihedron
475     if (!ShapeA.IsNull() &&
476       ShapeA->Type()==AIS_KOI_Datum  && ShapeA->Signature()==3  ) {
477         // on le downcast
478         Handle(AIS_Trihedron) TrihedronA =((*(Handle(AIS_Trihedron)*)&ShapeA));
479         // on le charge dans le contexte et on active le mode Plane.
480         TheAISContext()->Load(TrihedronA,0,Standard_False);
481         TheAISContext()->Activate(TrihedronA,3);
482       }
483       it.Next();
484   }
485
486   di<<" Select a plane."<<"\n";
487   // Boucle d'attente waitpick.
488   Standard_Integer argccc = 5;
489   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
490   const char **argvvv = (const char **) bufff;
491   while (ViewerMainLoop( argccc, argvvv) ) { }
492   // fin de la boucle
493
494   Handle(AIS_InteractiveObject) theIOB;
495   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
496     theIOB = TheAISContext()->Interactive();
497   }
498   // on le downcast
499   Handle(AIS_Plane) PlaneB =((*(Handle(AIS_Plane)*)&theIOB));
500
501   // Fermeture du contexte local.
502   TheAISContext()->CloseLocalContext(myCurrentIndex);
503
504   // on le display & bind
505   TheAISContext()->Display(PlaneB );
506   GetMapOfAIS().Bind ( PlaneB ,argv[1]);
507
508   return 0;
509 }
510
511
512
513 //==============================================================================
514 // Fonction        First click      2de click
515 //
516 // vaxis           vertex           vertex
517 //                 edge             None
518 // vaxispara       edge             vertex
519 // vaxisortho      edge             Vertex
520 // vaxisinter      Face             Face
521 //==============================================================================
522
523 //==============================================================================
524 //function : VAxisBuilder
525 //purpose  :
526 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
527 //==============================================================================
528 #include <TopoDS_Edge.hxx>
529 #include <TopoDS_Vertex.hxx>
530 #include <TopExp.hxx>
531 #include <Geom_Line.hxx>
532
533 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
534 {
535   // Declarations
536   Standard_Boolean HasArg;
537   TCollection_AsciiString name;
538   Standard_Integer MyCurrentIndex;
539
540   // Verification
541   if (argc<2 || argc>8 ) {di<<" Syntaxe error"<<"\n";return 1;}
542   if (argc==8) HasArg=Standard_True;
543   else HasArg=Standard_False;
544
545   name=argv[1];
546   // Fermeture des contextes
547   TheAISContext()->CloseAllContexts();
548
549   // Cas ou il y a des arguments
550   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
551   if (HasArg) {
552     Standard_Real coord[6];
553     for(Standard_Integer i=0;i<=5;i++){
554       coord[i]=Draw::Atof(argv[2+i]);
555     }
556     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
557
558     gp_Vec myVect (p1,p2);
559     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
560     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
561     GetMapOfAIS().Bind (TheAxis,name);
562     TheAISContext()->Display(TheAxis);
563   }
564
565   // Pas d'arguments
566   else {
567     // fonction vaxis
568     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
569     if ( !strcasecmp(argv[0], "vaxis")) {
570       TheAISContext()->OpenLocalContext();
571       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
572
573       // Active le mode edge et le mode vertex
574       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
575       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
576       di<<" Select an edge or a vertex."<<"\n";
577
578       // Boucle d'attente waitpick.
579       Standard_Integer argcc = 5;
580       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
581       const char **argvv = (const char **) buff;
582       while (ViewerMainLoop( argcc, argvv) ) { }
583       // fin de la boucle
584
585       // recuperation de la shape.
586       TopoDS_Shape ShapeA;
587       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
588         ShapeA = TheAISContext()->SelectedShape();
589       }
590       // recuperation de l'AIS_InteractiveObject
591       //Handle(AIS_InteractiveObject) myAISio=TheAISContext()->Current();
592       // down cast en AIS_Point si sig et type
593       // AIS_Point -> Geom_Pnt ....
594
595       if (ShapeA.ShapeType()==TopAbs_VERTEX) {
596         // on desactive le mode edge
597         TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
598         di<<" Select a different vertex."<<"\n";
599
600         TopoDS_Shape ShapeB;
601         do {
602           // Boucle d'attente waitpick.
603           Standard_Integer argccc = 5;
604           const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
605           const char **argvvv = (const char **) bufff;
606           while (ViewerMainLoop( argccc, argvvv) ) { }
607           // fin de la boucle
608           for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
609             ShapeB = TheAISContext()->SelectedShape();
610           }
611
612
613         } while(ShapeB.IsSame(ShapeA) );
614
615         // Fermeture du context local
616         TheAISContext()->CloseLocalContext(MyCurrentIndex);
617
618         // Construction de l'axe
619         gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
620         gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
621         gp_Vec   V (A,B);
622         gp_Dir   D (V);
623         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
624         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
625         GetMapOfAIS().Bind (TheAxis,name);
626         TheAISContext()->Display(TheAxis);
627       }
628       else {
629         // Un unique edge (ShapeA) a ete picke
630         // Fermeture du context local
631         TheAISContext()->CloseLocalContext(MyCurrentIndex);
632         // Constuction de l'axe
633         TopoDS_Edge    ed =TopoDS::Edge(ShapeA);
634         TopoDS_Vertex  Va,Vb;
635         TopExp::Vertices(ed,Va,Vb );
636         gp_Pnt A=BRep_Tool::Pnt(Va);
637         gp_Pnt B=BRep_Tool::Pnt(Vb);
638         gp_Vec  V (A,B);
639         gp_Dir   D (V);
640         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
641         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
642         GetMapOfAIS().Bind (TheAxis,name);
643         TheAISContext()->Display(TheAxis);
644       }
645
646     }
647
648     // Fonction axispara
649     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
650     else if ( !strcasecmp(argv[0], "vaxispara")) {
651
652       TheAISContext()->OpenLocalContext();
653       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
654
655       // Active le mode edge
656       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
657       di<<" Select an edge."<<"\n";
658
659       // Boucle d'attente waitpick.
660       Standard_Integer argcc = 5;
661       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
662       const char **argvv = (const char **) buff;
663       while (ViewerMainLoop( argcc, argvv) ) { }
664       // fin de la boucle
665
666       TopoDS_Shape ShapeA;
667       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
668         ShapeA = TheAISContext()->SelectedShape();
669       }
670       // Active le mode vertex et deactive edges
671       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
672       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
673       di<<" Select a vertex."<<"\n";
674
675       // Boucle d'attente waitpick.
676       Standard_Integer argccc = 5;
677       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
678       const char **argvvv = (const char **) bufff;
679       while (ViewerMainLoop( argccc, argvvv) ) { }
680       // fin de la boucle
681
682       // On peut choisir un pnt sur l'edge
683       TopoDS_Shape ShapeB;
684       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
685         ShapeB = TheAISContext()->SelectedShape();
686       }
687       // Fermeture du context local
688       TheAISContext()->CloseLocalContext(MyCurrentIndex);
689
690       // Construction de l'axe
691       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
692       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
693       TopoDS_Vertex  Va,Vc;
694       TopExp::Vertices(ed,Va,Vc );
695       gp_Pnt A=BRep_Tool::Pnt(Va);
696       gp_Pnt C=BRep_Tool::Pnt(Vc);
697       gp_Vec  V (A,C);
698       gp_Dir   D (V);
699       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
700       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
701       GetMapOfAIS().Bind (TheAxis,name);
702       TheAISContext()->Display(TheAxis);
703
704     }
705
706     // Fonction axisortho
707     else  {
708       TheAISContext()->OpenLocalContext();
709       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
710
711       // Active le mode edge
712       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
713       di<<" Select an edge."<<"\n";
714
715       // Boucle d'attente waitpick.
716       Standard_Integer argcc = 5;
717       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
718       const char **argvv = (const char **) buff;
719       while (ViewerMainLoop( argcc, argvv) ) { }
720       // fin de la boucle
721
722       TopoDS_Shape ShapeA;
723       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
724         ShapeA = TheAISContext()->SelectedShape();
725       }
726       // Active le mode vertex et deactive edges
727       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
728       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
729       di<<" Slect a vertex."<<"\n";
730
731       // Boucle d'attente waitpick.
732       Standard_Integer argccc = 5;
733       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
734       const char **argvvv = (const char **) bufff;
735       while (ViewerMainLoop( argccc, argvvv) ) { }
736       // fin de la boucle
737
738       // On peut choisir un pnt sur l'edge
739       TopoDS_Shape ShapeB;
740       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
741         ShapeB = TheAISContext()->SelectedShape();
742       }
743       // Fermeture du context local
744       TheAISContext()->CloseLocalContext(MyCurrentIndex);
745
746       // Construction de l'axe
747       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
748       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
749       TopoDS_Vertex  Va,Vc;
750       TopExp::Vertices(ed,Va,Vc );
751       gp_Pnt A=BRep_Tool::Pnt(Va);
752       gp_Pnt C=BRep_Tool::Pnt(Vc);
753       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
754       gp_Vec  V (A,E);
755       gp_Dir   D (V);
756       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
757       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
758       GetMapOfAIS().Bind (TheAxis,name);
759       TheAISContext()->Display(TheAxis);
760
761     }
762
763   }
764   return 0;
765 }
766
767
768 //==============================================================================
769 // Fonction        First click      Result
770 //
771 // vpoint          vertex           AIS_Point=Vertex
772 //                 edge             AIS_Point=Middle of the edge
773 //==============================================================================
774
775 //==============================================================================
776 //function : VPointBuilder
777 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
778 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
779 //==============================================================================
780 #include <TopoDS_Edge.hxx>
781 #include <TopoDS_Vertex.hxx>
782 #include <TopExp.hxx>
783 #include <AIS_Point.hxx>
784 #include <Geom_CartesianPoint.hxx>
785
786 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
787 {
788   // Declarations
789   Standard_Boolean HasArg;
790   TCollection_AsciiString name;
791   Standard_Integer myCurrentIndex;
792
793   // Verification
794   if (argc<2 || argc>5 ) {di<<" Syntaxe error"<<"\n";return 1;}
795   if (argc==5) HasArg=Standard_True;
796   else HasArg=Standard_False;
797
798   name=argv[1];
799   // Fermeture des contextes
800   TheAISContext()->CloseAllContexts();
801
802   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
803   if (HasArg) {
804     Standard_Real thecoord[3];
805     for(Standard_Integer i=0;i<=2;i++)
806       thecoord[i]=Draw::Atof(argv[2+i]);
807     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
808     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
809     GetMapOfAIS().Bind (myAISPoint,name);
810     TheAISContext()->Display(myAISPoint);
811   }
812
813   // Il n'a pas d'arguments
814   else {
815     TheAISContext()->OpenLocalContext();
816     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
817
818     // Active le mode Vertex et Edges
819     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
820     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
821     di<<" Select a vertex or an edge(build the middle)"<<"\n";
822
823     // Boucle d'attente waitpick.
824     Standard_Integer argcc = 5;
825     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
826     const char **argvv = (const char **) buff;
827     while (ViewerMainLoop( argcc, argvv) ) { }
828     // fin de la boucle
829
830     TopoDS_Shape ShapeA;
831     for (TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
832       ShapeA= TheAISContext()->SelectedShape();
833     }
834
835     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
836       // Un vertex a ete selectionne
837       // Fermeture du context local
838       TheAISContext()->CloseLocalContext(myCurrentIndex);
839
840       // Construction du point
841       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) );
842       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
843       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
844       GetMapOfAIS().Bind(myAISPoint,name);
845       TheAISContext()->Display(myAISPoint);
846     }
847     else {
848       // Un Edge a ete selectionne
849       // Fermeture du context local
850       TheAISContext()->CloseLocalContext(myCurrentIndex);
851
852       // Construction du point milieu de l'edge
853       TopoDS_Edge myEdge=TopoDS::Edge(ShapeA);
854       TopoDS_Vertex myVertexA,myVertexB;
855       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
856       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
857       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
858       // M est le milieu de [AB]
859       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
860       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
861       GetMapOfAIS().Bind(myAISPointM,name);
862       TheAISContext()->Display(myAISPointM);
863     }
864
865   }
866   return 0;
867
868 }
869
870 //==============================================================================
871 // Function        1st click   2de click  3de click
872 // vplane          Vertex      Vertex     Vertex
873 //                 Vertex      Edge
874 //                 Edge        Vertex
875 //                 Face
876 // vplanepara      Face        Vertex
877 //                 Vertex      Face
878 // vplaneortho     Face        Edge
879 //                 Edge        Face
880 //==============================================================================
881
882 //==============================================================================
883 //function : VPlaneBuilder
884 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
885 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
886 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
887 //                            [PlaneName] [PointName] [TypeOfSensitivity]
888 //==============================================================================
889
890 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
891                                        Standard_Integer argc,
892                                        const char** argv)
893 {
894   // Declarations
895   Standard_Boolean hasArg;
896   TCollection_AsciiString aName;
897   Standard_Integer aCurrentIndex;
898
899   // Verification
900   if (argc<2 || argc>6 )
901   {
902     std::cout<<" Syntax error\n";
903     return 1;
904   }
905   if (argc == 6 || argc==5 || argc==4)
906     hasArg=Standard_True;
907   else 
908     hasArg=Standard_False;
909
910   aName=argv[1];
911   // Close all contexts
912   TheAISContext()->CloseAllContexts();
913
914   // There are some arguments
915   if (hasArg)
916   {
917     if (!GetMapOfAIS().IsBound2(argv[2] ))
918     {
919       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
920       return 1;
921     }
922     // Get shape from map
923     Handle(AIS_InteractiveObject) aShapeA =
924       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2] ));
925
926     // The first argument is an AIS_Point
927     if (!aShapeA.IsNull() &&
928         aShapeA->Type()==AIS_KOI_Datum &&
929         aShapeA->Signature()==1)
930     {
931         // The second argument must also be an AIS_Point
932         if (argc<5 || !GetMapOfAIS().IsBound2(argv[3]))
933         {
934           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
935           return 1;
936         }
937         // Get shape from map
938         Handle(AIS_InteractiveObject) aShapeB =
939           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
940         // If B is not an AIS_Point
941         if (aShapeB.IsNull() ||
942           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
943         {
944           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
945           return 1;
946         }
947         // The third object is an AIS_Point
948         if (!GetMapOfAIS().IsBound2(argv[4]) ) 
949         {
950           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
951           return 1; 
952         }
953         // Get shape from map
954         Handle(AIS_InteractiveObject) aShapeC =
955           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
956         // If C is not an AIS_Point
957         if (aShapeC.IsNull() ||
958           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
959         {
960           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
961           return 1;
962         }
963
964         // Treatment of objects A, B, C
965         // Downcast an AIS_IO to AIS_Point
966         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
967         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
968         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
969
970         Handle(Geom_CartesianPoint ) aCartPointA = 
971           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
972
973         Handle(Geom_CartesianPoint ) aCartPointB = 
974           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
975
976         Handle(Geom_CartesianPoint ) aCartPointC = 
977           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
978
979         // Verification that the three points are different
980         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
981            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
982            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
983         {
984           // B=A
985           std::cout<<"vplane error: same points"<<"\n";return 1;
986         }
987         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
988            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
989            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
990         {
991           // C=A
992           std::cout<<"vplane error: same points"<<"\n";return 1;
993         }
994         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
995            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
996            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
997         {
998           // C=B
999           std::cout<<"vplane error: same points"<<"\n";return 1;
1000         }
1001
1002         gp_Pnt A = aCartPointA->Pnt();
1003         gp_Pnt B = aCartPointB->Pnt();
1004         gp_Pnt C = aCartPointC->Pnt();
1005
1006         // Construction of AIS_Plane
1007         GC_MakePlane MkPlane (A,B,C);
1008         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1009         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1010         GetMapOfAIS().Bind (anAISPlane,aName );
1011         if (argc == 6)
1012         {
1013           Standard_Integer aType = Draw::Atoi (argv[5]);
1014           if (aType != 0 && aType != 1)
1015           {
1016             std::cout << "vplane error: wrong type of sensitivity!\n"
1017                       << "Should be one of the following values:\n"
1018                       << "0 - Interior\n"
1019                       << "1 - Boundary"
1020                       << std::endl;
1021             return 1;
1022           }
1023           else
1024           {
1025             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1026           }
1027         }
1028         TheAISContext()->Display(anAISPlane);
1029       }
1030
1031       // The first argument is an AIS_Axis
1032       // Creation of a plane orthogonal to the axis through a point
1033     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1034       // The second argument should be an AIS_Point
1035       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3] ) )
1036       {
1037         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1038         return 1;
1039       }
1040       // Get shape from map
1041       Handle(AIS_InteractiveObject) aShapeB =
1042         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1043       // If B is not an AIS_Point
1044       if (aShapeB.IsNull() ||
1045         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1046       {
1047         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1048         return 1;
1049       }
1050
1051       // Treatment of objects A and B
1052       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1053       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1054
1055       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1056       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1057
1058       gp_Ax1 anAxis = aGeomLineA->Position();
1059       Handle(Geom_CartesianPoint) aCartPointB = 
1060         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1061
1062       gp_Dir D =anAxis.Direction();
1063       gp_Pnt B = aCartPointB->Pnt();
1064
1065       // Construction of AIS_Plane
1066       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1067       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1068       GetMapOfAIS().Bind (anAISPlane,aName );
1069       if (argc == 5)
1070       {
1071         Standard_Integer aType = Draw::Atoi (argv[4]);
1072         if (aType != 0 && aType != 1)
1073         {
1074           std::cout << "vplane error: wrong type of sensitivity!\n"
1075                     << "Should be one of the following values:\n"
1076                     << "0 - Interior\n"
1077                     << "1 - Boundary"
1078                     << std::endl;
1079           return 1;
1080         }
1081         else
1082         {
1083           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1084         }
1085       }
1086       TheAISContext()->Display(anAISPlane);
1087
1088     }
1089     // The first argumnet is an AIS_Plane
1090     // Creation of a plane parallel to the plane passing through the point
1091     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1092     {
1093       // The second argument should be an AIS_Point
1094       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3]))
1095       {
1096         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1097         return 1;
1098       }
1099       // Get shape from map
1100       Handle(AIS_InteractiveObject) aShapeB =
1101         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1102       // B should be an AIS_Point
1103       if (aShapeB.IsNull() ||
1104          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1105       {
1106         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1107         return 1;
1108       }
1109
1110       // Treatment of objects A and B
1111       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1112       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1113
1114       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1115       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1116
1117       Handle(Geom_CartesianPoint) aCartPointB = 
1118         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1119       gp_Pnt B= aCartPointB->Pnt();
1120
1121       // Construction of an AIS_Plane
1122       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1123       GetMapOfAIS().Bind (anAISPlane, aName);
1124       if (argc == 5)
1125       {
1126         Standard_Integer aType = Draw::Atoi (argv[4]);
1127         if (aType != 0 && aType != 1)
1128         {
1129           std::cout << "vplane error: wrong type of sensitivity!\n"
1130                     << "Should be one of the following values:\n"
1131                     << "0 - Interior\n"
1132                     << "1 - Boundary"
1133                     << std::endl;
1134           return 1;
1135         }
1136         else
1137         {
1138           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1139         }
1140       }
1141       TheAISContext()->Display(anAISPlane);
1142     }
1143     // Error
1144     else
1145     {
1146       std::cout<<"vplane: error 1st object is not an AIS\n";
1147       return 1;
1148     }
1149   }
1150   // There are no arguments
1151   else 
1152   {
1153     // Function vplane
1154     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1155     if (!strcasecmp(argv[0], "vplane"))
1156     {
1157       TheAISContext()->OpenLocalContext();
1158       aCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1159
1160       // Active modes Vertex, Edge and Face
1161       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1162       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1163       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1164       std::cout<<"Select a vertex, a face or an edge\n";
1165
1166       // Wait for picking
1167       Standard_Integer argcc = 5;
1168       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1169       const char **argvv = (const char **) buff;
1170       while (ViewerMainLoop( argcc, argvv) ) { }
1171       // end of the loop
1172
1173       TopoDS_Shape aShapeA;
1174       for (TheAISContext()->InitSelected();
1175            TheAISContext()->MoreSelected();
1176            TheAISContext()->NextSelected())
1177       {
1178         aShapeA = TheAISContext()->SelectedShape();
1179       }
1180
1181       // aShapeA is a Vertex
1182       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1183       {
1184         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1185         std::cout<<" Select an edge or a different vertex\n";
1186
1187         // Wait for picking
1188         Standard_Integer argccc = 5;
1189         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1190         const char **argvvv = (const char **) bufff;
1191         while (ViewerMainLoop( argccc, argvvv) ) { }
1192         // end of the loop
1193
1194         TopoDS_Shape aShapeB;
1195         for (TheAISContext()->InitSelected();
1196           TheAISContext()->MoreSelected();
1197           TheAISContext()->NextSelected())
1198         {
1199           aShapeB = TheAISContext()->SelectedShape();
1200         }
1201         // aShapeB is a Vertex
1202         if (aShapeB.ShapeType()==TopAbs_VERTEX)
1203         {
1204           // A and B are the same
1205           if (aShapeB.IsSame(aShapeA))
1206           {
1207             std::cout<<" vplane: error, same points selected\n";
1208             return 1;
1209           }
1210           TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1211           std::cout<<" Select a different vertex\n";
1212
1213           // Wait for picking
1214           Standard_Integer argcccc = 5;
1215           const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1216           const char **argvvvv = (const char **) buffff;
1217           while (ViewerMainLoop( argcccc, argvvvv) ) { }
1218           // end of the loop
1219
1220           TopoDS_Shape aShapeC;
1221           for (TheAISContext()->InitSelected();
1222                TheAISContext()->MoreSelected();
1223                TheAISContext()->NextSelected())
1224           {
1225             aShapeC = TheAISContext()->SelectedShape();
1226           }
1227           // aShapeC is the same as A or B
1228           if (aShapeC.IsSame(aShapeA)||aShapeC.IsSame(aShapeB))
1229           {
1230             std::cout<<" vplane: error, same points selected\n";
1231             return 1;
1232           }
1233
1234           // Close the local context
1235           TheAISContext()->CloseLocalContext(aCurrentIndex);
1236
1237           // Construction of plane
1238           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1239           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1240           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1241           GC_MakePlane MkPlane(A, B, C);
1242           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1243           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1244           GetMapOfAIS().Bind (anAISPlane, aName);
1245           TheAISContext()->Display(anAISPlane);
1246         }
1247         // ShapeB is an edge
1248         else
1249         {
1250           // Verify that the vertex is not on the edge ShapeB
1251           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1252           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1253
1254           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1255           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1256           {
1257             // The vertex is on the edge
1258             std::cout<<" vplane: error point is on the edge\n";
1259             return 1;
1260           }
1261           else
1262           {
1263             // Close the local context
1264             TheAISContext()->CloseLocalContext(aCurrentIndex);
1265             // Construction of plane
1266             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1267             TopoDS_Vertex aVBa, aVBb;
1268             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1269             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1270             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1271             GC_MakePlane MkPlane (A, aBa, aBb);
1272             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1273             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1274             GetMapOfAIS().Bind (anAISPlane, aName);
1275             TheAISContext()->Display(anAISPlane);
1276           }
1277         }
1278       }
1279       // aShapeA is an edge
1280       else if (aShapeA.ShapeType()==TopAbs_EDGE)
1281       {
1282         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1283         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1284         std::cout<<" Select a vertex that don't belong to the edge\n";
1285
1286         // Wait for picking
1287         Standard_Integer argccc = 5;
1288         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1289         const char **argvvv = (const char **) bufff;
1290         while (ViewerMainLoop( argccc, argvvv) ) { }
1291         // end of the loop
1292
1293         TopoDS_Shape aShapeB;
1294         for (TheAISContext()->InitSelected();
1295              TheAISContext()->MoreSelected();
1296              TheAISContext()->NextSelected())
1297         {
1298           aShapeB = TheAISContext()->SelectedShape();
1299         }
1300         // aShapeB should be a Vertex
1301         // Check that the vertex aShapeB is not on the edge
1302         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1303         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1304
1305         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1306         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1307         {
1308           // The vertex is on the edge
1309           std::cout<<" vplane: error point is on the edge\n";
1310           return 1;
1311         }
1312         else
1313         {
1314           // Close the local context
1315           TheAISContext()->CloseLocalContext(aCurrentIndex);
1316           // Construction of plane
1317           gp_Pnt B = BRep_Tool::Pnt(aVertB);
1318           TopoDS_Vertex aVAa, aVAb;
1319           TopExp::Vertices(anEdgeA, aVAa, aVAb);
1320           gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1321           gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1322           GC_MakePlane MkPlane (B,Aa,Ab);
1323           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1324           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1325           GetMapOfAIS().Bind (anAISPlane ,aName);
1326           TheAISContext()->Display(anAISPlane);
1327         }
1328       }
1329       // aShapeA is a Face
1330       else
1331       {
1332         // Close the local context: nothing to select
1333         TheAISContext()->CloseLocalContext(aCurrentIndex);
1334         // Construction of plane
1335         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1336         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1337         if (aSurface.GetType()==GeomAbs_Plane)
1338         {
1339           gp_Pln aPlane = aSurface.Plane();
1340           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1341           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1342           GetMapOfAIS().Bind (anAISPlane, aName);
1343           TheAISContext()->Display(anAISPlane);
1344         }
1345         else
1346         {
1347           std::cout<<" vplane: error\n";
1348           return 1;
1349         }
1350       }
1351     }
1352
1353     // Function vPlanePara
1354     // ===================
1355     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1356     else if (!strcasecmp(argv[0], "vplanepara"))
1357     {
1358       TheAISContext()->OpenLocalContext();
1359       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1360
1361       // Activate modes Vertex and Face
1362       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1363       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1364       std::cout<<" Select a vertex or a face\n";
1365
1366       // Wait for picking
1367       Standard_Integer argcc = 5;
1368       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1369       const char **argvv = (const char **) buff;
1370       while (ViewerMainLoop( argcc, argvv) ) { }
1371       // end of the loop
1372
1373       TopoDS_Shape aShapeA;
1374       for (TheAISContext()->InitSelected();
1375            TheAISContext()->MoreSelected();
1376            TheAISContext()->NextSelected())
1377       {
1378         aShapeA = TheAISContext()->SelectedShape();
1379       }
1380
1381       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1382       {
1383         // aShapeA is a vertex
1384         // Deactivate the mode Vertex
1385         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1));
1386         std::cout<<" Select a face\n";
1387
1388         // Wait for picking
1389         Standard_Integer argccc = 5;
1390         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1391         const char **argvvv = (const char **) bufff;
1392         while (ViewerMainLoop( argccc, argvvv) ) { }
1393         // end of the loop
1394
1395         TopoDS_Shape aShapeB;
1396         for (TheAISContext()->InitSelected();
1397              TheAISContext()->MoreSelected();
1398              TheAISContext()->NextSelected())
1399         {
1400           // A vertex ShapeA can be on Face ShapeB
1401           aShapeB = TheAISContext()->SelectedShape();
1402         }
1403
1404         // Close the local context
1405         TheAISContext()->CloseLocalContext(aCurrentIndex);
1406
1407         // Construction of plane
1408         gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1409
1410         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1411         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1412         if (aSurface.GetType()==GeomAbs_Plane )
1413         {
1414           gp_Pln aPlane = aSurface.Plane();
1415           // Construct a plane parallel to aGeomPlane through A
1416           aPlane.SetLocation(A);
1417           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1418           Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1419           GetMapOfAIS().Bind (aAISPlane ,aName);
1420           TheAISContext()->Display(aAISPlane);
1421         }
1422         else
1423         {
1424           std::cout<<" vplanepara: error\n";
1425           return 1;
1426         }
1427       }
1428       else
1429       {
1430         // ShapeA is a Face
1431         // Deactive the mode Face
1432         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1433         std::cout<<" Select a vertex\n";
1434
1435         // Wait for picking
1436         Standard_Integer argccc = 5;
1437         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1438         const char **argvvv = (const char **) bufff;
1439         while (ViewerMainLoop( argccc, argvvv) ) { }
1440         // end of the loop
1441
1442         TopoDS_Shape aShapeB;
1443         for (TheAISContext()->InitSelected();
1444              TheAISContext()->MoreSelected();
1445              TheAISContext()->NextSelected())
1446         {
1447           // A vertex ShapeB can be on Face ShapeA
1448           aShapeB = TheAISContext()->SelectedShape();
1449         }
1450         // Close the local context
1451         TheAISContext()->CloseLocalContext(aCurrentIndex);
1452
1453         // Construction of plane
1454         gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1455
1456         TopoDS_Face aFace=TopoDS::Face(aShapeA);
1457         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1458         if (aSurface.GetType()==GeomAbs_Plane )
1459         {
1460           gp_Pln aPlane = aSurface.Plane();
1461           aPlane.SetLocation(B);
1462           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1463           // Construct a plane parallel to aGeomPlane through B
1464           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, B);
1465           GetMapOfAIS().Bind (anAISPlane, aName);
1466           TheAISContext()->Display(anAISPlane);
1467         }
1468         else
1469         {
1470           std::cout<<" vplanepara: error"<<"\n";return 1;
1471         }
1472       }
1473     }
1474
1475     // Function vplaneortho
1476     // ====================
1477     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1478     else
1479     {
1480       TheAISContext()->OpenLocalContext();
1481       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1482
1483       // Activate the modes Edge and Face
1484       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1485       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1486       std::cout<<" Select a face and an edge coplanar\n";
1487
1488       // Wait for picking
1489       Standard_Integer argcc = 5;
1490       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1491       const char **argvv = (const char **) buff;
1492       while (ViewerMainLoop( argcc, argvv) ) { }
1493       // end of the loop
1494
1495       TopoDS_Shape aShapeA;
1496       for (TheAISContext()->InitSelected();
1497            TheAISContext()->MoreSelected();
1498            TheAISContext()->NextSelected())
1499       {
1500         aShapeA = TheAISContext()->SelectedShape();
1501       }
1502
1503       if (aShapeA.ShapeType()==TopAbs_EDGE )
1504       {
1505         // ShapeA is an edge, deactivate the mode Edge...
1506         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1507         std::cout<<" Select a face\n";
1508
1509         // Wait for picking
1510         Standard_Integer argccc = 5;
1511         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1512         const char **argvvv = (const char **) bufff;
1513         while (ViewerMainLoop( argccc, argvvv) ) { }
1514         // end of the loop
1515
1516         TopoDS_Shape aShapeB;
1517         for (TheAISContext()->InitSelected();
1518              TheAISContext()->MoreSelected();
1519              TheAISContext()->NextSelected())
1520         {
1521           // Edge ShapeA can be on Face ShapeB
1522           aShapeB = TheAISContext()->SelectedShape();
1523         }
1524
1525         // Close the local context
1526         TheAISContext()->CloseLocalContext(aCurrentIndex);
1527
1528         // Construction of plane
1529         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1530         TopoDS_Vertex aVAa, aVAb;
1531         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1532         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1533         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1534         gp_Vec ab (Aa,Ab);
1535
1536         gp_Dir Dab (ab);
1537         // Creation of rotation axis
1538         gp_Ax1 aRotAxis (Aa,Dab);
1539
1540         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1541         // The edge must be parallel to the face
1542         BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1543         BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1544         // Compare to heights
1545         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1546             >Precision::Confusion())
1547         {
1548           // the edge is not parallel to the face
1549           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1550           return 1;
1551         }
1552         // the edge is OK
1553         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1554         if (aSurface.GetType()==GeomAbs_Plane)
1555         {
1556           gp_Pln aPlane = aSurface.Plane();
1557           // It rotates a half turn round the axis of rotation
1558           aPlane.Rotate(aRotAxis , M_PI/2);
1559
1560           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1561           // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1562           gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1563           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1564           GetMapOfAIS().Bind (anAISPlane, aName);
1565           TheAISContext()->Display(anAISPlane);
1566         }
1567         else
1568         {
1569           std::cout<<" vplaneortho: error\n";
1570           return 1;
1571         }
1572       }
1573       else
1574       {
1575         // ShapeA is a Face, deactive the mode Face.
1576         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1577         std::cout<<" Select an edge\n";
1578
1579         // Wait for picking
1580         Standard_Integer argccc = 5;
1581         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1582         const char **argvvv = (const char **) bufff;
1583         while (ViewerMainLoop( argccc, argvvv) ) { }
1584         // end of the loop
1585
1586         TopoDS_Shape aShapeB;
1587         for (TheAISContext()->InitSelected();
1588              TheAISContext()->MoreSelected();
1589              TheAISContext()->NextSelected())
1590         {
1591           // Edge ShapeB can be on Face ShapeA
1592           aShapeB = TheAISContext()->SelectedShape();
1593         }
1594         // Close the local context
1595         TheAISContext()->CloseLocalContext(aCurrentIndex);
1596
1597         // Construction of plane
1598         TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1599         TopoDS_Vertex aVBa, aVBb;
1600         TopExp::Vertices(anEdgeB, aVBa, aVBb);
1601         gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1602         gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1603         gp_Vec ab (aBa,aBb);
1604         gp_Dir Dab (ab);
1605         // Creation of rotation axe
1606         gp_Ax1 aRotAxis (aBa,Dab);
1607
1608         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1609         // The edge must be parallel to the face
1610         BRepExtrema_ExtPF aHeightA (aVBa, aFace);
1611         BRepExtrema_ExtPF aHeightB (aVBb, aFace);
1612         // Comparing the two heights
1613         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1614             >Precision::Confusion())
1615         {
1616           // the edge is not parallel to the face
1617           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1618           return 1;
1619         }
1620         // The edge is OK
1621         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1622         if (aSurface.GetType()==GeomAbs_Plane)
1623         {
1624           gp_Pln aPlane = aSurface.Plane();
1625           // It rotates a half turn round the axis of rotation
1626           aPlane.Rotate(aRotAxis , M_PI/2);
1627           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1628           // constructed aGeomPlane parallel to a plane containing the edge theGeomPlane (center mid-edge)
1629           gp_Pnt aMiddle ((aBa.X()+aBb.X() )/2 , (aBa.Y()+aBb.Y() )/2 , (aBa.Z()+aBb.Z() )/2 );
1630           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1631           GetMapOfAIS().Bind (anAISPlane ,aName);
1632           TheAISContext()->Display(anAISPlane);
1633         }
1634         else
1635         {
1636           std::cout<<" vplaneortho: error\n";
1637           return 1;
1638         }
1639       }
1640     }
1641   }
1642   return 0;
1643 }
1644
1645 //===============================================================================================
1646 //function : VChangePlane
1647 //purpose  :
1648 //===============================================================================================
1649 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1650 {
1651   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1652   if (aContextAIS.IsNull())
1653   {
1654     std::cout << theArgVec[0] << "AIS context is not available.\n";
1655     return 1;
1656   }
1657
1658   if (theArgsNb < 3 || theArgsNb > 11)
1659   {
1660     std::cerr << theArgVec[0] 
1661               << ": incorrect number of command arguments.\n"
1662               << "Type help for more information.\n";
1663     return 1;
1664   }
1665
1666   TCollection_AsciiString aName (theArgVec[1]);
1667
1668   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1669     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1670     : NULL;
1671
1672   if ( aPlane.IsNull() )
1673   {
1674     std::cout << theArgVec[0] 
1675               << ": there is no interactive plane with the given name."
1676               << "Type help for more information.\n";
1677     return 1;
1678   }
1679
1680   Standard_Real aCenterX = aPlane->Center().X();
1681   Standard_Real aCenterY = aPlane->Center().Y();
1682   Standard_Real aCenterZ = aPlane->Center().Z();
1683
1684   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1685   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1686   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1687
1688   Standard_Real aSizeX = 0.0;
1689   Standard_Real aSizeY = 0.0;
1690   aPlane->Size (aSizeX, aSizeY);
1691   Standard_Boolean isUpdate = Standard_True;
1692
1693   TCollection_AsciiString aPName, aPValue;
1694   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1695   {
1696     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1697     TCollection_AsciiString anArgCase = anArg;
1698     anArgCase.UpperCase();
1699     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1700     {
1701       aPName.UpperCase();
1702       if (aPName.IsEqual ("X"))
1703       {
1704         aCenterX = aPValue.RealValue();
1705       }
1706       else if (aPName.IsEqual ("Y"))
1707       {
1708         aCenterY = aPValue.RealValue();
1709       }
1710       else if (aPName.IsEqual ("Z"))
1711       {
1712         aCenterZ = aPValue.RealValue();
1713       }
1714       else if (aPName.IsEqual ("DX"))
1715       {
1716         aDirX = aPValue.RealValue();
1717       }
1718       else if (aPName.IsEqual ("DY"))
1719       {
1720         aDirY = aPValue.RealValue();
1721       }
1722       else if (aPName.IsEqual ("DZ"))
1723       {
1724         aDirZ = aPValue.RealValue();
1725       }
1726       else if (aPName.IsEqual ("SX"))
1727       {
1728         aSizeX = aPValue.RealValue();
1729       }
1730       else if (aPName.IsEqual ("SY"))
1731       {
1732         aSizeY = aPValue.RealValue();
1733       }
1734     }
1735     else if (anArg.IsEqual ("NOUPDATE"))
1736     {
1737       isUpdate = Standard_False;
1738     }
1739   }
1740
1741   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1742   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1743   aPlane->SetCenter (aCenterPnt);
1744   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1745   aPlane->SetSize (aSizeX, aSizeY);
1746
1747   aContextAIS->Update (aPlane, isUpdate);
1748
1749   return 0;
1750 }
1751
1752 //==============================================================================
1753 // Fonction  vline
1754 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1755 //==============================================================================
1756
1757 //==============================================================================
1758 //function : VLineBuilder
1759 //purpose  : Build an AIS_Line
1760 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1761 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1762 //==============================================================================
1763 #include <Geom_CartesianPoint.hxx>
1764 #include <AIS_Line.hxx>
1765
1766
1767 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1768 {
1769   Standard_Integer myCurrentIndex;
1770   // Verifications
1771   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct "<<"\n";return 1; }
1772   // Fermeture des contextes
1773   TheAISContext()->CloseAllContexts();
1774
1775   // On recupere les parametres
1776   Handle(AIS_InteractiveObject) theShapeA;
1777   Handle(AIS_InteractiveObject) theShapeB;
1778
1779   // Parametres: AIS_Point AIS_Point
1780   // ===============================
1781   if (argc==4) {
1782     theShapeA=
1783       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
1784     // On verifie que c'est bien une AIS_Point
1785     if (!theShapeA.IsNull() &&
1786       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1787         // on recupere le deuxieme AIS_Point
1788         theShapeB=
1789           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1790         if (theShapeA.IsNull() ||
1791           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1792         {
1793           di <<"vline error: wrong type of 2de argument."<<"\n";
1794           return 1;
1795         }
1796       }
1797     else {di <<"vline error: wrong type of 1st argument."<<"\n";return 1; }
1798     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1799     Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA;
1800     Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB;
1801
1802     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1803     Handle(Geom_CartesianPoint ) myCartPointA= *((Handle(Geom_CartesianPoint)*)&  myGeomPointBA);
1804     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1805
1806     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1807     Handle(Geom_CartesianPoint ) myCartPointB= *((Handle(Geom_CartesianPoint)*)&  myGeomPointB);
1808     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1809
1810     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1811       // B=A
1812       di<<"vline error: same points"<<"\n";return 1;
1813     }
1814     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1815     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1816     GetMapOfAIS().Bind(theAISLine,argv[1] );
1817     TheAISContext()->Display(theAISLine );
1818
1819   }
1820
1821   // Parametres 6 Reals
1822   // ==================
1823
1824   else if (argc==8) {
1825     // On verifie que les deux points ne sont pas confondus
1826
1827     Standard_Real coord[6];
1828     for(Standard_Integer i=0;i<=2;i++){
1829       coord[i]=Draw::Atof(argv[2+i]);
1830       coord[i+3]=Draw::Atof(argv[5+i]);
1831     }
1832
1833     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1834     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1835
1836     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1837     GetMapOfAIS().Bind(theAISLine,argv[1] );
1838     TheAISContext()->Display(theAISLine );
1839
1840   }
1841
1842   // Pas de parametres: Selection dans le viewer.
1843   // ============================================
1844
1845   else {
1846     TheAISContext()->OpenLocalContext();
1847     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1848
1849     // Active le mode Vertex.
1850     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1851     di<<" Select a vertex "<<"\n";
1852
1853     // Boucle d'attente waitpick.
1854     Standard_Integer argcc = 5;
1855     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1856     const char **argvv = (const char **) buff;
1857     while (ViewerMainLoop( argcc, argvv) ) { }
1858     // fin de la boucle
1859
1860     TopoDS_Shape ShapeA;
1861     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1862       ShapeA = TheAISContext()->SelectedShape();
1863     }
1864
1865     // ShapeA est un Vertex
1866     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
1867
1868       di<<" Select a different vertex."<<"\n";
1869
1870       TopoDS_Shape ShapeB;
1871       do {
1872
1873         // Boucle d'attente waitpick.
1874         Standard_Integer argccc = 5;
1875         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1876         const char **argvvv = (const char **) bufff;
1877         while (ViewerMainLoop( argccc, argvvv) ) { }
1878         // fin de la boucle
1879
1880         for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1881           ShapeB = TheAISContext()->SelectedShape();
1882         }
1883
1884
1885       } while(ShapeB.IsSame(ShapeA) );
1886
1887       // Fermeture du context local
1888       TheAISContext()->CloseLocalContext(myCurrentIndex);
1889
1890       // Construction de la line
1891       gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
1892       gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
1893
1894       Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1895       Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1896
1897       Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1898       GetMapOfAIS().Bind(theAISLine,argv[1] );
1899       TheAISContext()->Display(theAISLine );
1900
1901     }
1902     else  {
1903       di<<"vline error."<<"\n";
1904     }
1905
1906   }
1907
1908   return 0;
1909 }
1910
1911 //==============================================================================
1912 // class   : FilledCircle
1913 // purpose : creates filled circle based on AIS_InteractiveObject 
1914 //           and Geom_Circle.
1915 //           This class is used to check method Matches() of class 
1916 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1917 //           because none of AIS classes provides creation of 
1918 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1919 //           (look method ComputeSelection() )
1920 //============================================================================== 
1921
1922 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1923 {
1924   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
1925   gp_Circ aCirc(anAxes, theRadius);
1926   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
1927   return aCircle;
1928 }
1929
1930 DEFINE_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1931
1932 class FilledCircle : public AIS_InteractiveObject 
1933 {
1934 public:
1935     // CASCADE RTTI
1936     DEFINE_STANDARD_RTTI(FilledCircle); 
1937
1938     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1939     FilledCircle(Handle(Geom_Circle) theCircle);
1940
1941 private:
1942     TopoDS_Face ComputeFace();
1943
1944     // Virtual methods implementation
1945     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1946                   const Handle(Prs3d_Presentation)& thePresentation,
1947                   const Standard_Integer theMode);
1948
1949     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1950                            const Standard_Integer theMode);
1951
1952 protected:
1953     Handle(Geom_Circle) myCircle;
1954     Standard_Boolean myFilledStatus;
1955
1956 }; 
1957
1958 IMPLEMENT_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1959 IMPLEMENT_STANDARD_RTTIEXT(FilledCircle, AIS_InteractiveObject)
1960
1961 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1962 {
1963   myCircle = CreateCircle(theCenter, theRadius);
1964   myFilledStatus = Standard_True;
1965 }
1966
1967 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1968 {
1969   myCircle = theCircle;
1970   myFilledStatus = Standard_True;
1971 }
1972
1973 TopoDS_Face FilledCircle::ComputeFace() 
1974 {
1975   // Create edge from myCircle 
1976   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1977   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1978
1979   // Create wire from anEdge 
1980   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1981   TopoDS_Wire aWire = aWireMaker.Wire();
1982
1983   // Create face from aWire
1984   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1985   TopoDS_Face aFace = aFaceMaker.Face();
1986
1987   return aFace;
1988 }
1989
1990 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
1991                            const Handle(Prs3d_Presentation) &thePresentation, 
1992                            const Standard_Integer theMode) 
1993 {
1994   thePresentation->Clear();
1995
1996   TopoDS_Face aFace = ComputeFace();
1997
1998   if (aFace.IsNull()) return;
1999   if (theMode != 0) return;
2000
2001   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
2002 }
2003
2004 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2005                                     const Standard_Integer /*theMode*/)
2006 {
2007   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2008   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2009       myCircle, myFilledStatus);
2010   theSelection->Add(aSensitiveCircle);
2011 }
2012
2013 //==============================================================================
2014 // Fonction  vcircle
2015 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2016 //==============================================================================
2017
2018 //==============================================================================
2019 //function : VCircleBuilder
2020 //purpose  : Build an AIS_Circle
2021 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2022 //                              PointName PointName PointName IsFilled
2023 //==============================================================================
2024
2025 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2026                     TCollection_AsciiString theName, 
2027                     Standard_Boolean isFilled) 
2028 {
2029   Handle(AIS_InteractiveObject) aCircle;
2030   if (isFilled) 
2031   {
2032     aCircle = new FilledCircle(theGeomCircle);
2033   }
2034   else
2035   {
2036     aCircle = new AIS_Circle(theGeomCircle);
2037     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2038   }
2039
2040   // Check if there is an object with given name
2041   // and remove it from context
2042   if (GetMapOfAIS().IsBound2(theName)) 
2043   {
2044     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
2045     Handle(AIS_InteractiveObject) anInterObj = 
2046          Handle(AIS_InteractiveObject)::DownCast(anObj);
2047     TheAISContext()->Remove(anInterObj, Standard_False);
2048     GetMapOfAIS().UnBind2(theName);
2049    }
2050
2051    // Bind the circle to its name
2052    GetMapOfAIS().Bind(aCircle, theName);
2053
2054    // Display the circle
2055    TheAISContext()->Display(aCircle);
2056   
2057 }
2058
2059 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2060 {
2061   Standard_Integer myCurrentIndex;
2062   // Verification of the arguments
2063   if (argc>6 || argc<2) 
2064   { 
2065     std::cout << "vcircle error: expect 4 arguments.\n"; 
2066     return 1; // TCL_ERROR 
2067   }
2068   TheAISContext()->CloseAllContexts();
2069
2070   // There are all arguments
2071   if (argc == 6) 
2072   {
2073     // Get arguments
2074     TCollection_AsciiString aName(argv[1]);
2075     Standard_Boolean isFilled = (Standard_Boolean)Draw::Atoi(argv[5]);
2076
2077     Handle(AIS_InteractiveObject) theShapeA;
2078     Handle(AIS_InteractiveObject) theShapeB;
2079
2080     theShapeA =
2081       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2082     theShapeB =
2083       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2084
2085
2086     // Arguments: AIS_Point AIS_Point AIS_Point
2087     // ========================================
2088     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2089       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2090     {
2091       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2092       {
2093         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2094         return 1; // TCL_ERROR 
2095       }
2096       // The third object must be a point
2097       Handle(AIS_InteractiveObject) theShapeC =
2098         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2099       if (theShapeC.IsNull() ||
2100         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2101       {
2102         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2103         return 1; // TCL_ERROR 
2104       }
2105         // tag
2106         // Verify that the three points are different
2107         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2108         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2109         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2110         
2111         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2112         Handle(Geom_CartesianPoint) myCartPointA = 
2113           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2114
2115         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2116         Handle(Geom_CartesianPoint) myCartPointB =
2117           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2118
2119         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2120         Handle(Geom_CartesianPoint) myCartPointC =
2121           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2122
2123         // Test A=B
2124         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2125             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2126             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2127         {
2128           std::cout << "vcircle error: Same points.\n"; 
2129           return 1; // TCL_ERROR 
2130         }
2131         // Test A=C
2132         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2133             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2134             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2135         {
2136           std::cout << "vcircle error: Same points.\n"; 
2137           return 1; // TCL_ERROR 
2138         }
2139         // Test B=C
2140         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2141             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2142             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2143         {
2144           std::cout << "vcircle error: Same points.\n"; 
2145           return 1;// TCL_ERROR 
2146         }
2147         // Construction of the circle
2148         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2149           myCartPointB->Pnt(), myCartPointC->Pnt() );
2150         Handle (Geom_Circle) theGeomCircle;
2151         try 
2152         {
2153           theGeomCircle = Cir.Value();
2154         }
2155         catch (StdFail_NotDone)
2156         {
2157           std::cout << "vcircle error: can't create circle\n";
2158           return -1; // TCL_ERROR
2159         }
2160         
2161         DisplayCircle(theGeomCircle, aName, isFilled);
2162     }
2163
2164     // Arguments: AIS_Plane AIS_Point Real
2165     // ===================================
2166     else if (theShapeA->Type() == AIS_KOI_Datum && 
2167       theShapeA->Signature() == 7 ) 
2168     {
2169       if (theShapeB->Type() != AIS_KOI_Datum || 
2170         theShapeB->Signature() != 1 ) 
2171       {
2172         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2173         return 1; // TCL_ERROR 
2174       }
2175       // Check that the radius is >= 0
2176       if (Draw::Atof(argv[4]) <= 0 ) 
2177       {
2178         std::cout << "vcircle error: the radius must be >=0.\n"; 
2179         return 1; // TCL_ERROR 
2180       }
2181
2182       // Recover the normal to the plane
2183       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2184       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2185
2186       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2187       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2188       Handle(Geom_CartesianPoint) myCartPointB = 
2189         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2190
2191       gp_Pln mygpPlane = myGeomPlane->Pln();
2192       gp_Ax1 thegpAxe = mygpPlane.Axis();
2193       gp_Dir theDir = thegpAxe.Direction();
2194       gp_Pnt theCenter = myCartPointB->Pnt();
2195       Standard_Real TheR = Draw::Atof(argv[4]);
2196       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2197       Handle (Geom_Circle) theGeomCircle;
2198       try 
2199       {
2200         theGeomCircle = Cir.Value();
2201       }
2202       catch (StdFail_NotDone)
2203       {
2204         std::cout << "vcircle error: can't create circle\n";
2205         return -1; // TCL_ERROR
2206       }
2207
2208       DisplayCircle(theGeomCircle, aName, isFilled);
2209
2210     }
2211
2212     // Error
2213     else
2214     {
2215       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2216       return 1; // TCL_ERROR 
2217     }
2218
2219   }
2220   // No arguments: selection in the viewer
2221   // =========================================
2222   else 
2223   {
2224     // Get the name of the circle 
2225     TCollection_AsciiString aName(argv[1]);
2226
2227     TheAISContext()->OpenLocalContext();
2228     myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
2229
2230     // Activate selection mode for vertices and faces
2231     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2232     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2233     std::cout << " Select a vertex or a face\n";
2234
2235     // Wait for picking
2236     Standard_Integer argcc = 5;
2237     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2238     const char **argvv = (const char **) buff;
2239     while (ViewerMainLoop( argcc, argvv) ) { }
2240     // end of the loop
2241
2242     TopoDS_Shape ShapeA;
2243     for(TheAISContext()->InitSelected(); 
2244       TheAISContext()->MoreSelected(); 
2245       TheAISContext()->NextSelected() ) 
2246     {
2247       ShapeA = TheAISContext()->SelectedShape();
2248     }
2249
2250     // ShapeA is a Vertex
2251     if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
2252     {
2253       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2254       std::cout << " Select a different vertex\n";
2255
2256       TopoDS_Shape ShapeB;
2257       do 
2258       {
2259         // Wait for picking
2260         Standard_Integer argccc = 5;
2261         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2262         const char **argvvv = (const char **) bufff;
2263         while (ViewerMainLoop( argccc, argvvv) ) { }
2264         // end of the loop
2265
2266         for(TheAISContext()->InitSelected(); 
2267           TheAISContext()->MoreSelected(); 
2268           TheAISContext()->NextSelected() ) 
2269         {
2270           ShapeB = TheAISContext()->SelectedShape();
2271         }
2272       } while(ShapeB.IsSame(ShapeA) );
2273
2274       // Selection of ShapeC
2275       std::cout << " Select the last vertex\n";
2276       TopoDS_Shape ShapeC;
2277       do 
2278       {
2279         // Wait for picking
2280         Standard_Integer argcccc = 5;
2281         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2282         const char **argvvvv = (const char **) buffff;
2283         while (ViewerMainLoop( argcccc, argvvvv) ) { }
2284         // end of the loop
2285
2286         for(TheAISContext()->InitSelected(); 
2287           TheAISContext()->MoreSelected(); 
2288           TheAISContext()->NextSelected() ) 
2289         {
2290           ShapeC = TheAISContext()->SelectedShape();
2291         }
2292       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
2293       
2294       // Get isFilled
2295       Standard_Boolean isFilled;
2296       std::cout << "Enter filled status (0 or 1)\n";
2297       cin >> isFilled;
2298
2299       // Close the local context
2300       TheAISContext()->CloseLocalContext(myCurrentIndex);
2301
2302       // Construction of the circle
2303       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
2304       gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2305       gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
2306
2307       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2308       Handle (Geom_Circle) theGeomCircle;
2309       try 
2310       {
2311         theGeomCircle = Cir.Value();
2312       }
2313       catch (StdFail_NotDone)
2314       {
2315         std::cout << "vcircle error: can't create circle\n";
2316         return -1; // TCL_ERROR
2317       }
2318
2319       DisplayCircle(theGeomCircle, aName, isFilled);
2320
2321     }
2322     // Shape is a face
2323     else
2324     {
2325       std::cout << " Select a vertex (in your face)\n";
2326       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2327
2328       TopoDS_Shape ShapeB;
2329       // Wait for picking
2330       Standard_Integer argccc = 5;
2331       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2332       const char **argvvv = (const char **) bufff;
2333       while (ViewerMainLoop( argccc, argvvv) ) { }
2334       // end of the loop
2335
2336       for(TheAISContext()->InitSelected(); 
2337         TheAISContext()->MoreSelected(); 
2338         TheAISContext()->NextSelected() ) 
2339       {
2340         ShapeB = TheAISContext()->SelectedShape();
2341       }
2342
2343       // Recover the radius 
2344       Standard_Real theRad;
2345       do 
2346       {
2347         std::cout << " Enter the value of the radius:\n";
2348         cin >> theRad;
2349       } while (theRad <= 0);
2350       
2351       // Get filled status
2352       Standard_Boolean isFilled;
2353       std::cout << "Enter filled status (0 or 1)\n";
2354       cin >> isFilled;
2355
2356       // Close the local context
2357       TheAISContext()->CloseLocalContext(myCurrentIndex);
2358       // Construction of the circle
2359
2360       // Recover the normal to the plane. tag
2361       TopoDS_Face myFace = TopoDS::Face(ShapeA);
2362       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2363       gp_Pln myPlane = mySurface.Plane();
2364       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2365       gp_Pln mygpPlane = theGeomPlane->Pln();
2366       gp_Ax1 thegpAxe = mygpPlane.Axis();
2367       gp_Dir theDir = thegpAxe.Direction();
2368
2369       // Recover the center
2370       gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2371
2372       // Construct the circle
2373       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2374       Handle (Geom_Circle) theGeomCircle;
2375       try 
2376       {
2377         theGeomCircle = Cir.Value();
2378       }
2379       catch (StdFail_NotDone)
2380       {
2381         std::cout << "vcircle error: can't create circle\n";
2382         return -1; // TCL_ERROR
2383       }
2384
2385       DisplayCircle(theGeomCircle, aName, isFilled);
2386       
2387     }
2388
2389   }
2390
2391   return 0;
2392 }
2393
2394 //=======================================================================
2395 //function : VDrawText
2396 //purpose  :
2397 //=======================================================================
2398 static int VDrawText (Draw_Interpretor& theDI,
2399                       Standard_Integer  theArgsNb,
2400                       const char**      theArgVec)
2401 {
2402   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2403   if (theArgsNb < 3)
2404   {
2405     std::cout << "Error: wrong number of arguments! See usage:\n";
2406     theDI.PrintHelp (theArgVec[0]);
2407     return 1;
2408   }
2409   else if (aContext.IsNull())
2410   {
2411     std::cout << "Error: no active view!\n";
2412     return 1;
2413   }
2414
2415   Standard_Integer           anArgIt = 1;
2416   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2417   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2418   Handle(AIS_TextLabel)      aTextPrs;
2419   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2420
2421   if (GetMapOfAIS().IsBound2 (aName))
2422   {
2423     aTextPrs  = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2424   }
2425   else
2426   {
2427     aTextPrs = new AIS_TextLabel();
2428     aTextPrs->SetFont ("Courier");
2429   }
2430
2431   aTextPrs->SetText (aText);
2432
2433   for (; anArgIt < theArgsNb; ++anArgIt)
2434   {
2435     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2436     aParam.LowerCase();
2437
2438     if (anAutoUpdater.parseRedrawMode (aParam))
2439     {
2440       continue;
2441     }
2442     else if (aParam == "-pos"
2443           || aParam == "-position")
2444     {
2445       if (anArgIt + 3 >= theArgsNb)
2446       {
2447         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2448         return 1;
2449       }
2450
2451       gp_Pnt aPos;
2452       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2453       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2454       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2455       aTextPrs->SetPosition (aPos);
2456     }
2457     else if (aParam == "-color")
2458     {
2459       if (anArgIt + 1 >= theArgsNb)
2460       {
2461         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2462         return 1;
2463       }
2464
2465       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2466       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2467       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2468       {
2469         anArgIt += 1;
2470         aTextPrs->SetColor (aNameOfColor);
2471         continue;
2472       }
2473       else if (anArgIt + 3 >= theArgsNb)
2474       {
2475         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2476         return 1;
2477       }
2478
2479       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2480       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2481       if (!aColor.IsRealValue()
2482        || !aGreen.IsRealValue()
2483        || !aBlue.IsRealValue())
2484       {
2485         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2486         return 1;
2487       }
2488
2489       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2490                                    aGreen.RealValue(),
2491                                    aBlue.RealValue());
2492
2493       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2494       anArgIt += 3;
2495     }
2496     else if (aParam == "-halign")
2497     {
2498       if (++anArgIt >= theArgsNb)
2499       {
2500         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2501         return 1;
2502       }
2503
2504       TCollection_AsciiString aType (theArgVec[anArgIt]);
2505       aType.LowerCase();
2506       if (aType == "left")
2507       {
2508         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2509       }
2510       else if (aType == "center")
2511       {
2512         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2513       }
2514       else if (aType == "right")
2515       {
2516         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2517       }
2518       else
2519       {
2520         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2521         return 1;
2522       }
2523     }
2524     else if (aParam == "-valign")
2525     {
2526       if (++anArgIt >= theArgsNb)
2527       {
2528         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2529         return 1;
2530       }
2531
2532       TCollection_AsciiString aType (theArgVec[anArgIt]);
2533       aType.LowerCase();
2534       if (aType == "top")
2535       {
2536         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2537       }
2538       else if (aType == "center")
2539       {
2540         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2541       }
2542       else if (aType == "bottom")
2543       {
2544         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2545       }
2546       else
2547       {
2548         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2549         return 1;
2550       }
2551     }
2552     else if (aParam == "-angle")
2553     {
2554       if (++anArgIt >= theArgsNb)
2555       {
2556         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2557         return 1;
2558       }
2559
2560       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2561     }
2562     else if (aParam == "-zoom")
2563     {
2564       if (++anArgIt >= theArgsNb)
2565       {
2566         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2567         return 1;
2568       }
2569
2570       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2571     }
2572     else if (aParam == "-height")
2573     {
2574       if (++anArgIt >= theArgsNb)
2575       {
2576         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2577         return 1;
2578       }
2579
2580       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2581     }
2582     else if (aParam == "-aspect")
2583     {
2584       if (++anArgIt >= theArgsNb)
2585       {
2586         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2587         return 1;
2588       }
2589
2590       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2591       anOption.LowerCase();
2592       if (anOption.IsEqual ("regular"))
2593       {
2594         aTextPrs->SetFontAspect (Font_FA_Regular);
2595       }
2596       else if (anOption.IsEqual ("bold"))
2597       {
2598         aTextPrs->SetFontAspect (Font_FA_Bold);
2599       }
2600       else if (anOption.IsEqual ("italic"))
2601       {
2602         aTextPrs->SetFontAspect (Font_FA_Italic);
2603       }
2604       else if (anOption.IsEqual ("bolditalic"))
2605       {
2606         aTextPrs->SetFontAspect (Font_FA_BoldItalic);
2607       }
2608     }
2609     else if (aParam == "-font")
2610     {
2611       if (++anArgIt >= theArgsNb)
2612       {
2613         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2614         return 1;
2615       }
2616
2617       aTextPrs->SetFont (theArgVec[anArgIt]);
2618     }
2619     else
2620     {
2621       std::cout << "Error: unknown argument '" << aParam << "'\n";
2622       return 1;
2623     }
2624   }
2625
2626   ViewerTest::Display (aName, aTextPrs, Standard_False);
2627   return 0;
2628 }
2629
2630 #include <math.h>
2631 #include <gp_Pnt.hxx>
2632 #include <Graphic3d_ArrayOfPoints.hxx>
2633 #include <Graphic3d_ArrayOfPrimitives.hxx>
2634 #include <Graphic3d_ArrayOfTriangles.hxx>
2635 #include <Poly_Array1OfTriangle.hxx>
2636 #include <Poly_Triangle.hxx>
2637 #include <Poly_Triangulation.hxx>
2638 #include <TColgp_Array1OfPnt.hxx>
2639 #include <TShort_Array1OfShortReal.hxx>
2640 #include <TShort_HArray1OfShortReal.hxx>
2641
2642 #include <AIS_Triangulation.hxx>
2643 #include <StdPrs_ToolShadedShape.hxx>
2644 #include <Poly_Connect.hxx>
2645 #include <TColgp_Array1OfDir.hxx>
2646 #include <Graphic3d_GraphicDriver.hxx>
2647
2648 #include <TColStd_Array1OfInteger.hxx>
2649 #include <TColStd_HArray1OfInteger.hxx>
2650 #include <Prs3d_ShadingAspect.hxx>
2651 #include <Graphic3d_MaterialAspect.hxx>
2652 #include <Graphic3d_AspectFillArea3d.hxx>
2653
2654 #include <BRepPrimAPI_MakeCylinder.hxx>
2655 #include <TopoDS_Shape.hxx>
2656 #include <TopExp_Explorer.hxx>
2657 #include <TopAbs.hxx>
2658 #include <StdSelect_ShapeTypeFilter.hxx>
2659
2660
2661 //===============================================================================================
2662 //function : CalculationOfSphere
2663 //author   : psn
2664 //purpose  : Create a Sphere
2665 //===============================================================================================
2666
2667 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2668                                                   int res ,
2669                                                   double Radius ){
2670   double mRadius = Radius;
2671   double mCenter[3] = {X,Y,Z};
2672   int mThetaResolution;
2673   int mPhiResolution;
2674   double mStartTheta = 0;//StartTheta;
2675   double mEndTheta = 360;//EndTheta;
2676   double mStartPhi = 0;//StartPhi;
2677   double mEndPhi = 180;//EndPhi;
2678   res = res < 4 ? 4 : res;
2679
2680   mThetaResolution = res;
2681   mPhiResolution = res;
2682
2683   int i, j;
2684   int jStart, jEnd, numOffset;
2685   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2686   double startTheta, endTheta, startPhi, endPhi;
2687   int base, numPoles=0, thetaResolution, phiResolution;
2688
2689   int pts[3];
2690   int piece = -1;
2691   int numPieces = 1;
2692   if ( numPieces > mThetaResolution ) {
2693     numPieces = mThetaResolution;
2694   }
2695
2696   int localThetaResolution =  mThetaResolution;
2697   double localStartTheta =  mStartTheta;
2698   double localEndTheta =  mEndTheta;
2699
2700   while ( localEndTheta < localStartTheta ) {
2701     localEndTheta += 360.0;
2702   }
2703
2704   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2705
2706   // Change the ivars based on pieces.
2707   int start, end;
2708   start = piece * localThetaResolution / numPieces;
2709   end = (piece+1) * localThetaResolution / numPieces;
2710   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2711   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2712   localThetaResolution = end - start;
2713
2714   // Create north pole if needed
2715   int number_point = 0;
2716   int number_pointArray = 0;
2717
2718   if ( mStartPhi <= 0.0 ) {
2719     number_pointArray++;
2720     numPoles++;
2721   }
2722   if ( mEndPhi >= 180.0 ) {
2723     number_pointArray++;
2724     numPoles++;
2725   }
2726
2727   // Check data, determine increments, and convert to radians
2728   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2729   startTheta *= M_PI  / 180.0;
2730   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2731   endTheta *= M_PI  / 180.0;
2732
2733
2734   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2735   startPhi *= M_PI  / 180.0;
2736   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2737   endPhi *= M_PI  / 180.0;
2738
2739   phiResolution =  mPhiResolution - numPoles;
2740   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2741   thetaResolution = localThetaResolution;
2742   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2743     ++localThetaResolution;
2744   }
2745   deltaTheta = (endTheta - startTheta) / thetaResolution;
2746
2747   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2748   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2749
2750   // Create intermediate points
2751   for ( i = 0; i < localThetaResolution; i++ ) {
2752     for ( j = jStart; j < jEnd; j++ ) {
2753         number_pointArray++;
2754     }
2755   }
2756
2757   //Generate mesh connectivity
2758   base = phiResolution * localThetaResolution;
2759
2760   int number_triangle = 0 ;
2761   if ( mStartPhi <= 0.0 ) { // around north pole
2762     number_triangle += localThetaResolution;
2763   }
2764
2765   if ( mEndPhi >= 180.0 ) { // around south pole
2766     number_triangle += localThetaResolution;
2767   }
2768
2769   // bands in-between poles
2770   for ( i=0; i < localThetaResolution; i++){
2771     for ( j=0; j < (phiResolution-1); j++){
2772        number_triangle +=2;
2773     }
2774   }
2775
2776   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2777   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2778   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2779
2780   if (  mStartPhi <= 0.0 ){
2781       x[0] =  mCenter[0];
2782       x[1] =  mCenter[1];
2783       x[2] =  mCenter[2] +  mRadius;
2784       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2785   }
2786
2787   // Create south pole if needed
2788   if (  mEndPhi >= 180.0 ){
2789       x[0] =  mCenter[0];
2790       x[1] =  mCenter[1];
2791       x[2] =  mCenter[2] -  mRadius;
2792       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2793   }
2794
2795   number_point = 3;
2796   for ( i=0; i < localThetaResolution; i++){
2797     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2798     for ( j = jStart; j < jEnd; j++){
2799         phi = startPhi + j*deltaPhi;
2800         radius =  mRadius * sin((double)phi);
2801         n[0] = radius * cos((double)theta);
2802         n[1] = radius * sin((double)theta);
2803         n[2] =  mRadius * cos((double)phi);
2804         x[0] = n[0] +  mCenter[0];
2805         x[1] = n[1] +  mCenter[1];
2806         x[2] = n[2] +  mCenter[2];
2807         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2808         number_point++;
2809       }
2810     }
2811
2812   numPoles = 3;
2813   number_triangle = 1;
2814   if ( mStartPhi <= 0.0 ){// around north pole
2815     for (i=0; i < localThetaResolution; i++){
2816         pts[0] = phiResolution*i + numPoles;
2817         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2818         pts[2] = 1;
2819         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2820         number_triangle++;
2821       }
2822     }
2823
2824   if (  mEndPhi >= 180.0 ){ // around south pole
2825     numOffset = phiResolution - 1 + numPoles;
2826     for (i=0; i < localThetaResolution; i++){
2827         pts[0] = phiResolution*i + numOffset;
2828         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2829         pts[1] = numPoles - 1;
2830         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2831         number_triangle++;
2832       }
2833     }
2834
2835   // bands in-between poles
2836
2837   for (i=0; i < localThetaResolution; i++){
2838     for (j=0; j < (phiResolution-1); j++){
2839         pts[0] = phiResolution*i + j + numPoles;
2840         pts[1] = pts[0] + 1;
2841         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2842         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2843         number_triangle++;
2844         pts[1] = pts[2];
2845         pts[2] = pts[1] - 1;
2846         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2847         number_triangle++;
2848       }
2849     }
2850
2851   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2852
2853   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2854
2855   Standard_Integer index[3];
2856   Standard_Real Tol = Precision::Confusion();
2857
2858   gp_Dir Nor;
2859   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2860       gp_XYZ eqPlan(0, 0, 0);
2861       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2862         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2863         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2864         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2865         gp_XYZ vv = v1^v2;
2866         Standard_Real mod = vv.Modulus();
2867         if(mod < Tol) continue;
2868         eqPlan += vv/mod;
2869       }
2870
2871       Standard_Real modmax = eqPlan.Modulus();
2872
2873       if(modmax > Tol)
2874         Nor = gp_Dir(eqPlan);
2875       else
2876         Nor = gp_Dir(0., 0., 1.);
2877
2878       Standard_Integer j = (i - PointsOfArray.Lower()) * 3;
2879       Normals->SetValue(j + 1, (Standard_ShortReal)Nor.X());
2880       Normals->SetValue(j + 2, (Standard_ShortReal)Nor.Y());
2881       Normals->SetValue(j + 3, (Standard_ShortReal)Nor.Z());
2882   }
2883
2884   delete pc;
2885   polyTriangulation->SetNormals(Normals);
2886
2887   return polyTriangulation;
2888 }
2889
2890 //===============================================================================================
2891 //function : VDrawSphere
2892 //author   : psn
2893 //purpose  : Create an AIS shape.
2894 //===============================================================================================
2895 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2896 {
2897   // check for errors
2898   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2899   if (aContextAIS.IsNull())
2900   {
2901     std::cout << "Call vinit before!\n";
2902     return 1;
2903   }
2904   else if (argc < 3)
2905   {
2906     std::cout << "Use: " << argv[0]
2907               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2908     return 1;
2909   }
2910
2911   // read the arguments
2912   TCollection_AsciiString aShapeName (argv[1]);
2913   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2914   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2915   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2916   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
2917   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
2918   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
2919   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
2920
2921   // remove AIS object with given name from map
2922   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
2923
2924   if (toPrintInfo)
2925     std::cout << "Compute Triangulation...\n";
2926   Handle(AIS_Triangulation) aShape
2927     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2928                                                   aResolution,
2929                                                   aRadius));
2930   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2931   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2932
2933   // stupid initialization of Green color in RGBA space as integer
2934   // probably wrong for big-endian CPUs
2935   Standard_Integer aRed    = 0;
2936   Standard_Integer aGreen  = 255;
2937   Standard_Integer aBlue   = 0;
2938   Standard_Integer anAlpha = 0; // not used
2939   Standard_Integer aColorInt = aRed;
2940   aColorInt += aGreen  << 8;
2941   aColorInt += aBlue   << 16;
2942   aColorInt += anAlpha << 24;
2943
2944   // setup colors array per vertex
2945   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2946   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2947   {
2948     aColorArray->SetValue (aNodeId, aColorInt);
2949   }
2950   aShape->SetColors (aColorArray);
2951
2952   // show statistics
2953   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2954   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2955   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2956   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2957   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
2958   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
2959   aTotalSize >>= 20; //MB
2960   aNormalsSize >>= 20;
2961   aColorsSize >>= 20;
2962   aTrianglesSize >>= 20;
2963   aPolyConnectSize >>= 20;
2964   if (toPrintInfo)
2965   {
2966     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
2967       << "NumberOfTriangles: " << aNumberTriangles << "\n"
2968       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
2969       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
2970       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
2971       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
2972   }
2973
2974   // Setting material properties, very important for desirable visual result!
2975   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
2976   aMat.SetAmbient (0.2);
2977   aMat.SetSpecular (0.5);
2978   Handle(Graphic3d_AspectFillArea3d) anAspect
2979     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
2980                                       Quantity_NOC_RED,
2981                                       Quantity_NOC_YELLOW,
2982                                       Aspect_TOL_SOLID,
2983                                       1.0,
2984                                       aMat,
2985                                       aMat);
2986   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
2987   if (toShowEdges)
2988   {
2989     anAspect->SetEdgeOn();
2990   }
2991   else
2992   {
2993     anAspect->SetEdgeOff();
2994   }
2995   aShAsp->SetAspect (anAspect);
2996   aShape->Attributes()->SetShadingAspect (aShAsp);
2997
2998   VDisplayAISObject (aShapeName, aShape);
2999   return 0;
3000 }
3001
3002 //=============================================================================
3003 //function : VComputeHLR
3004 //purpose  :
3005 //=============================================================================
3006
3007 static int VComputeHLR (Draw_Interpretor& di,
3008                         Standard_Integer argc,
3009                         const char** argv)
3010 {
3011   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3012
3013   if (aContextAIS.IsNull ())
3014   {
3015     di << "Please call vinit before\n";
3016     return 1;
3017   }
3018
3019   if ( argc != 3 &&  argc != 12 )
3020   {
3021     di << "Usage: " << argv[0] << " ShapeName HlrName "
3022        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]" << "\n"
3023        << "                    ShapeName - name of the initial shape\n"
3024        << "                    HlrName - result hlr object from initial shape\n"
3025        << "                    eye, dir are eye position and look direction\n"
3026        << "                    up is the look up direction vector\n"
3027        << "                    Use vtop to see projected hlr shape\n";
3028     return 1;
3029   }
3030
3031   // shape and new object name
3032   TCollection_AsciiString aShapeName (argv[1]);
3033   TCollection_AsciiString aHlrName (argv[2]);
3034
3035   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3036   if (aSh.IsNull()) 
3037   {
3038     BRep_Builder aBrepBuilder;
3039     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3040     if (aSh.IsNull ())
3041     {
3042       di << "No shape with name " << argv[1] << " found\n";
3043       return 1;
3044     }
3045   }
3046
3047   if (GetMapOfAIS ().IsBound2 (aHlrName))
3048   {
3049     di << "Presentable object with name " << argv[2] << " already exists\n";
3050     return 1;
3051   }
3052
3053   // close local context
3054   if (aContextAIS->HasOpenedContext ())
3055     aContextAIS->CloseLocalContext ();
3056
3057   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3058   HLRBRep_PolyHLRToShape aHLRToShape;
3059
3060   gp_Pnt anEye;
3061   gp_Dir aDir;
3062   gp_Ax2 aProjAx;
3063   if (argc == 9)
3064   {
3065     gp_Dir anUp;
3066
3067     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3068     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3069     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3070     aProjAx.SetLocation (anEye);
3071     aProjAx.SetDirection (aDir);
3072     aProjAx.SetYDirection (anUp);
3073   }
3074   else
3075   {
3076     gp_Dir aRight;
3077
3078     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3079     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3080     Standard_Integer aWidth, aHeight;
3081     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3082     Standard_Real aRightX, aRightY, aRightZ;
3083     aView->Window()->Size (aWidth, aHeight);
3084
3085     aView->ConvertWithProj (aWidth, aHeight/2, 
3086                             aRightX, aRightY, aRightZ,
3087                             aDirX, aDirY, aDirZ);
3088
3089     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3090                             aCentX, aCentY, aCentZ,
3091                             aDirX, aDirY, aDirZ);
3092
3093     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3094     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3095     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3096     aProjAx.SetLocation (anEye);
3097     aProjAx.SetDirection (aDir);
3098     aProjAx.SetXDirection (aRight);
3099   }
3100
3101   HLRAlgo_Projector aProjector (aProjAx);
3102   aPolyAlgo->Projector (aProjector);
3103   aPolyAlgo->Load (aSh);
3104   aPolyAlgo->Update ();
3105
3106   aHLRToShape.Update (aPolyAlgo);
3107
3108   // make hlr shape from input shape
3109   TopoDS_Compound aHlrShape;
3110   BRep_Builder aBuilder;
3111   aBuilder.MakeCompound (aHlrShape);
3112
3113   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3114   if (!aCompound.IsNull ())
3115   {
3116     aBuilder.Add (aHlrShape, aCompound);
3117   }
3118   
3119   // extract visible outlines
3120   aCompound = aHLRToShape.OutLineVCompound();
3121   if (!aCompound.IsNull ())
3122   {
3123     aBuilder.Add (aHlrShape, aCompound);
3124   }
3125
3126   // create an AIS shape and display it
3127   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3128   GetMapOfAIS().Bind (anObject, aHlrName);
3129   aContextAIS->Display (anObject);
3130
3131   aContextAIS->UpdateCurrentViewer ();
3132
3133   return 0;
3134 }
3135
3136 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3137 // manipulating and displaying such an array with AIS context
3138 DEFINE_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3139 class MyPArrayObject : public AIS_InteractiveObject
3140 {
3141
3142 public:
3143
3144   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3145                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3146   {
3147     myArrayDescription = theArrayDescription;
3148     myMarkerAspect = theMarkerAspect;
3149   }
3150
3151   DEFINE_STANDARD_RTTI(MyPArrayObject);
3152
3153 private:
3154
3155   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3156                 const Handle(Prs3d_Presentation)& aPresentation,
3157                 const Standard_Integer aMode);
3158
3159   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3160                          const Standard_Integer /*theMode*/);
3161
3162   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3163                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3164                           Standard_Integer &theArgIndex,
3165                           Standard_Integer theArgCount,
3166                           Standard_Integer theMaxArgs);
3167
3168 protected:
3169
3170   Handle(TColStd_HArray1OfAsciiString) myArrayDescription;
3171   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3172
3173 };
3174
3175 IMPLEMENT_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3176 IMPLEMENT_STANDARD_RTTIEXT(MyPArrayObject, AIS_InteractiveObject)
3177
3178 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3179                               const Handle(Prs3d_Presentation)& aPresentation,
3180                               const Standard_Integer /*aMode*/)
3181 {
3182
3183   // Parsing array description
3184   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3185   Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
3186   hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
3187
3188   Standard_Integer anArgIndex = 0;
3189   Standard_Integer anArgsCount = myArrayDescription->Length();
3190   TCollection_AsciiString anArrayType = myArrayDescription->Value (anArgIndex++);
3191
3192   TCollection_AsciiString aCommand;
3193   while (anArgIndex < anArgsCount)
3194   {
3195     aCommand = myArrayDescription->Value (anArgIndex);
3196     aCommand.LowerCase();
3197
3198     // vertex command
3199     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3200     {
3201       // vertex has a normal or normal with color or texel
3202       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3203         hasNormals = Standard_True;
3204
3205       // vertex has a color
3206       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3207         hasVColors = Standard_True;
3208
3209       // vertex has a texel
3210       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3211         hasTexels = Standard_True;
3212
3213       aVertexNum++;
3214     }
3215     // bound command
3216     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3217     {
3218       // bound has color
3219       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3220         hasBColors = Standard_True;
3221
3222       aBoundNum++;
3223     }
3224     // edge command
3225     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3226     {
3227       aEdgeNum++;
3228     }
3229     // unknown command
3230     else
3231       anArgIndex++;
3232   }
3233
3234   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3235   if (anArrayType == "points")
3236   {
3237     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3238   }
3239   else if (anArrayType == "segments")
3240     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3241   else if (anArrayType == "polylines")
3242     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3243                                               hasVColors, hasBColors);
3244   else if (anArrayType == "triangles")
3245     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3246                                               hasVColors, hasTexels);
3247   else if (anArrayType == "trianglefans")
3248     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3249                                                  hasNormals, hasVColors,
3250                                                  hasBColors, hasTexels);
3251   else if (anArrayType == "trianglestrips")
3252     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3253                                                    hasNormals, hasVColors,
3254                                                    hasBColors, hasTexels);
3255   else if (anArrayType == "quads")
3256     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3257                                                 hasNormals, hasVColors,
3258                                                 hasTexels);
3259   else if (anArrayType == "quadstrips")
3260     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3261                                                      hasNormals, hasVColors,
3262                                                      hasBColors, hasTexels);
3263   else if (anArrayType == "polygons")
3264     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3265                                              hasNormals, hasVColors, hasBColors,
3266                                              hasTexels);
3267
3268   anArgIndex = 1;
3269   while (anArgIndex < anArgsCount)
3270   {
3271     aCommand = myArrayDescription->Value (anArgIndex);
3272     aCommand.LowerCase();
3273     if (!aCommand.IsAscii())
3274       break;
3275
3276     // vertex command
3277     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3278     {
3279       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3280                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
3281                           myArrayDescription->Value (anArgIndex - 1).RealValue());
3282       const Standard_Integer aVertIndex = anArray->VertexNumber();
3283
3284       // vertex has a normal or normal with color or texel
3285       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3286         anArray->SetVertexNormal (aVertIndex,
3287                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
3288                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
3289                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
3290       
3291       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3292         anArray->SetVertexColor (aVertIndex,
3293                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
3294                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3295                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3296       
3297       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3298         anArray->SetVertexTexel (aVertIndex,
3299                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3300                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3301     }
3302     // bounds command
3303     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3304     {
3305       Standard_Integer aVertCount = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3306
3307       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3308         anArray->AddBound (aVertCount,
3309                            myArrayDescription->Value (anArgIndex - 3).RealValue(),
3310                            myArrayDescription->Value (anArgIndex - 2).RealValue(),
3311                            myArrayDescription->Value (anArgIndex - 1).RealValue());
3312
3313       else
3314         anArray->AddBound (aVertCount);
3315     }
3316     // edge command
3317     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3318     {
3319       const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3320       anArray->AddEdge (aVertIndex);
3321     }
3322     // unknown command
3323     else
3324       anArgIndex++;
3325   }
3326
3327   aPresentation->Clear();
3328   if (!myMarkerAspect.IsNull())
3329   {
3330     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
3331   }
3332   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
3333 }
3334
3335 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3336                                        const Standard_Integer /*theMode*/)
3337 {
3338   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
3339
3340   Standard_Integer anArgIndex = 1;
3341   while (anArgIndex < myArrayDescription->Length())
3342   {
3343     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, myArrayDescription->Length()))
3344     {
3345       gp_Pnt aPoint (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3346                      myArrayDescription->Value (anArgIndex - 2).RealValue(),
3347                      myArrayDescription->Value (anArgIndex - 1).RealValue());
3348       Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
3349       theSelection->Add (aSensetivePoint);
3350     }
3351     else
3352     {
3353       anArgIndex++;
3354     }
3355   }
3356 }
3357
3358 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3359                                        const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3360                                        Standard_Integer &theArgIndex,
3361                                        Standard_Integer theArgCount,
3362                                        Standard_Integer theMaxArgs)
3363 {
3364   // check if there is more elements than expected
3365   if (theArgIndex >= theMaxArgs)
3366     return false;
3367
3368   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3369   aStrCommand.LowerCase();
3370   if (aStrCommand.Search(theCommand) != 1 ||
3371       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3372     return false;
3373
3374   // go to the first data element
3375   theArgIndex++;
3376
3377   // check data if it can be converted to numeric
3378   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3379   {
3380     aStrCommand = theArgsArray->Value (theArgIndex);
3381     if (!aStrCommand.IsRealValue())
3382       return false;
3383   }
3384
3385   return true;
3386 }
3387
3388 //=============================================================================
3389 //function : VDrawPArray
3390 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3391 //=============================================================================
3392
3393 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3394 {
3395   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3396   if (aContextAIS.IsNull())
3397   {
3398     di << "Call vinit before!\n";
3399     return 1;
3400   }
3401   else if (argc < 3)
3402   {
3403     di << "Use: " << argv[0] << " Name TypeOfArray"
3404        << " [vertex] ... [bounds] ... [edges]\n"
3405        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
3406        << "                trianglefans | trianglestrips | quads |\n"
3407        << "                quadstrips | polygons }\n"
3408        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
3409        << " [texel={ 't' tx ty }] } \n"
3410        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
3411        << "  edges={ 'e' vertex_id }\n";
3412     return 1;
3413   }
3414
3415   // read the arguments
3416   Standard_Integer aArgIndex = 1;
3417   TCollection_AsciiString aName (argv[aArgIndex++]);
3418   TCollection_AsciiString anArrayType (argv[aArgIndex++]);
3419
3420   Standard_Boolean hasVertex = Standard_False;
3421
3422   Handle(TColStd_HArray1OfAsciiString) anArgsArray = new TColStd_HArray1OfAsciiString (0, argc - 2);
3423   anArgsArray->SetValue (0, anArrayType);
3424
3425   if (anArrayType != "points"         &&
3426       anArrayType != "segments"       &&
3427       anArrayType != "polylines"      &&
3428       anArrayType != "triangles"      &&
3429       anArrayType != "trianglefans"   &&
3430       anArrayType != "trianglestrips" &&
3431       anArrayType != "quads"          &&
3432       anArrayType != "quadstrips"     &&
3433       anArrayType != "polygons")
3434   {
3435     di << "Unexpected type of primitives array\n";
3436     return 1;
3437   }
3438
3439   TCollection_AsciiString aCommand;
3440   for (Standard_Integer anArgIndex = 3; anArgIndex < argc; anArgIndex++)
3441   {
3442     aCommand = argv[anArgIndex];
3443     aCommand.LowerCase();
3444     if (!aCommand.IsAscii())
3445     {
3446       di << "Unexpected argument: #" << aArgIndex - 1 << " , "
3447          << "should be an array element: 'v', 'b', 'e' \n";
3448       break;
3449     }
3450
3451     if (aCommand == "v")
3452     {
3453       hasVertex = Standard_True;
3454     }
3455
3456     anArgsArray->SetValue (anArgIndex - 2, aCommand);
3457   }
3458
3459   if (!hasVertex)
3460   {
3461     di << "You should pass any verticies in the list of array elements\n";
3462     return 1;
3463   }
3464
3465   Handle(Graphic3d_AspectMarker3d)    anAspPoints;
3466   if (anArrayType == "points")
3467   {
3468     anAspPoints = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
3469   }
3470
3471   // create primitives array object
3472   Handle(MyPArrayObject) aPObject = new MyPArrayObject (anArgsArray, anAspPoints);
3473
3474   // register the object in map
3475   VDisplayAISObject (aName, aPObject);
3476
3477   return 0;
3478 }
3479
3480 //=======================================================================
3481 //function : VSetLocation
3482 //purpose  : Change location of AIS interactive object
3483 //=======================================================================
3484
3485 static Standard_Integer VSetLocation (Draw_Interpretor& /*di*/,
3486                                       Standard_Integer  theArgNb,
3487                                       const char**      theArgVec)
3488 {
3489   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3490   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
3491   if (aContext.IsNull())
3492   {
3493     std::cout << "Error: no active view!\n";
3494     return 1;
3495   }
3496
3497   TCollection_AsciiString aName;
3498   gp_Vec aLocVec;
3499   Standard_Boolean isSetLoc = Standard_False;
3500
3501   Standard_Integer anArgIter = 1;
3502   for (; anArgIter < theArgNb; ++anArgIter)
3503   {
3504     Standard_CString anArg = theArgVec[anArgIter];
3505     if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3506     {
3507       continue;
3508     }
3509     else if (aName.IsEmpty())
3510     {
3511       aName = anArg;
3512     }
3513     else if (!isSetLoc)
3514     {
3515       isSetLoc = Standard_True;
3516       if (anArgIter + 1 >= theArgNb)
3517       {
3518         std::cout << "Error: syntax error at '" << anArg << "'\n";
3519         return 1;
3520       }
3521       aLocVec.SetX (Draw::Atof (theArgVec[anArgIter++]));
3522       aLocVec.SetY (Draw::Atof (theArgVec[anArgIter]));
3523       if (anArgIter + 1 < theArgNb)
3524       {
3525         aLocVec.SetZ (Draw::Atof (theArgVec[++anArgIter]));
3526       }
3527     }
3528     else
3529     {
3530       std::cout << "Error: unknown argument '" << anArg << "'\n";
3531       return 1;
3532     }
3533   }
3534
3535   // find object
3536   const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3537   Handle(AIS_InteractiveObject) anIObj;
3538   if (aMap.IsBound2 (aName))
3539   {
3540     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
3541   }
3542   if (anIObj.IsNull())
3543   {
3544     std::cout << "Error: object '" << aName << "' is not displayed!\n";
3545     return 1;
3546   }
3547
3548   gp_Trsf aTrsf;
3549   aTrsf.SetTranslation (aLocVec);
3550   TopLoc_Location aLocation (aTrsf);
3551   aContext->SetLocation (anIObj, aLocation);
3552   return 0;
3553 }
3554
3555 //=======================================================================
3556 //function : TransformPresentation
3557 //purpose  : Change transformation of AIS interactive object
3558 //=======================================================================
3559 static Standard_Integer LocalTransformPresentation (Draw_Interpretor& /*theDi*/,
3560                                                     Standard_Integer theArgNb,
3561                                                     const char** theArgVec)
3562 {
3563   if (theArgNb <= 1)
3564   {
3565     std::cout << "Error: too few arguments.\n";
3566     return 1;
3567   }
3568
3569   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3570   ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
3571   if (aContext.IsNull())
3572   {
3573     std::cout << "Error: no active view!\n";
3574     return 1;
3575   }
3576
3577   gp_Trsf aTrsf;
3578   Standard_Integer aLast = theArgNb;
3579   const char* aName = theArgVec[0];
3580
3581   Standard_Boolean isReset = Standard_False;
3582   Standard_Boolean isMove = Standard_False;
3583
3584   // Prefix 'vloc'
3585   aName += 4;
3586
3587   if (!strcmp (aName, "reset"))
3588   {
3589     isReset = Standard_True;
3590   }
3591   else if (!strcmp (aName, "move"))
3592   {
3593     if (theArgNb < 3)
3594     {
3595       std::cout << "Error: too few arguments.\n";
3596       return 1;
3597     }
3598
3599     const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3600
3601     Handle(AIS_InteractiveObject) anIObj;
3602     if (aMap.IsBound2 (theArgVec[theArgNb - 1]))
3603     {
3604       anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[theArgNb - 1]));
3605     }
3606
3607     if (anIObj.IsNull())
3608     {
3609       std::cout << "Error: object '" << theArgVec[theArgNb - 1] << "' is not displayed!\n";
3610       return 1;
3611     }
3612
3613     isMove = Standard_True;
3614
3615     aTrsf = anIObj->Transformation();
3616     aLast = theArgNb - 1;
3617   }
3618   else if (!strcmp (aName, "translate"))
3619   {
3620     if (theArgNb < 5)
3621     {
3622       std::cout << "Error: too few arguments.\n";
3623       return 1;
3624     }
3625     aTrsf.SetTranslation (gp_Vec (Draw::Atof (theArgVec[theArgNb - 3]),
3626                                   Draw::Atof (theArgVec[theArgNb - 2]),
3627                                   Draw::Atof (theArgVec[theArgNb - 1])));
3628     aLast = theArgNb - 3;
3629   }
3630   else if (!strcmp (aName, "rotate"))
3631   {
3632     if (theArgNb < 9)
3633     {
3634       std::cout << "Error: too few arguments.\n";
3635       return 1;
3636     }
3637
3638     aTrsf.SetRotation (
3639       gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[theArgNb - 7]),
3640                       Draw::Atof (theArgVec[theArgNb - 6]),
3641                       Draw::Atof (theArgVec[theArgNb - 5])),
3642               gp_Vec (Draw::Atof (theArgVec[theArgNb - 4]),
3643                       Draw::Atof (theArgVec[theArgNb - 3]),
3644                       Draw::Atof (theArgVec[theArgNb - 2]))),
3645       Draw::Atof (theArgVec[theArgNb - 1]) * (M_PI / 180.0));
3646
3647     aLast = theArgNb - 7;
3648   }
3649   else if (!strcmp (aName, "mirror"))
3650   {
3651     if (theArgNb < 8)
3652     {
3653       std::cout << "Error: too few arguments.\n";
3654       return 1;
3655     }
3656
3657     aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
3658                                      Draw::Atof(theArgVec[theArgNb - 5]),
3659                                      Draw::Atof(theArgVec[theArgNb - 4])),
3660                              gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
3661                                      Draw::Atof(theArgVec[theArgNb - 2]),
3662                                      Draw::Atof(theArgVec[theArgNb - 1]))));
3663     aLast = theArgNb - 6;
3664   }
3665   else if (!strcmp (aName, "scale"))
3666   {
3667     if (theArgNb < 6)
3668     {
3669       std::cout << "Error: too few arguments.\n";
3670       return 1;
3671     }
3672
3673     aTrsf.SetScale (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 4]),
3674                             Draw::Atof(theArgVec[theArgNb - 3]),
3675                             Draw::Atof(theArgVec[theArgNb - 2])),
3676                     Draw::Atof(theArgVec[theArgNb - 1]));
3677     aLast = theArgNb - 4;
3678   }
3679
3680   for (Standard_Integer anIdx = 1; anIdx < aLast; anIdx++)
3681   {
3682     // find object
3683     const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3684     Handle(AIS_InteractiveObject) anIObj;
3685     if (aMap.IsBound2 (theArgVec[anIdx]))
3686     {
3687       anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[anIdx]));
3688     }
3689     if (anIObj.IsNull())
3690     {
3691       std::cout << "Error: object '" << theArgVec[anIdx] << "' is not displayed!\n";
3692       return 1;
3693     }
3694     
3695     if (isReset)
3696     {
3697       // aTrsf already identity
3698     }
3699     else if (isMove)
3700     {
3701       aTrsf = anIObj->LocalTransformation() * anIObj->Transformation().Inverted() * aTrsf;
3702     }
3703     else
3704     {
3705       aTrsf = anIObj->LocalTransformation() * aTrsf;
3706     }
3707
3708     TopLoc_Location aLocation (aTrsf);
3709     aContext->SetLocation (anIObj, aLocation);
3710   }
3711
3712   return 0;
3713 }
3714
3715 //===============================================================================================
3716 //function : VConnect
3717 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3718 //Draw arg : vconnect name Xo Yo Zo object1 object2 ... [color=NAME]
3719 //===============================================================================================
3720
3721 static Standard_Integer VConnect (Draw_Interpretor& /*di*/, 
3722                                   Standard_Integer argc, 
3723                                   const char ** argv) 
3724 {
3725   // Check the viewer
3726   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3727   if (aContext.IsNull())
3728   {
3729     std::cout << "vconnect error : call vinit before\n";
3730     return 1; // TCL_ERROR
3731   }
3732   // Check argumnets 
3733   if (argc < 6)
3734   {
3735     std::cout << "vconnect error: expect at least 5 arguments\n";
3736     return 1; // TCL_ERROR
3737   }
3738
3739   // Get values
3740   Standard_Integer anArgIter = 1;
3741   TCollection_AsciiString aName (argv[anArgIter++]);
3742   Handle(AIS_MultipleConnectedInteractive) anOriginObject;
3743   TCollection_AsciiString aColorString (argv[argc-1]);
3744   Standard_CString aColorName = "";
3745   Standard_Boolean hasColor = Standard_False;
3746   if (aColorString.Search ("color=") != -1)
3747   {
3748     hasColor = Standard_True;
3749     aColorString.Remove (1, 6);
3750     aColorName = aColorString.ToCString();
3751   }
3752   Handle(AIS_InteractiveObject) anObject;
3753
3754   // AIS_MultipleConnectedInteractive
3755   const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
3756   for (Standard_Integer i = 5; i < aNbShapes; ++i)
3757   {
3758     TCollection_AsciiString anOriginObjectName (argv[i]);
3759     if (aName.IsEqual (anOriginObjectName))
3760     {
3761       std::cout << "vconnect error: equal names for connected objects\n";
3762       continue;
3763     }
3764     if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3765     {
3766       Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3767       anObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3768       if (anObject.IsNull())
3769       {
3770         std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3771         continue;
3772       }
3773     }
3774     else
3775     {
3776       Standard_CString aName = anOriginObjectName.ToCString();
3777       TopoDS_Shape aTDShape = DBRep::Get (aName);
3778       if (aTDShape.IsNull())
3779       {
3780         std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3781         continue;
3782       }
3783       anObject = new AIS_Shape (aTDShape);
3784       aContext->Load (anObject);
3785       anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
3786     }
3787
3788     if (anOriginObject.IsNull())
3789     {
3790       anOriginObject = new AIS_MultipleConnectedInteractive();
3791     }
3792
3793     anOriginObject->Connect (anObject);
3794   }
3795   if (anOriginObject.IsNull())
3796   {
3797     std::cout << "vconect error : can't connect input objects\n";
3798     return 1; // TCL_ERROR
3799   }
3800
3801   // Get location data
3802   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3803   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3804   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3805
3806   // Create transformation
3807   gp_Vec aTranslation (aXo, aYo, aZo);
3808
3809   gp_Trsf aTrsf; 
3810   aTrsf.SetTranslationPart (aTranslation);
3811   TopLoc_Location aLocation (aTrsf);
3812
3813   anOriginObject->SetLocalTransformation (aTrsf);
3814
3815   // Check if there is another object with given name
3816   // and remove it from context
3817   if(GetMapOfAIS().IsBound2(aName))
3818   {
3819     Handle(AIS_InteractiveObject) anObj = 
3820       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3821     TheAISContext()->Remove(anObj, Standard_False);
3822     GetMapOfAIS().UnBind2(aName);
3823   }
3824
3825   // Bind connected object to its name
3826   GetMapOfAIS().Bind (anOriginObject, aName);
3827
3828   // Display connected object
3829   TheAISContext()->Display (anOriginObject);
3830
3831   return 0;
3832 }
3833
3834 //===============================================================================================
3835 //function : VConnectTo
3836 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3837 //Draw arg : vconnectto name Xo Yo Zo object [-nodisplay|-noupdate|-update]
3838 //===============================================================================================
3839
3840 static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, 
3841                                     Standard_Integer argc, 
3842                                     const char ** argv) 
3843 {
3844   // Check the viewer
3845   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3846   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
3847   if (aContext.IsNull())
3848   {
3849     std::cout << "vconnect error : call vinit before\n";
3850     return 1; // TCL_ERROR
3851   }
3852   // Check argumnets 
3853   if (argc != 6 && argc != 7)
3854   {
3855     std::cout << "vconnect error: expect at least 5 arguments\n";
3856     return 1; // TCL_ERROR
3857   }
3858
3859   // Get values
3860   Standard_Integer anArgIter = 1;
3861   TCollection_AsciiString aName (argv[anArgIter++]);
3862   Handle(AIS_InteractiveObject) anOriginObject;
3863
3864   TCollection_AsciiString anOriginObjectName(argv[5]);
3865   if (aName.IsEqual (anOriginObjectName))
3866   {
3867     std::cout << "vconnect error: equal names for connected objects\n"; 
3868     return 1; // TCL_ERROR
3869   }
3870   if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3871   {
3872     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3873     anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3874     if (anOriginObject.IsNull())
3875     {
3876       std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3877       return 1; // TCL_ERROR
3878     }
3879   }
3880   else
3881   {
3882     Standard_CString aName = anOriginObjectName.ToCString();
3883     TopoDS_Shape aTDShape = DBRep::Get (aName);
3884     if (aTDShape.IsNull())
3885     {
3886       std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3887       return 1; // TCL_ERROR
3888     }
3889     anOriginObject = new AIS_Shape (aTDShape);
3890     GetMapOfAIS().Bind (anOriginObject, anOriginObjectName);
3891   }
3892  
3893   // Get location data
3894   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3895   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3896   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3897
3898   // Create transformation
3899   gp_Vec aTranslation (aXo, aYo, aZo);
3900
3901   gp_Trsf aTrsf; 
3902   aTrsf.SetTranslationPart (aTranslation);
3903  
3904   Handle(AIS_ConnectedInteractive) aConnected;
3905
3906   aConnected = new AIS_ConnectedInteractive();
3907
3908   aConnected->Connect (anOriginObject, aTrsf);
3909
3910   // Check if there is another object with given name
3911   // and remove it from context
3912   if(GetMapOfAIS().IsBound2(aName))
3913   {
3914     Handle(AIS_InteractiveObject) anObj = 
3915       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3916     TheAISContext()->Remove(anObj, Standard_False);
3917     GetMapOfAIS().UnBind2(aName);
3918   }
3919
3920   // Bind connected object to its name
3921   GetMapOfAIS().Bind (aConnected, aName);
3922
3923   if (argc == 7)
3924   {
3925     TCollection_AsciiString anArg = argv[6];
3926     anArg.LowerCase();
3927     if (anArg == "-nodisplay")
3928       return 0;
3929
3930     if (!anUpdateTool.parseRedrawMode (anArg))
3931     {
3932       std::cout << "Warning! Unknown argument '" << anArg << "' passed, -nodisplay|-noupdate|-update expected at this point.\n";
3933     }
3934   }
3935
3936   // Display connected object
3937   TheAISContext()->Display (aConnected, Standard_False);
3938
3939   return 0;
3940 }
3941
3942 //=======================================================================
3943 //function : VDisconnect
3944 //purpose  :
3945 //=======================================================================
3946 static Standard_Integer VDisconnect (Draw_Interpretor& di,
3947                                      Standard_Integer argc,
3948                                      const char ** argv)
3949 {
3950   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3951   if (aContext.IsNull())
3952   {
3953     std::cout << argv[0] << "ERROR : use 'vinit' command before " << "\n";
3954     return 1;
3955   }
3956   
3957   if (argc != 3)
3958   {
3959     std::cout << "ERROR : Usage : " << argv[0] << " name object" << "\n";
3960     return 1;
3961   }
3962
3963   TCollection_AsciiString aName (argv[1]);
3964   TCollection_AsciiString anObject (argv[2]);
3965   Standard_Integer anObjectNumber = Draw::Atoi (argv[2]);
3966
3967   // find objects
3968   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3969   Handle(AIS_MultipleConnectedInteractive) anAssembly;
3970   if (!aMap.IsBound2 (aName) )
3971   {
3972     std::cout << "Use 'vdisplay' before" << "\n";
3973     return 1;
3974   }
3975
3976   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
3977   if (anAssembly.IsNull())
3978   {
3979     di << "Not an assembly" << "\n";
3980     return 1;
3981   }
3982
3983   Handle(AIS_InteractiveObject) anIObj;
3984   if (!aMap.IsBound2 (anObject))
3985   {
3986     // try to interpret second argument as child number
3987     if (anObjectNumber > 0 && anObjectNumber <= anAssembly->Children().Size())
3988     {
3989       Standard_Integer aCounter = 1;
3990       for (PrsMgr_ListOfPresentableObjectsIter anIter (anAssembly->Children()); anIter.More(); anIter.Next())
3991       {
3992         if (aCounter == anObjectNumber)
3993         {
3994           anIObj = Handle(AIS_InteractiveObject)::DownCast (anIter.Value());
3995           break;
3996         }
3997         ++aCounter;
3998       }
3999     }
4000     else
4001     {
4002       std::cout << "Use 'vdisplay' before" << "\n";
4003       return 1;
4004     }    
4005   }
4006
4007   // if object was found by name
4008   if (anIObj.IsNull())
4009   {
4010     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (anObject));
4011   }
4012
4013   aContext->Disconnect (anAssembly, anIObj);
4014   aContext->UpdateCurrentViewer();
4015
4016   return 0;
4017 }
4018
4019 //=======================================================================
4020 //function : VAddConnected
4021 //purpose  :
4022 //=======================================================================
4023 static Standard_Integer VAddConnected (Draw_Interpretor& di,
4024                                        Standard_Integer argc,
4025                                        const char ** argv)
4026 {
4027   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4028   if (aContext.IsNull())
4029   {
4030     std::cout << argv[0] << "error : use 'vinit' command before " << "\n";
4031     return 1;
4032   }
4033   
4034   if (argc != 6)
4035   {
4036     std::cout << argv[0] << " error: expect 5 arguments\n";
4037     return 1;
4038   }
4039
4040   TCollection_AsciiString aName (argv[1]);
4041   TCollection_AsciiString anObject (argv[5]);
4042   Standard_Real aX = Draw::Atof (argv[2]);
4043   Standard_Real aY = Draw::Atof (argv[3]);
4044   Standard_Real aZ = Draw::Atof (argv[4]);
4045
4046   // find object
4047   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4048   Handle(AIS_MultipleConnectedInteractive) anAssembly;
4049   if (!aMap.IsBound2 (aName) )
4050   {
4051     std::cout << "Use 'vdisplay' before" << "\n";
4052     return 1;
4053   }
4054
4055   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
4056   if (anAssembly.IsNull())
4057   {
4058     di << "Not an assembly" << "\n";
4059     return 1;
4060   }
4061
4062   Handle(AIS_InteractiveObject) anIObj;
4063   if (!aMap.IsBound2 (anObject))
4064   {
4065       std::cout << "Use 'vdisplay' before" << "\n";
4066       return 1; 
4067   }
4068
4069   anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (anObject));
4070
4071   gp_Trsf aTrsf;
4072   aTrsf.SetTranslation (gp_Vec (aX, aY, aZ));
4073  
4074   anAssembly->Connect (anIObj, aTrsf);
4075   TheAISContext()->Display (anAssembly);
4076   TheAISContext()->RecomputeSelectionOnly (anAssembly);
4077   aContext->UpdateCurrentViewer();
4078
4079   return 0;
4080 }
4081
4082 //=======================================================================
4083 //function : VListConnected
4084 //purpose  :
4085 //=======================================================================
4086 static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
4087                                         Standard_Integer argc,
4088                                         const char ** argv)
4089 {
4090   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4091   if (aContext.IsNull())
4092   {
4093     std::cout << argv[0] << "ERROR : use 'vinit' command before " << "\n";
4094     return 1;
4095   }
4096   
4097   if (argc != 2)
4098   {
4099     std::cout << "ERROR : Usage : " << argv[0] << " name" << "\n";
4100     return 1;
4101   }
4102
4103   TCollection_AsciiString aName (argv[1]);
4104
4105   // find object
4106   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4107   Handle(AIS_MultipleConnectedInteractive) anAssembly;
4108   if (!aMap.IsBound2 (aName) )
4109   {
4110     std::cout << "Use 'vdisplay' before" << "\n";
4111     return 1;
4112   }
4113
4114   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
4115   if (anAssembly.IsNull())
4116   {
4117     std::cout << "Not an assembly" << "\n";
4118     return 1;
4119   }
4120
4121   std::cout << "Children of " << aName << ":\n";
4122
4123   Standard_Integer aCounter = 1;
4124   for (PrsMgr_ListOfPresentableObjectsIter anIter (anAssembly->Children()); anIter.More(); anIter.Next())
4125   {
4126     if (GetMapOfAIS().IsBound1 (anIter.Value()))
4127     {
4128       TCollection_AsciiString aName = GetMapOfAIS().Find1 (anIter.Value());
4129       std::cout << aCounter << ")  " << aName << "    (" << anIter.Value()->DynamicType()->Name() << ")";
4130     }
4131
4132     std::cout << aCounter << ")  " << anIter.Value()->DynamicType()->Name();
4133
4134     Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (anIter.Value());
4135     if (!aConnected.IsNull() && !aConnected->ConnectedTo().IsNull() && aMap.IsBound1 (aConnected->ConnectedTo()))
4136     {
4137       std::cout << " connected to " << aMap.Find1 (aConnected->ConnectedTo());
4138     }
4139     std::cout << std::endl;
4140     
4141     ++aCounter;
4142   }
4143
4144   return 0;
4145 }
4146
4147 namespace
4148 {
4149   //! Checks if theMode is already turned on for theObj.
4150   static Standard_Boolean InList (const Handle(AIS_InteractiveContext)& theAISContext,
4151                                   const Handle(AIS_InteractiveObject)&  theObj,
4152                                   const Standard_Integer                theMode)
4153   {
4154     TColStd_ListOfInteger anActiveModes;
4155     theAISContext->ActivatedModes (theObj, anActiveModes);
4156     for (TColStd_ListIteratorOfListOfInteger aModeIt (anActiveModes); aModeIt.More(); aModeIt.Next())
4157     {
4158       if (aModeIt.Value() == theMode)
4159       {
4160         return Standard_True;
4161       }
4162     }
4163     return Standard_False;
4164   }
4165 };
4166
4167 //===============================================================================================
4168 //function : VSetSelectionMode
4169 //purpose  : Sets input selection mode for input object or for all displayed objects 
4170 //Draw arg : vselmode [object] mode On/Off (1/0)
4171 //===============================================================================================
4172 static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
4173                                            Standard_Integer  theArgc,
4174                                            const char**      theArgv)
4175 {
4176   // Check errors
4177   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4178   if (anAISContext.IsNull())
4179   {
4180     std::cerr << "Call vinit before!" << std::endl;
4181     return 1;
4182   }
4183
4184   // Check the arguments
4185   if (theArgc != 3 && theArgc != 4)
4186   {
4187     std::cerr << "vselmode error : expects at least 2 arguments.\n"
4188               << "Type help "<< theArgv[0] <<" for more information." << std::endl;
4189     return 1;
4190   }
4191
4192   // get objects to change selection mode
4193   AIS_ListOfInteractive aTargetIOs;
4194   if (theArgc == 3)
4195   {
4196     anAISContext->DisplayedObjects (aTargetIOs);
4197   }
4198   else
4199   {
4200     // Check if there is an object with given name in context
4201     const TCollection_AsciiString aNameIO (theArgv[1]);
4202     if (GetMapOfAIS().IsBound2 (aNameIO))
4203     {
4204       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aNameIO));
4205       if (anIO.IsNull())
4206       {
4207         std::cerr << "vselmode error : object name is used for non AIS viewer" << std::endl;
4208         return 1;
4209       }
4210       aTargetIOs.Append (anIO);
4211     }
4212   }
4213
4214   const Standard_Integer aSelectionMode = Draw::Atoi (theArgc == 3 ? theArgv[1] : theArgv[2]);
4215   const Standard_Boolean toTurnOn       = Draw::Atoi (theArgc == 3 ? theArgv[2] : theArgv[3]);
4216   if (aSelectionMode == 0 && anAISContext->HasOpenedContext())
4217   {
4218     anAISContext->CloseLocalContext();
4219   }
4220
4221   if (aSelectionMode == 0)
4222   {
4223     if (toTurnOn)
4224     {
4225       for (AIS_ListIteratorOfListOfInteractive aTargetIt (aTargetIOs); aTargetIt.More(); aTargetIt.Next())
4226       {
4227         const Handle(AIS_InteractiveObject)& anIO = aTargetIt.Value();
4228         if (!InList (anAISContext, anIO, aSelectionMode))
4229         {
4230           anAISContext->Activate (anIO);
4231         }
4232       }
4233     }
4234     else
4235     {
4236       for (AIS_ListIteratorOfListOfInteractive aTargetIt (aTargetIOs); aTargetIt.More(); aTargetIt.Next())
4237       {
4238         const Handle(AIS_InteractiveObject)& anIO = aTargetIt.Value();
4239         if (InList (anAISContext, anIO, aSelectionMode))
4240         {
4241           anAISContext->Deactivate (anIO);
4242         }
4243       }
4244     }
4245   }
4246
4247   if (aSelectionMode != 0 && toTurnOn) // Turn on specified mode
4248   {
4249     if (!anAISContext->HasOpenedContext())
4250     {
4251       anAISContext->OpenLocalContext (Standard_False);
4252     }
4253
4254     for (AIS_ListIteratorOfListOfInteractive aTargetIt (aTargetIOs); aTargetIt.More(); aTargetIt.Next())
4255     {
4256       const Handle(AIS_InteractiveObject)& anIO = aTargetIt.Value();
4257       if (!InList (anAISContext, anIO, aSelectionMode))
4258       {
4259         anAISContext->Load (anIO, -1, Standard_True);
4260         anAISContext->Activate (anIO, aSelectionMode);
4261       }
4262     }
4263   }
4264
4265   if (aSelectionMode != 0 && !toTurnOn) // Turn off specified mode
4266   {
4267     if (!anAISContext->HasOpenedContext())
4268     {
4269       return 0;
4270     }
4271
4272     for (AIS_ListIteratorOfListOfInteractive aTargetIt (aTargetIOs); aTargetIt.More(); aTargetIt.Next())
4273     {
4274       const Handle(AIS_InteractiveObject)& anIO = aTargetIt.Value();
4275       if (InList (anAISContext, anIO, aSelectionMode))
4276       {
4277         anAISContext->Deactivate (anIO, aSelectionMode);
4278       }
4279     }
4280   }
4281
4282   return 0;
4283 }
4284
4285 //===============================================================================================
4286 //function : VSelectionNext
4287 //purpose  : 
4288 //===============================================================================================
4289 static Standard_Integer VSelectionNext(Draw_Interpretor& /*theDI*/,
4290                                  Standard_Integer /*theArgsNb*/,
4291                                  const char** /*theArgVec*/)
4292 {
4293   // Check errors
4294   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4295   Handle(V3d_View) aView = ViewerTest::CurrentView();
4296
4297   if (anAISContext.IsNull())
4298   {
4299     std::cerr << "Call vinit before!" << std::endl;
4300     return 1;
4301   }
4302
4303   anAISContext->HilightNextDetected(aView);
4304   return 0;
4305 }
4306
4307 //===============================================================================================
4308 //function : VSelectionPrevious
4309 //purpose  : 
4310 //===============================================================================================
4311 static Standard_Integer VSelectionPrevious(Draw_Interpretor& /*theDI*/,
4312                                  Standard_Integer /*theArgsNb*/,
4313                                  const char** /*theArgVec*/)
4314 {
4315   // Check errors
4316   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4317   Handle(V3d_View) aView = ViewerTest::CurrentView();
4318
4319   if (anAISContext.IsNull())
4320   {
4321     std::cerr << "Call vinit before!" << std::endl;
4322     return 1;
4323   }
4324
4325   anAISContext->HilightPreviousDetected(aView);
4326   return 0;
4327 }
4328
4329
4330 //==========================================================================
4331 //class   : Triangle 
4332 //purpose : creates Triangle based on AIS_InteractiveObject. 
4333 //          This class was implemented for testing Select3D_SensitiveTriangle
4334 //===========================================================================
4335 DEFINE_STANDARD_HANDLE(Triangle, AIS_InteractiveObject)
4336 class Triangle: public AIS_InteractiveObject 
4337 {
4338 public: 
4339   // CASCADE RTTI
4340   DEFINE_STANDARD_RTTI(FilledCircle); 
4341   Triangle (const gp_Pnt& theP1, 
4342             const gp_Pnt& theP2, 
4343             const gp_Pnt& theP3);
4344 protected:
4345   void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
4346                   const Handle(Prs3d_Presentation)& thePresentation,
4347                   const Standard_Integer theMode);
4348
4349   void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
4350                            const Standard_Integer theMode);
4351 private: 
4352   gp_Pnt myPoint1;
4353   gp_Pnt myPoint2;
4354   gp_Pnt myPoint3;
4355 };
4356 IMPLEMENT_STANDARD_HANDLE(Triangle, AIS_InteractiveObject)
4357 IMPLEMENT_STANDARD_RTTIEXT(Triangle, AIS_InteractiveObject)
4358
4359 Triangle::Triangle (const gp_Pnt& theP1,
4360                     const gp_Pnt& theP2,
4361                     const gp_Pnt& theP3)
4362 {
4363   myPoint1 = theP1;
4364   myPoint2 = theP2;
4365   myPoint3 = theP3;
4366 }
4367
4368 void Triangle::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
4369                        const Handle(Prs3d_Presentation)& thePresentation,
4370                        const Standard_Integer /*theMode*/)
4371 {
4372   thePresentation->Clear();
4373
4374   BRepBuilderAPI_MakeEdge anEdgeMaker1(myPoint1, myPoint2),
4375                           anEdgeMaker2(myPoint2, myPoint3),
4376                           anEdgeMaker3(myPoint3, myPoint1);
4377
4378   TopoDS_Edge anEdge1 = anEdgeMaker1.Edge(),
4379               anEdge2 = anEdgeMaker2.Edge(),
4380               anEdge3 = anEdgeMaker3.Edge();
4381   if(anEdge1.IsNull() || anEdge2.IsNull() || anEdge3.IsNull())
4382     return;
4383
4384   BRepBuilderAPI_MakeWire aWireMaker(anEdge1, anEdge2, anEdge3);
4385   TopoDS_Wire aWire = aWireMaker.Wire();
4386   if(aWire.IsNull()) return;
4387
4388   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
4389   TopoDS_Face aFace = aFaceMaker.Face();
4390   if(aFace.IsNull()) return;
4391
4392   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
4393 }
4394
4395 void Triangle::ComputeSelection(const Handle(SelectMgr_Selection)& theSelection, 
4396                                 const Standard_Integer /*theMode*/)
4397 {
4398   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
4399   Handle(Select3D_SensitiveTriangle) aSensTriangle = 
4400     new Select3D_SensitiveTriangle(anEntityOwner, myPoint1, myPoint2, myPoint3);
4401   theSelection->Add(aSensTriangle);
4402 }
4403
4404 //===========================================================================
4405 //function : VTriangle 
4406 //Draw arg : vtriangle Name PointName PointName PointName
4407 //purpose  : creates and displays Triangle
4408 //===========================================================================
4409
4410 //function: IsPoint
4411 //purpose : checks if the object with theName is AIS_Point, 
4412 //          if yes initialize thePoint from MapOfAIS
4413 Standard_Boolean IsPoint (const TCollection_AsciiString& theName,
4414                           Handle(AIS_Point)& thePoint)
4415 {
4416   Handle(AIS_InteractiveObject) anObject = 
4417     Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(theName));
4418   if(anObject.IsNull() || 
4419      anObject->Type() != AIS_KOI_Datum || 
4420      anObject->Signature() != 1)
4421   {
4422     return Standard_False;
4423   }
4424   thePoint = Handle(AIS_Point)::DownCast(anObject);
4425   if(thePoint.IsNull())
4426     return Standard_False;
4427   return Standard_True;
4428 }
4429
4430 //function: IsMatch
4431 //purpose: checks if thePoint1 is equal to thePoint2
4432 Standard_Boolean IsMatch (const Handle(Geom_CartesianPoint)& thePoint1,
4433                           const Handle(Geom_CartesianPoint)& thePoint2)
4434 {
4435   if(Abs(thePoint1->X()-thePoint2->X()) <= Precision::Confusion() &&
4436      Abs(thePoint1->Y()-thePoint2->Y()) <= Precision::Confusion() &&
4437      Abs(thePoint1->Z()-thePoint2->Z()) <= Precision::Confusion())
4438   {
4439     return Standard_True;
4440   }
4441   return Standard_False;
4442 }
4443
4444 static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
4445                                    Standard_Integer argc,
4446                                    const char ** argv)
4447 {
4448   // Check arguments
4449   if (argc != 5)
4450   {
4451     std::cout<<"vtriangle error: expects 4 argumnets\n";
4452     return 1; // TCL_ERROR
4453   }
4454
4455   TheAISContext()->CloseAllContexts();
4456
4457   // Get and check values
4458   TCollection_AsciiString aName(argv[1]);
4459
4460   Handle(AIS_Point) aPoint1, aPoint2, aPoint3;
4461   if (!IsPoint(argv[2], aPoint1))
4462   {
4463     std::cout<<"vtriangle error: the 2nd argument must be a point\n";
4464     return 1; // TCL_ERROR
4465   }
4466   if (!IsPoint(argv[3], aPoint2))
4467   {
4468     std::cout<<"vtriangle error: the 3d argument must be a point\n";
4469     return 1; // TCL_ERROR
4470   }
4471   if (!IsPoint(argv[4], aPoint3))
4472   {
4473     std::cout<<"vtriangle error: the 4th argument must be a point\n";
4474     return 1; // TCL_ERROR
4475   }
4476
4477   // Check that points are different
4478   Handle(Geom_CartesianPoint) aCartPoint1 = 
4479     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4480   Handle(Geom_CartesianPoint) aCartPoint2 = 
4481     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4482   // Test aPoint1 = aPoint2
4483   if (IsMatch(aCartPoint1, aCartPoint2))
4484   {
4485     std::cout<<"vtriangle error: the 1st and the 2nd points are equal\n";
4486     return 1; // TCL_ERROR
4487   }
4488   // Test aPoint2 = aPoint3
4489   Handle(Geom_CartesianPoint) aCartPoint3 = 
4490     Handle(Geom_CartesianPoint)::DownCast(aPoint3->Component());
4491   if (IsMatch(aCartPoint2, aCartPoint3))
4492   {
4493     std::cout<<"vtriangle error: the 2nd and the 3d points are equal\n";
4494     return 1; // TCL_ERROR
4495   }
4496   // Test aPoint3 = aPoint1
4497   if (IsMatch(aCartPoint1, aCartPoint3))
4498   {
4499     std::cout<<"vtriangle error: the 1st and the 3d points are equal\n";
4500     return 1; // TCL_ERROR
4501   }
4502
4503   // Create triangle
4504   Handle(Triangle) aTriangle = new Triangle(aCartPoint1->Pnt(),
4505                                             aCartPoint2->Pnt(),
4506                                             aCartPoint3->Pnt());
4507
4508   // Check if there is an object with given name
4509   // and remove it from context
4510   if (GetMapOfAIS().IsBound2(aName))
4511   {
4512     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4513     Handle(AIS_InteractiveObject) anInterObj = 
4514          Handle(AIS_InteractiveObject)::DownCast(anObj);
4515     TheAISContext()->Remove(anInterObj, Standard_False);
4516     GetMapOfAIS().UnBind2(aName);
4517   }
4518
4519   // Bind triangle to its name
4520   GetMapOfAIS().Bind(aTriangle, aName);
4521
4522   // Display triangle
4523   TheAISContext()->Display(aTriangle);
4524   return 0;
4525 }
4526
4527 //class  : SegmentObject
4528 //purpose: creates segment based on AIS_InteractiveObject.
4529 //         This class was implemented for testing Select3D_SensitiveCurve
4530 DEFINE_STANDARD_HANDLE(SegmentObject, AIS_InteractiveObject)
4531 class SegmentObject: public AIS_InteractiveObject
4532 {
4533 public:
4534   // CASCADE RTTI
4535   DEFINE_STANDARD_RTTI(SegmentObject); 
4536   SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2);
4537 protected:
4538   void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
4539                 const Handle(Prs3d_Presentation)& thePresentation,
4540                 const Standard_Integer theMode);
4541
4542   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
4543                          const Standard_Integer theMode);
4544 private:
4545   gp_Pnt myPoint1;
4546   gp_Pnt myPoint2;
4547 };
4548 IMPLEMENT_STANDARD_HANDLE(SegmentObject, AIS_InteractiveObject)
4549 IMPLEMENT_STANDARD_RTTIEXT(SegmentObject, AIS_InteractiveObject)
4550
4551 SegmentObject::SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2)
4552 {
4553   myPoint1 = thePnt1;
4554   myPoint2 = thePnt2;
4555 }
4556
4557 void SegmentObject::Compute (const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/,
4558                              const Handle(Prs3d_Presentation) &thePresentation,
4559                              const Standard_Integer /*theMode*/)
4560 {
4561   thePresentation->Clear();
4562   BRepBuilderAPI_MakeEdge anEdgeMaker(myPoint1, myPoint2);
4563   TopoDS_Edge anEdge = anEdgeMaker.Edge();
4564   if (anEdge.IsNull())
4565     return;
4566   BRepAdaptor_Curve aCurveAdaptor(anEdge);
4567   StdPrs_Curve::Add(thePresentation, aCurveAdaptor, myDrawer);
4568 }
4569
4570 void SegmentObject::ComputeSelection (const Handle(SelectMgr_Selection) &theSelection,
4571                                       const Standard_Integer /*theMode*/)
4572 {
4573   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
4574   Handle(TColgp_HArray1OfPnt) anArray = new TColgp_HArray1OfPnt(1, 2);
4575   anArray->SetValue(1, myPoint1);
4576   anArray->SetValue(2, myPoint2);
4577   Handle(Select3D_SensitiveCurve) aSensCurve = 
4578     new Select3D_SensitiveCurve(anOwner, anArray);
4579   theSelection->Add(aSensCurve);
4580 }
4581
4582 //=======================================================================
4583 //function  : VSegment
4584 //Draw args : vsegment Name PointName PointName
4585 //purpose   : creates and displays Segment
4586 //=======================================================================
4587 static Standard_Integer VSegment (Draw_Interpretor& /*di*/,
4588                                   Standard_Integer argc,
4589                                   const char ** argv)
4590 {
4591   // Check arguments
4592   if(argc!=4)
4593   {
4594     std::cout<<"vsegment error: expects 3 arguments\n";
4595     return 1; // TCL_ERROR
4596   }
4597
4598   TheAISContext()->CloseAllContexts();
4599
4600   // Get and check arguments
4601   TCollection_AsciiString aName(argv[1]);
4602   Handle(AIS_Point) aPoint1, aPoint2;
4603   if (!IsPoint(argv[2], aPoint1))
4604   {
4605     std::cout<<"vsegment error: the 2nd argument should be a point\n";
4606     return 1; // TCL_ERROR
4607   }
4608   if (!IsPoint(argv[3], aPoint2))
4609   {
4610     std::cout<<"vsegment error: the 3d argument should be a point\n";
4611     return 1; // TCL_ERROR
4612   }
4613   //Check that points are different
4614   Handle(Geom_CartesianPoint) aCartPoint1 = 
4615     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4616   Handle(Geom_CartesianPoint) aCartPoint2 = 
4617     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4618   if(IsMatch(aCartPoint1, aCartPoint2))
4619   {
4620     std::cout<<"vsegment error: equal points\n";
4621     return 1; // TCL_ERROR
4622   }
4623   
4624   // Create segment
4625   Handle(SegmentObject) aSegment = new SegmentObject(aCartPoint1->Pnt(), aCartPoint2->Pnt());
4626   // Check if there is an object with given name
4627   // and remove it from context
4628   if (GetMapOfAIS().IsBound2(aName))
4629   {
4630     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4631     Handle(AIS_InteractiveObject) anInterObj = 
4632          Handle(AIS_InteractiveObject)::DownCast(anObj);
4633     TheAISContext()->Remove(anInterObj, Standard_False);
4634     GetMapOfAIS().UnBind2(aName);
4635   }
4636
4637   // Bind segment to its name
4638   GetMapOfAIS().Bind(aSegment, aName);
4639
4640   // Display segment
4641   TheAISContext()->Display(aSegment);
4642   return 0;
4643 }
4644
4645 //=======================================================================
4646 //function : VObjZLayer
4647 //purpose  : Set or get z layer id for presentable object
4648 //=======================================================================
4649
4650 static Standard_Integer VObjZLayer (Draw_Interpretor& di,
4651                                     Standard_Integer argc,
4652                                     const char ** argv)
4653 {
4654   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4655   if (aContext.IsNull())
4656   {
4657     di << argv[0] << "Call 'vinit' before!\n";
4658     return 1;
4659   }
4660
4661   // get operation
4662   TCollection_AsciiString aOperation;
4663   if (argc >= 2)
4664     aOperation = TCollection_AsciiString (argv [1]);
4665
4666   // check for correct arguments
4667   if (!(argc == 4 && aOperation.IsEqual ("set")) &&
4668       !(argc == 3 && aOperation.IsEqual ("get")))
4669   {
4670     di << "Usage : " << argv[0] << " set/get object [layerid]\n";
4671     di << " set - set layer id for interactive object, layerid - z layer id\n";
4672     di << " get - get layer id of interactive object\n";
4673     di << " argument layerid should be passed for set operation only\n";
4674     return 1;
4675   }
4676
4677   // find object
4678   TCollection_AsciiString aName (argv[2]);
4679   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4680   if (!aMap.IsBound2 (aName))
4681   {
4682     di << "Use 'vdisplay' before" << "\n";
4683     return 1;
4684   }
4685
4686   // find interactive object
4687   Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
4688   Handle(AIS_InteractiveObject) anInterObj =
4689     Handle(AIS_InteractiveObject)::DownCast (anObj);
4690   if (anInterObj.IsNull())
4691   {
4692     di << "Not an AIS interactive object!\n";
4693     return 1;
4694   }
4695
4696   // process operation
4697   if (aOperation.IsEqual ("set"))
4698   {
4699     Standard_Integer aLayerId = Draw::Atoi (argv [3]);
4700     aContext->SetZLayer (anInterObj, aLayerId);
4701   }
4702   else if (aOperation.IsEqual ("get"))
4703   {
4704     di << "Z layer id: " << aContext->GetZLayer (anInterObj);
4705   }
4706   
4707   return 0;
4708 }
4709
4710 //=======================================================================
4711 //function : VPolygonOffset
4712 //purpose  : Set or get polygon offset parameters
4713 //=======================================================================
4714 static Standard_Integer VPolygonOffset(Draw_Interpretor& /*di*/,
4715                                        Standard_Integer argc,
4716                                        const char ** argv)
4717 {
4718   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4719   if (aContext.IsNull())
4720   {
4721     std::cout << argv[0] << " Call 'vinit' before!\n";
4722     return 1;
4723   }
4724
4725   if (argc > 2 && argc != 5)
4726   {
4727     std::cout << "Usage : " << argv[0] << " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
4728       "without arguments prints the default values" << std::endl;
4729     return 1;
4730   }
4731
4732   // find object
4733   Handle(AIS_InteractiveObject) anInterObj;
4734   if (argc >= 2)
4735   {
4736     TCollection_AsciiString aName (argv[1]);
4737     ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4738     if (!aMap.IsBound2 (aName))
4739     {
4740       std::cout << "Use 'vdisplay' before" << std::endl;
4741       return 1;
4742     }
4743
4744     // find interactive object
4745     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
4746     anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
4747     if (anInterObj.IsNull())
4748     {
4749       std::cout << "Not an AIS interactive object!" << std::endl;
4750       return 1;
4751     }
4752   }
4753
4754   Standard_Integer aMode;
4755   Standard_ShortReal    aFactor, aUnits;
4756   if (argc == 5)
4757   {
4758     aMode   = Draw::Atoi(argv[2]);
4759     aFactor = (Standard_ShortReal) Draw::Atof(argv[3]);
4760     aUnits  = (Standard_ShortReal) Draw::Atof(argv[4]);
4761
4762     anInterObj->SetPolygonOffsets(aMode, aFactor, aUnits);
4763     aContext->UpdateCurrentViewer();
4764     return 0;
4765   }
4766   else if (argc == 2)
4767   {
4768     if (anInterObj->HasPolygonOffsets())
4769     {
4770       anInterObj->PolygonOffsets(aMode, aFactor, aUnits);
4771       std::cout << "Current polygon offset parameters for " << argv[1] << ":" << std::endl;
4772       std::cout << "\tMode: "   << aMode   << std::endl;
4773       std::cout << "\tFactor: " << aFactor << std::endl;
4774       std::cout << "\tUnits: "  << aUnits  << std::endl;
4775       return 0;
4776     }
4777     else
4778     {
4779       std::cout << "Specific polygon offset parameters are not set for " << argv[1] << std::endl;
4780     }
4781   }
4782
4783   std::cout << "Default polygon offset parameters:" << std::endl;
4784   aContext->DefaultDrawer()->ShadingAspect()->Aspect()->PolygonOffsets(aMode, aFactor, aUnits);
4785   std::cout << "\tMode: "   << aMode   << std::endl;
4786   std::cout << "\tFactor: " << aFactor << std::endl;
4787   std::cout << "\tUnits: "  << aUnits  << std::endl;
4788
4789   return 0;
4790 }
4791
4792 //=======================================================================
4793 //function : VShowFaceBoundaries
4794 //purpose  : Set face boundaries drawing on/off for ais object
4795 //=======================================================================
4796 static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/,
4797                                            Standard_Integer argc,
4798                                            const char ** argv)
4799 {
4800   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext ();
4801   if (aContext.IsNull ())
4802   {
4803     std::cout << argv[0] << " Call 'vinit' before!\n";
4804     return 1;
4805   }
4806
4807   if ((argc != 3 && argc < 6) || argc > 8)
4808   {
4809     std::cout << "Usage :\n " << argv[0]
4810               << " ObjectName isOn [R G B [LineWidth [LineStyle]]]\n"
4811               << "   ObjectName - name of AIS interactive object. \n"
4812               << "                if ObjectName = \"\", then set as default\n"
4813               << "                settings for all newly displayed objects\n"
4814               << "   isOn       - flag indicating whether the boundaries\n"
4815               << "                should be turned on or off (can be set\n"
4816               << "                to 0 (off) or 1 (on)).\n"
4817               << "   R, G, B    - red, green and blue components of boundary\n"
4818               << "                color in range (0 - 255).\n"
4819               << "                (default is (0, 0, 0)\n"
4820               << "   LineWidth  - line width\n"
4821               << "                (default is 1)\n"
4822               << "   LineStyle  - line fill style :\n"
4823               << "                 0 - solid  \n"
4824               << "                 1 - dashed \n"
4825               << "                 2 - dot    \n"
4826               << "                 3 - dashdot\n"
4827               << "                 (default is solid)";
4828     return 1;
4829   }
4830
4831   TCollection_AsciiString aName (argv[1]);
4832
4833   Quantity_Parameter aRed      = 0.0;
4834   Quantity_Parameter aGreen    = 0.0;
4835   Quantity_Parameter aBlue     = 0.0;
4836   Standard_Real      aWidth    = 1.0;
4837   Aspect_TypeOfLine  aLineType = Aspect_TOL_SOLID;
4838   
4839   // find object
4840   Handle(AIS_InteractiveObject) anInterObj;
4841
4842   // if name is empty - apply attributes for default aspect
4843   if (!aName.IsEmpty ())
4844   {
4845     ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS ();
4846     if (!aMap.IsBound2 (aName))
4847     {
4848       std::cout << "Use 'vdisplay' on " << aName << " before" << std::endl;
4849       return 1;
4850     }
4851
4852     // find interactive object
4853     Handle(Standard_Transient) anObj = GetMapOfAIS ().Find2 (aName);
4854     anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
4855     if (anInterObj.IsNull ())
4856     {
4857       std::cout << "Not an AIS interactive object!" << std::endl;
4858       return 1;
4859     }
4860   }
4861   
4862   const Handle(Prs3d_Drawer)& aDrawer = (aName.IsEmpty ()) ?
4863     TheAISContext ()->DefaultDrawer () : anInterObj->Attributes ();
4864
4865   // turn boundaries on/off
4866   Standard_Boolean isBoundaryDraw = (Draw::Atoi (argv[2]) == 1);
4867   aDrawer->SetFaceBoundaryDraw (isBoundaryDraw);
4868   
4869   // set boundary line color
4870   if (argc >= 6)
4871   {
4872     // Text color
4873     aRed   = Draw::Atof (argv[3])/255.;
4874     aGreen = Draw::Atof (argv[4])/255.;
4875     aBlue  = Draw::Atof (argv[5])/255.;
4876   }
4877
4878   // set line width
4879   if (argc >= 7)
4880   {
4881     aWidth = (Standard_Real)Draw::Atof (argv[6]);
4882   }
4883
4884   // select appropriate line type
4885   if (argc == 8)
4886   {
4887     switch (Draw::Atoi (argv[7]))
4888     {
4889       case 1: aLineType = Aspect_TOL_DASH;    break;
4890       case 2: aLineType = Aspect_TOL_DOT;     break;
4891       case 3: aLineType = Aspect_TOL_DOTDASH; break;
4892       default:
4893         aLineType = Aspect_TOL_SOLID;
4894     }
4895   }
4896
4897   Quantity_Color aColor (aRed, aGreen, aBlue, Quantity_TOC_RGB);
4898
4899   Handle(Prs3d_LineAspect) aBoundaryAspect = 
4900     new Prs3d_LineAspect (aColor, aLineType, aWidth);
4901
4902   aDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
4903
4904   TheAISContext()->Redisplay (anInterObj);
4905   
4906   return 0;
4907 }
4908
4909 // This class is used for testing markers.
4910 DEFINE_STANDARD_HANDLE(ViewerTest_MarkersArrayObject, AIS_InteractiveObject)
4911 class ViewerTest_MarkersArrayObject : public AIS_InteractiveObject
4912 {
4913
4914 public:
4915
4916   ViewerTest_MarkersArrayObject (const gp_XYZ& theStartPoint,
4917                                  const Standard_Integer& thePointsOnSide,
4918                                  Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
4919   {
4920     myStartPoint = theStartPoint;
4921     myPointsOnSide = thePointsOnSide;
4922     myMarkerAspect = theMarkerAspect;
4923   }
4924
4925   DEFINE_STANDARD_RTTI(MyPArrayObject);
4926
4927 private:
4928
4929   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
4930                 const Handle(Prs3d_Presentation)& aPresentation,
4931                 const Standard_Integer aMode);
4932
4933   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
4934                          const Standard_Integer /*theMode*/);
4935
4936 protected:
4937
4938   gp_XYZ myStartPoint;
4939   Standard_Integer myPointsOnSide;
4940   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
4941 };
4942
4943 IMPLEMENT_STANDARD_HANDLE(ViewerTest_MarkersArrayObject, AIS_InteractiveObject)
4944 IMPLEMENT_STANDARD_RTTIEXT(ViewerTest_MarkersArrayObject, AIS_InteractiveObject)
4945
4946 void ViewerTest_MarkersArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
4947                               const Handle(Prs3d_Presentation)& aPresentation,
4948                               const Standard_Integer /*aMode*/)
4949 {
4950   Handle(Graphic3d_ArrayOfPrimitives) anArray = new Graphic3d_ArrayOfPoints ((Standard_Integer )Pow (myPointsOnSide, 3), myPointsOnSide != 1);
4951   if (myPointsOnSide == 1)
4952   {
4953     anArray->AddVertex (myStartPoint);
4954   }
4955   else
4956   {
4957     for (Standard_Real i = 1; i <= myPointsOnSide; i++)
4958     {
4959       for (Standard_Real j = 1; j <= myPointsOnSide; j++)
4960       {
4961         for (Standard_Real k = 1; k <= myPointsOnSide; k++)
4962         {
4963           anArray->AddVertex (myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
4964           anArray->SetVertexColor (anArray->VertexNumber(),
4965                                    i / myPointsOnSide,
4966                                    j / myPointsOnSide,
4967                                    k / myPointsOnSide);
4968         }
4969       }
4970     }
4971   }
4972
4973   aPresentation->Clear();
4974   if (!myMarkerAspect.IsNull())
4975   {
4976     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
4977   }
4978   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
4979 }
4980
4981 void ViewerTest_MarkersArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
4982                                        const Standard_Integer /*theMode*/)
4983 {
4984   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
4985
4986   if (myPointsOnSide == 1)
4987   {
4988     gp_Pnt aPoint (myStartPoint);
4989     Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
4990     theSelection->Add (aSensetivePoint);
4991   }
4992   else
4993   {
4994     for (Standard_Real i = 1; i <= myPointsOnSide; i++)
4995     {
4996       for (Standard_Real j = 1; j <= myPointsOnSide; j++)
4997       {
4998         for (Standard_Real k = 1; k <= myPointsOnSide; k++)
4999         {
5000           gp_Pnt aPoint (myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
5001           Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
5002           theSelection->Add (aSensetivePoint);
5003         }
5004       }
5005     }
5006   }
5007 }
5008 //=======================================================================
5009 //function : VMarkersTest
5010 //purpose  : Draws an array of markers for testing purposes.
5011 //=======================================================================
5012 static Standard_Integer VMarkersTest (Draw_Interpretor&,
5013                                       Standard_Integer  theArgNb,
5014                                       const char**      theArgVec)
5015 {
5016   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5017   if (aContext.IsNull())
5018   {
5019     std::cerr << "Call 'vinit' before!\n";
5020     return 1;
5021   }
5022
5023   if (theArgNb < 5)
5024   {
5025     std::cerr << "Usage :\n " << theArgVec[0]
5026               << "name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n";
5027     return 1;
5028   }
5029
5030   Standard_Integer anArgIter = 1;
5031
5032   TCollection_AsciiString aName (theArgVec[anArgIter++]);
5033   TCollection_AsciiString aFileName;
5034   gp_XYZ aPnt (Atof (theArgVec[anArgIter]),
5035                Atof (theArgVec[anArgIter + 1]),
5036                Atof (theArgVec[anArgIter + 2]));
5037   anArgIter += 3;
5038
5039   Standard_Integer aPointsOnSide = 10;
5040   Standard_Integer aMarkerType   = -1;
5041   Standard_Real    aScale        = 1.0;
5042   for (; anArgIter < theArgNb; ++anArgIter)
5043   {
5044     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
5045     if (anArg.Search ("PointsOnSide=") > -1)
5046     {
5047       aPointsOnSide = anArg.Token ("=", 2).IntegerValue();
5048     }
5049     else if (anArg.Search ("MarkerType=") > -1)
5050     {
5051       aMarkerType = anArg.Token ("=", 2).IntegerValue();
5052     }
5053     else if (anArg.Search ("Scale=") > -1)
5054     {
5055       aScale = anArg.Token ("=", 2).RealValue();
5056     }
5057     else if (anArg.Search ("FileName=") > -1)
5058     {
5059       aFileName = anArg.Token ("=", 2);
5060     }
5061     else
5062     {
5063       std::cerr << "Wrong argument: " << anArg << "\n";
5064       return 1;
5065     }
5066   }
5067
5068   Handle(Graphic3d_AspectMarker3d) anAspect;
5069   Handle(Image_AlienPixMap) anImage;
5070   Quantity_Color aColor (Quantity_NOC_GREEN1);
5071   if ((aMarkerType == Aspect_TOM_USERDEFINED || aMarkerType < 0)
5072    && !aFileName.IsEmpty())
5073   {
5074     anImage = new Image_AlienPixMap();
5075     if (!anImage->Load (aFileName))
5076     {
5077       std::cerr << "Could not load image from file '" << aFileName << "'!\n";
5078       return 1;
5079     }
5080     if (anImage->Format() == Image_PixMap::ImgGray)
5081     {
5082       anImage->SetFormat (Image_PixMap::ImgAlpha);
5083     }
5084     else if (anImage->Format() == Image_PixMap::ImgGrayF)
5085     {
5086       anImage->SetFormat (Image_PixMap::ImgAlphaF);
5087     }
5088     anAspect = new Graphic3d_AspectMarker3d (anImage);
5089   }
5090   else
5091   {
5092     anAspect = new Graphic3d_AspectMarker3d (aMarkerType >= 0 ? (Aspect_TypeOfMarker )aMarkerType : Aspect_TOM_POINT, aColor, aScale);
5093   }
5094
5095   Handle(ViewerTest_MarkersArrayObject) aMarkersArray = new ViewerTest_MarkersArrayObject (aPnt, aPointsOnSide, anAspect);
5096   VDisplayAISObject (aName, aMarkersArray);
5097
5098   return 0;
5099 }
5100
5101 //! Auxiliary function to parse font aspect style argument
5102 static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
5103                                         Font_FontAspect&               theAspect)
5104 {
5105   if (theArg == "regular"
5106    || *theArg.ToCString() == 'r')
5107   {
5108     theAspect = Font_FA_Regular;
5109     return Standard_True;
5110   }
5111   else if (theArg == "bolditalic")
5112   {
5113     theAspect = Font_FA_BoldItalic;
5114     return Standard_True;
5115   }
5116   else if (theArg == "bold"
5117         || *theArg.ToCString() == 'b')
5118   {
5119     theAspect = Font_FA_Bold;
5120     return Standard_True;
5121   }
5122   else if (theArg == "italic"
5123         || *theArg.ToCString() == 'i')
5124   {
5125     theAspect = Font_FA_Italic;
5126     return Standard_True;
5127   }
5128   return Standard_False;
5129 }
5130
5131 //! Auxiliary function
5132 static TCollection_AsciiString fontStyleString (const Font_FontAspect theAspect)
5133 {
5134   switch (theAspect)
5135   {
5136     case Font_FA_Regular:    return "regular";
5137     case Font_FA_BoldItalic: return "bolditalic";
5138     case Font_FA_Bold:       return "bold";
5139     case Font_FA_Italic:     return "italic";
5140     default:                 return "undefined";
5141   }
5142 }
5143
5144 //=======================================================================
5145 //function : TextToBrep
5146 //purpose  : Tool for conversion text to occt-shapes
5147 //=======================================================================
5148
5149 static int TextToBRep (Draw_Interpretor& /*theDI*/,
5150                        Standard_Integer  theArgNb,
5151                        const char**      theArgVec)
5152 {
5153   // Check arguments
5154   if (theArgNb < 5)
5155   {
5156     std::cerr << "Error: " << theArgVec[0] << " - invalid syntax\n";
5157     return 1;
5158   }
5159
5160   Standard_Integer    anArgIter = 1;
5161   Standard_CString    aResName  = theArgVec[anArgIter++];
5162   Standard_CString    aText     = theArgVec[anArgIter++];
5163   Standard_CString    aFontName = theArgVec[anArgIter++];
5164   const Standard_Real aSize     = Atof (theArgVec[anArgIter++]);
5165
5166   Font_BRepFont    aFont;
5167   Font_FontAspect  aFontAspect      = Font_FA_Regular;
5168   Standard_Boolean isCompositeCurve = Standard_False;
5169   gp_Ax3           aPenAx3 (gp::XOY());
5170   gp_Pnt           aPenLoc;
5171   while (anArgIter < theArgNb)
5172   {
5173     const TCollection_AsciiString anArg (theArgVec[anArgIter++]);
5174     TCollection_AsciiString anArgCase (anArg);
5175     anArgCase.LowerCase();
5176     if (anArgCase.Search ("x=") > -1)
5177     {
5178       aPenLoc.SetX (anArg.Token ("=", 2).RealValue());
5179     }
5180     else if (anArgCase.Search ("y=") > -1)
5181     {
5182       aPenLoc.SetY (anArg.Token ("=", 2).RealValue());
5183     }
5184     else if (anArgCase.Search ("z=") > -1)
5185     {
5186       aPenLoc.SetZ (anArg.Token ("=", 2).RealValue());
5187     }
5188     else if (anArgCase.Search ("composite=") > -1)
5189     {
5190       isCompositeCurve = (anArg.Token ("=", 2).IntegerValue() == 1);
5191     }
5192     else if (parseFontStyle (anArgCase, aFontAspect))
5193     {
5194       //
5195     }
5196     else
5197     {
5198       std::cerr << "Warning! Unknown argument '" << anArg.ToCString() << "'\n";
5199     }
5200   }
5201
5202   aFont.SetCompositeCurveMode (isCompositeCurve);
5203   if (!aFont.Init (aFontName, aFontAspect, aSize))
5204   {
5205     std::cerr << "Font initialization error\n";
5206     return 1;
5207   }
5208
5209   aPenAx3.SetLocation (aPenLoc);
5210   DBRep::Set (aResName, aFont.RenderText (aText, aPenAx3));
5211   return 0;
5212 }
5213
5214 //=======================================================================
5215 //function : VFont
5216 //purpose  : Font management
5217 //=======================================================================
5218
5219 static int VFont (Draw_Interpretor& theDI,
5220                   Standard_Integer  theArgNb,
5221                   const char**      theArgVec)
5222 {
5223   Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
5224   if (theArgNb < 2)
5225   {
5226     // just print the list of available fonts
5227     Standard_Boolean isFirst = Standard_True;
5228     for (Font_NListOfSystemFont::Iterator anIter (aMgr->GetAvailableFonts());
5229          anIter.More(); anIter.Next())
5230     {
5231       const Handle(Font_SystemFont)& aFont = anIter.Value();
5232       if (!isFirst)
5233       {
5234         theDI << "\n";
5235       }
5236
5237       theDI << aFont->FontName()->String()
5238             << " " << fontStyleString (aFont->FontAspect())
5239             << " " << aFont->FontPath()->String();
5240       isFirst = Standard_False;
5241     }
5242     return 0;
5243   }
5244
5245   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5246   {
5247     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
5248     TCollection_AsciiString anArgCase (anArg);
5249     anArgCase.LowerCase();
5250     if (anArgCase == "find")
5251     {
5252       if (++anArgIter >= theArgNb)
5253       {
5254         std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
5255         return 1;
5256       }
5257
5258       Standard_CString aFontName   = theArgVec[anArgIter];
5259       Font_FontAspect  aFontAspect = Font_FA_Undefined;
5260       if (++anArgIter < theArgNb)
5261       {
5262         anArgCase = theArgVec[anArgIter];
5263         anArgCase.LowerCase();
5264         if (!parseFontStyle (anArgCase, aFontAspect))
5265         {
5266           --anArgIter;
5267         }
5268       }
5269       Handle(Font_SystemFont) aFont = aMgr->FindFont (new TCollection_HAsciiString (aFontName), aFontAspect, -1);
5270       if (aFont.IsNull())
5271       {
5272         std::cerr << "Error: font '" << aFontName << "' is not found!\n";
5273         continue;
5274       }
5275
5276       theDI << aFont->FontName()->String()
5277             << " " << fontStyleString (aFont->FontAspect())
5278             << " " << aFont->FontPath()->String();
5279     }
5280     else if (anArgCase == "add"
5281           || anArgCase == "register")
5282     {
5283       if (++anArgIter >= theArgNb)
5284       {
5285         std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
5286         return 1;
5287       }
5288       Standard_CString aFontPath   = theArgVec[anArgIter];
5289       Standard_CString aFontName   = NULL;
5290       Font_FontAspect  aFontAspect = Font_FA_Undefined;
5291       if (++anArgIter < theArgNb)
5292       {
5293         if (!parseFontStyle (anArgCase, aFontAspect))
5294         {
5295           aFontName = theArgVec[anArgIter];
5296         }
5297         if (++anArgIter < theArgNb)
5298         {
5299           anArgCase = theArgVec[anArgIter];
5300           anArgCase.LowerCase();
5301           if (!parseFontStyle (anArgCase, aFontAspect))
5302           {
5303             --anArgIter;
5304           }
5305         }
5306       }
5307
5308       Handle(Font_SystemFont) aFont = aMgr->CheckFont (aFontPath);
5309       if (aFont.IsNull())
5310       {
5311         std::cerr << "Error: font '" << aFontPath << "' is not found!\n";
5312         continue;
5313       }
5314
5315       if (aFontAspect != Font_FA_Undefined
5316        || aFontName   != NULL)
5317       {
5318         if (aFontAspect == Font_FA_Undefined)
5319         {
5320           aFontAspect = aFont->FontAspect();
5321         }
5322         Handle(TCollection_HAsciiString) aName = aFont->FontName();
5323         if (aFontName != NULL)
5324         {
5325           aName = new TCollection_HAsciiString (aFontName);
5326         }
5327         aFont = new Font_SystemFont (aName, aFontAspect, new TCollection_HAsciiString (aFontPath));
5328       }
5329
5330       aMgr->RegisterFont (aFont, Standard_True);
5331       theDI << aFont->FontName()->String()
5332             << " " << fontStyleString (aFont->FontAspect())
5333             << " " << aFont->FontPath()->String();
5334     }
5335     else
5336     {
5337       std::cerr << "Warning! Unknown argument '" << anArg.ToCString() << "'\n";
5338     }
5339   }
5340
5341   return 0;
5342 }
5343
5344 //=======================================================================
5345 //function : VSetEdgeType
5346 //purpose  : Edges type management
5347 //=======================================================================
5348
5349 static int VSetEdgeType (Draw_Interpretor& theDI,
5350                          Standard_Integer  theArgNum,
5351                          const char**      theArgs)
5352 {
5353   if (theArgNum < 4 || theArgNum > 9)
5354   {
5355     theDI << theArgs[0] << " error: wrong number of parameters. Type 'help "
5356           << theArgs[0] << "' for more information.\n";
5357     return 1;
5358   }
5359
5360   Standard_Boolean isForceRedisplay = Standard_False;
5361
5362   // Get shape name
5363   TCollection_AsciiString aName(theArgs[1]);
5364   if (!GetMapOfAIS().IsBound2 (aName))
5365   {
5366     theDI <<  theArgs[0] << " error: wrong object name.\n";
5367     return 1;
5368   }
5369   
5370   Handle(AIS_InteractiveObject) anObject = 
5371     Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
5372   
5373   // Enable trianle edge mode
5374   anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeOn();
5375
5376   // Parse parameters
5377   for (Standard_Integer anIt = 2; anIt < theArgNum; ++anIt)
5378   {
5379     TCollection_AsciiString aParam ((theArgs[anIt]));
5380     if (aParam.Value (1) == '-' && !aParam.IsRealValue())
5381     {
5382       if (aParam.IsEqual ("-type"))
5383       {
5384         if (theArgNum <= anIt + 1)
5385         {
5386           theDI <<  theArgs[0] << " error: wrong number of values for parameter '"
5387                 << aParam.ToCString() << "'.\n";
5388           return 1;
5389         }
5390
5391         TCollection_AsciiString aType = theArgs[++anIt];
5392         aType.UpperCase();
5393
5394         if (aType.IsEqual ("SOLID"))
5395         {
5396           anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeLineType(Aspect_TOL_SOLID);
5397         }
5398         else if (aType.IsEqual ("DASH"))
5399         {
5400           anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeLineType(Aspect_TOL_DASH);
5401         }
5402         else if (aType.IsEqual ("DOT"))
5403         {
5404           anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeLineType(Aspect_TOL_DOT);
5405         }
5406         else if (aType.IsEqual ("DOTDASH"))
5407         {
5408           anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeLineType(Aspect_TOL_DOTDASH);
5409         }
5410         else
5411         {
5412           theDI <<  theArgs[0] << " error: wrong line type: '" << aType.ToCString() << "'.\n";
5413           return 1;
5414         }
5415         
5416       }
5417       else if (aParam.IsEqual ("-color"))
5418       {
5419         if (theArgNum <= anIt + 3)
5420         {
5421           theDI <<  theArgs[0] << " error: wrong number of values for parameter '"
5422                 << aParam.ToCString() << "'.\n";
5423           return 1;
5424         }
5425
5426         Quantity_Parameter aR = Draw::Atof(theArgs[++anIt]);
5427         Quantity_Parameter aG = Draw::Atof(theArgs[++anIt]);
5428         Quantity_Parameter aB = Draw::Atof(theArgs[++anIt]);
5429         Quantity_Color aColor = Quantity_Color (aR > 1 ? aR / 255.0 : aR,
5430                                                 aG > 1 ? aG / 255.0 : aG,
5431                                                 aB > 1 ? aB / 255.0 : aB,
5432                                                 Quantity_TOC_RGB);
5433
5434         anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeColor (aColor);
5435       }
5436       else if (aParam.IsEqual ("-force"))
5437       {
5438         isForceRedisplay = Standard_True;
5439       }
5440       else
5441       {
5442         theDI <<  theArgs[0] << " error: unknown parameter '"
5443               << aParam.ToCString() << "'.\n";
5444         return 1;
5445       }
5446     }
5447   }
5448
5449   // Update shape presentation as aspect parameters were changed
5450   if (isForceRedisplay)
5451   {
5452     ViewerTest::GetAISContext()->Redisplay (anObject);
5453   }
5454   else
5455   {
5456     anObject->SetAspect (anObject->Attributes()->ShadingAspect());
5457   }
5458
5459   //Update view
5460   ViewerTest::CurrentView()->Redraw();
5461
5462   return 0;
5463 }
5464
5465 //=======================================================================
5466 //function : VUnsetEdgeType
5467 //purpose  : Unsets edges visibility in shading mode
5468 //=======================================================================
5469
5470 static int VUnsetEdgeType (Draw_Interpretor& theDI,
5471                          Standard_Integer  theArgNum,
5472                          const char**      theArgs)
5473 {
5474   if (theArgNum != 2 && theArgNum != 3)
5475   {
5476     theDI << theArgs[0] << " error: wrong number of parameters. Type 'help "
5477           << theArgs[0] << "' for more information.\n";
5478     return 1;
5479   }
5480
5481   Standard_Boolean isForceRedisplay = Standard_False;
5482
5483   // Get shape name
5484   TCollection_AsciiString aName (theArgs[1]);
5485   if (!GetMapOfAIS().IsBound2 (aName))
5486   {
5487     theDI <<  theArgs[0] << " error: wrong object name.\n";
5488     return 1;
5489   }
5490
5491   Handle(AIS_InteractiveObject) anObject = 
5492     Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(aName));
5493
5494   // Enable trianle edge mode
5495   anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeOff();
5496
5497   // Parse parameters
5498   if (theArgNum == 3)
5499   {
5500     TCollection_AsciiString aParam ((theArgs[2]));
5501     if (aParam.IsEqual ("-force"))
5502     {
5503       isForceRedisplay = Standard_True;
5504     }
5505     else
5506     {
5507        theDI <<  theArgs[0] << " error: unknown parameter '"
5508               << aParam.ToCString() << "'.\n";
5509        return 1;
5510     }
5511   }
5512
5513   // Update shape presentation as aspect parameters were changed
5514   if (isForceRedisplay)
5515   {
5516     ViewerTest::GetAISContext()->Redisplay (anObject);
5517   }
5518   else
5519   {
5520     anObject->SetAspect (anObject->Attributes()->ShadingAspect());
5521   }
5522
5523   //Update view
5524   ViewerTest::CurrentView()->Redraw();
5525
5526   return 0;
5527 }
5528
5529
5530 //=======================================================================
5531 //function : VVertexMode
5532 //purpose  : Switches vertex display mode for AIS_Shape or displays the current value
5533 //=======================================================================
5534
5535 static int VVertexMode (Draw_Interpretor& theDI,
5536                          Standard_Integer  theArgNum,
5537                          const char**      theArgs)
5538 {
5539   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5540   if (aContext.IsNull())
5541   {
5542     std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
5543     return 1;
5544   }
5545
5546   // No arguments --> print the current default vertex draw mode
5547   if (theArgNum == 1)
5548   {
5549     Prs3d_VertexDrawMode aCurrMode = aContext->DefaultDrawer()->VertexDrawMode();
5550     theDI <<  "Default vertex draw mode: " << (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
5551     return 0;
5552   }
5553
5554   // -set argument --> change the default vertex draw mode and the mode for all displayed or given object(s)
5555   TCollection_AsciiString aParam (theArgs[1]);
5556   if (aParam == "-set")
5557   {
5558     if (theArgNum == 2)
5559     {
5560       std::cout << "Error: '-set' option not followed by the mode and optional object name(s)" << std::endl;
5561       std::cout << "Type 'help vvertexmode' for usage hints" << std::endl;
5562       return 1;
5563     }
5564
5565     TCollection_AsciiString aModeStr (theArgs[2]);
5566     Prs3d_VertexDrawMode aNewMode =
5567        aModeStr == "isolated" ? Prs3d_VDM_Isolated :
5568       (aModeStr == "all"      ? Prs3d_VDM_All :
5569                                 Prs3d_VDM_Inherited);
5570
5571     Standard_Boolean aRedrawNeeded = Standard_False;
5572     AIS_ListOfInteractive anObjs;
5573
5574     // No object(s) specified -> use all displayed
5575     if (theArgNum == 3)
5576     {
5577       theDI << "Setting the default vertex draw mode and updating all displayed objects...\n";
5578       aContext->DisplayedObjects (anObjs);
5579       aContext->DefaultDrawer()->SetVertexDrawMode (aNewMode);
5580       aRedrawNeeded = Standard_True;
5581     }
5582
5583     Handle(AIS_InteractiveObject) anObject;
5584     for (Standard_Integer aCount = 3; aCount < theArgNum; aCount++)
5585     {
5586       TCollection_AsciiString aName (theArgs[aCount]);
5587       if (!GetMapOfAIS().IsBound2 (aName))
5588       {
5589         theDI << "Warning: wrong object name ignored - " << theArgs[0] << "\n";
5590         continue;
5591       }
5592       anObject = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(aName));
5593       anObjs.Append (anObject);
5594     }
5595
5596     for (AIS_ListIteratorOfListOfInteractive anIt (anObjs); anIt.More(); anIt.Next())
5597     {
5598       anObject = anIt.Value();
5599       anObject->Attributes()->SetVertexDrawMode (aNewMode);
5600       aContext->Redisplay (anObject, Standard_False);
5601       aRedrawNeeded = Standard_True;
5602     }
5603
5604     if (aRedrawNeeded)
5605       ViewerTest::CurrentView()->Redraw();
5606
5607     return 0;
5608   }
5609
5610   if (theArgNum > 2)
5611   {
5612     std::cout << "Error: invalid number of arguments" << std::endl;
5613     std::cout << "Type 'help vvertexmode' for usage hints" << std::endl;
5614     return 1;
5615   }
5616
5617   // One argument (object name) --> print the current vertex draw mode for the object
5618   Handle(AIS_InteractiveObject) anObject =
5619     Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aParam));
5620   Prs3d_VertexDrawMode aCurrMode = anObject->Attributes()->VertexDrawMode();
5621   theDI <<  "Object's vertex draw mode: " << (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
5622   return 0;
5623 }
5624
5625 //=======================================================================
5626 //function : VPointCloud
5627 //purpose  : Create interactive object for arbitary set of points.
5628 //=======================================================================
5629 static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
5630                                      Standard_Integer  theArgNum,
5631                                      const char**      theArgs)
5632 {
5633   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5634   if (anAISContext.IsNull())
5635   {
5636     std::cerr << "Error: no active view!\n";
5637     return 1;
5638   }
5639
5640   // command to execute
5641   enum Command
5642   {
5643     CloudForShape, // generate point cloud for shape
5644     CloudSphere,   // generate point cloud for generic sphere
5645     Unknow
5646   };
5647
5648   // count number of non-optional command arguments
5649   Command aCmd = Unknow;
5650   Standard_Integer aCmdArgs = 0;
5651   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
5652   {
5653     Standard_CString anArg = theArgs[anArgIter];
5654     TCollection_AsciiString aFlag (anArg);
5655     aFlag.LowerCase();
5656     if (aFlag.IsRealValue() || aFlag.Search ("-") != 1)
5657     {
5658       aCmdArgs++;
5659     }
5660   }
5661   switch (aCmdArgs)
5662   {
5663     case 2  : aCmd = CloudForShape; break;
5664     case 7  : aCmd = CloudSphere; break;
5665     default :
5666       std::cout << "Error: wrong number of arguments! See usage:\n";
5667       theDI.PrintHelp (theArgs[0]);
5668       return 1;
5669   }
5670
5671   // parse options
5672   Standard_Boolean toRandColors = Standard_False;
5673   Standard_Boolean hasNormals   = Standard_True;
5674   Standard_Boolean isSetArgNorm = Standard_False;
5675   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
5676   {
5677     Standard_CString anArg = theArgs[anArgIter];
5678     TCollection_AsciiString aFlag (anArg);
5679     aFlag.LowerCase();
5680     if (aFlag == "-randcolors"
5681      || aFlag == "-randcolor")
5682     {
5683       if (isSetArgNorm && hasNormals)
5684       {
5685         std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
5686         return 1;
5687       }
5688       toRandColors = Standard_True;
5689       hasNormals   = Standard_False;
5690     }
5691     else if (aFlag == "-normals"
5692           || aFlag == "-normal")
5693     {
5694       if (toRandColors)
5695       {
5696         std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
5697         return 1;
5698       }
5699       isSetArgNorm = Standard_True;
5700       hasNormals   = Standard_True;
5701     }
5702     else if (aFlag == "-nonormals"
5703           || aFlag == "-nonormal")
5704     {
5705       isSetArgNorm = Standard_True;
5706       hasNormals   = Standard_False;
5707     }
5708   }
5709
5710   Standard_CString aName = theArgs[1];
5711
5712   // generate arbitrary set of points
5713   Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
5714   if (aCmd == CloudForShape)
5715   {
5716     Standard_CString aShapeName = theArgs[2];
5717     TopoDS_Shape     aShape     = DBRep::Get (aShapeName);
5718
5719     if (aShape.IsNull())
5720     {
5721       std::cout << "Error: no shape with name '" << aShapeName << "' found\n";
5722       return 1;
5723     }
5724
5725     // calculate number of points
5726     TopLoc_Location  aLocation;
5727     Standard_Integer aNbPoints = 0;
5728     for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
5729     {
5730       const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
5731       Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation);
5732       if (!aTriangulation.IsNull())
5733       {
5734         aNbPoints += aTriangulation->NbNodes();
5735       }
5736     }
5737     if (aNbPoints < 3)
5738     {
5739       std::cout << "Error: shape should be triangulated!\n";
5740       return 1;
5741     }
5742
5743     anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
5744     for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
5745     {
5746       const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
5747       Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation);
5748       if (aTriangulation.IsNull())
5749       {
5750         continue;
5751       }
5752
5753       const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
5754       const gp_Trsf&            aTrsf  = aLocation.Transformation();
5755
5756       // extract normals from nodes
5757       TColgp_Array1OfDir aNormals (aNodes.Lower(), hasNormals ? aNodes.Upper() : aNodes.Lower());
5758       if (hasNormals)
5759       {
5760         Poly_Connect aPolyConnect (aTriangulation);
5761         StdPrs_ToolShadedShape::Normal (aFace, aPolyConnect, aNormals);
5762       }
5763
5764       for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
5765       {
5766         gp_Pnt aPoint = aNodes (aNodeIter);
5767         if (!aLocation.IsIdentity())
5768         {
5769           aPoint.Transform (aTrsf);
5770           if (hasNormals)
5771           {
5772             aNormals (aNodeIter).Transform (aTrsf);
5773           }
5774         }
5775
5776         // add vertex into array of points
5777         const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
5778         if (toRandColors)
5779         {
5780           Quantity_Color aColor (360.0 * Standard_Real(anIndexOfPoint) / Standard_Real(aNbPoints),
5781                                  1.0, 0.5, Quantity_TOC_HLS);
5782           anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
5783         }
5784
5785         if (hasNormals)
5786         {
5787           anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter));
5788         }
5789       }
5790     }
5791   }
5792   else if (aCmd == CloudSphere)
5793   {
5794     Standard_Real aCenterX       = Draw::Atof (theArgs[2]);
5795     Standard_Real aCenterY       = Draw::Atof (theArgs[3]);
5796     Standard_Real aCenterZ       = Draw::Atof (theArgs[4]);
5797     Standard_Real aRadius        = Draw::Atof (theArgs[5]);
5798     Standard_Integer aNbPoints   = Draw::Atoi (theArgs[6]);
5799
5800     TCollection_AsciiString aDistribution = TCollection_AsciiString(theArgs[7]);
5801     aDistribution.LowerCase();
5802     if ( aDistribution != "surface" && aDistribution != "volume" )
5803     {
5804       std::cout << "Error: wrong arguments! See usage:\n";
5805       theDI.PrintHelp (theArgs[0]);
5806       return 1;
5807     }
5808     Standard_Boolean isSurface = aDistribution == "surface";
5809
5810     gp_Pnt aCenter(aCenterX, aCenterY, aCenterZ);
5811
5812     anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
5813     for (Standard_Integer aPntIt = 0; aPntIt < aNbPoints; ++aPntIt)
5814     {
5815       Standard_Real anAlpha   = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
5816       Standard_Real aBeta     = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
5817       Standard_Real aDistance = isSurface ?
5818         aRadius : (Standard_Real (rand() % aNbPoints) / aNbPoints) * aRadius;
5819
5820       gp_Dir aDir (Cos (anAlpha) * Sin (aBeta),
5821                    Sin (anAlpha),
5822                    Cos (anAlpha) * Cos (aBeta));
5823       gp_Pnt aPoint = aCenter.Translated (aDir.XYZ() * aDistance);
5824
5825       const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
5826       if (toRandColors)
5827       {
5828         Quantity_Color aColor (360.0 * Standard_Real (anIndexOfPoint) / Standard_Real (aNbPoints),
5829                                1.0, 0.5, Quantity_TOC_HLS);
5830         anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
5831       }
5832
5833       if (hasNormals)
5834       {
5835         anArrayPoints->SetVertexNormal (anIndexOfPoint, aDir);
5836       }
5837     }
5838   }
5839
5840   // set array of points in point cloud object
5841   Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud();
5842   aPointCloud->SetPoints (anArrayPoints);
5843   VDisplayAISObject (aName, aPointCloud);
5844   return 0;
5845 }
5846
5847 //=======================================================================
5848 //function : VPriority
5849 //purpose  : Prints or sets the display priority for an object
5850 //=======================================================================
5851
5852 static int VPriority (Draw_Interpretor& theDI,
5853                       Standard_Integer  theArgNum,
5854                       const char**      theArgs)
5855 {
5856   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5857   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
5858   if (aContext.IsNull())
5859   {
5860     std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
5861     return 1;
5862   }
5863
5864   TCollection_AsciiString aLastArg (theArgs[theArgNum - 1]);
5865   Standard_Integer aPriority = -1;
5866   Standard_Integer aNbArgs   = theArgNum;
5867   if (aLastArg.IsIntegerValue())
5868   {
5869     aPriority = aLastArg.IntegerValue();
5870     --aNbArgs;
5871     if (aPriority < 0 || aPriority > 10)
5872     {
5873       std::cout << "Error: the specified display priority value '" << aLastArg
5874                 << "' is outside the valid range [0..10]" << std::endl;
5875       return 1;
5876     }
5877   }
5878   else
5879   {
5880     anUpdateTool.Invalidate();
5881   }
5882
5883   if (aNbArgs < 2)
5884   {
5885     std::cout << "Error: wrong number of arguments! See usage:\n";
5886     theDI.PrintHelp (theArgs[0]);
5887     return 1;
5888   }
5889
5890   for (Standard_Integer anArgIter = 1; anArgIter < aNbArgs; ++anArgIter)
5891   {
5892     if (anUpdateTool.parseRedrawMode (theArgs[anArgIter]))
5893     {
5894       continue;
5895     }
5896
5897     TCollection_AsciiString aName (theArgs[anArgIter]);
5898     Handle(AIS_InteractiveObject) anIObj;
5899     if (GetMapOfAIS().IsBound2 (aName))
5900     {
5901       anIObj = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
5902     }
5903
5904     if (anIObj.IsNull())
5905     {
5906       std::cout << "Error: the object '" << theArgs[1] << "' is not displayed" << std::endl;
5907       return 1;
5908     }
5909
5910     if (aPriority < 1)
5911     {
5912       theDI << aContext->DisplayPriority (anIObj) << " ";
5913     }
5914     else
5915     {
5916       aContext->SetDisplayPriority (anIObj, aPriority);
5917     }
5918   }
5919   return 0;
5920 }
5921
5922 //=======================================================================
5923 //function : ObjectsCommands
5924 //purpose  :
5925 //=======================================================================
5926
5927 void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
5928 {
5929   const char *group ="AISObjects";
5930   theCommands.Add("vtrihedron",
5931     "vtrihedron         : vtrihedron name [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw] ",
5932     __FILE__,VTrihedron,group);
5933
5934   theCommands.Add("vtri2d",
5935     "vtri2d Name Selection in the viewer only ",
5936     __FILE__,VTrihedron2D ,group);
5937
5938   theCommands.Add("vplanetri",
5939     "vplanetri Name Selection in the viewer only ",
5940     __FILE__,VPlaneTrihedron ,group);
5941
5942   theCommands.Add("vsize",
5943     "vsize       : vsize [name(Default=Current)] [size(Default=100)] ",
5944     __FILE__,VSize,group);
5945
5946   theCommands.Add("vaxis",
5947     "vaxis nom [Xa] [Ya] [Za] [Xb] [Yb] [Zb]",
5948     __FILE__,VAxisBuilder,group);
5949
5950   theCommands.Add("vaxispara",
5951     "vaxispara  nom ",
5952     __FILE__,VAxisBuilder,group);
5953
5954   theCommands.Add("vaxisortho",
5955     "vaxisotho  nom ",
5956     __FILE__,VAxisBuilder,group);
5957
5958   theCommands.Add("vpoint",
5959     "vpoint  PointName [Xa] [Ya] [Za] ",
5960     __FILE__,VPointBuilder,group);
5961
5962   theCommands.Add("vplane",
5963     "vplane  PlaneName [AxisName/PlaneName/PointName] [PointName/PointName/PointName] [Nothing/Nothing/PointName] [TypeOfSensitivity]",
5964     __FILE__,VPlaneBuilder,group);
5965
5966   theCommands.Add ("vchangeplane", "vchangeplane usage: \n"
5967     "   vchangeplane <plane_name>"
5968     " [x=center_x y=center_y z=center_z]"
5969     " [dx=dir_x dy=dir_y dz=dir_z]"
5970     " [sx=size_x sy=size_y]"
5971     " [noupdate]\n"
5972     "   - changes parameters of the plane:\n"
5973     "   - x y z     - center\n"
5974     "   - dx dy dz  - normal\n"
5975     "   - sx sy     - plane sizes\n"
5976     "   - noupdate  - do not update/redisplay the plane in context\n"
5977     "   Please enter coordinates in format \"param=value\" in arbitrary order.",
5978     __FILE__, VChangePlane, group);
5979
5980   theCommands.Add("vplanepara",
5981     "vplanepara  PlaneName  ",
5982     __FILE__,VPlaneBuilder,group);
5983
5984   theCommands.Add("vplaneortho",
5985     "vplaneortho  PlaneName  ",
5986     __FILE__,VPlaneBuilder,group);
5987
5988   theCommands.Add("vline",
5989     "vline: vline LineName [Xa/PointName] [Ya/PointName] [Za] [Xb] [Yb] [Zb]  ",
5990     __FILE__,VLineBuilder,group);
5991
5992   theCommands.Add("vcircle",
5993     "vcircle CircleName [PointName PointName PointName IsFilled]\n\t\t\t\t\t[PlaneName PointName Radius IsFilled]",
5994     __FILE__,VCircleBuilder,group);
5995
5996   theCommands.Add ("vdrawtext",
5997                    "vdrawtext name text"
5998                    "\n\t\t: [-pos X=0 Y=0 Z=0]"
5999                    "\n\t\t: [-color {R G B|name}=yellow]"
6000                    "\n\t\t: [-halign {left|center|right}=left]"
6001                    "\n\t\t: [-valign {top|center|bottom}=bottom}]"
6002                    "\n\t\t: [-angle angle=0]"
6003                    "\n\t\t: [-zoom {0|1}=0]"
6004                    "\n\t\t: [-height height=16]"
6005                    "\n\t\t: [-aspect {regular|bold|italic|bolditalic}=regular]"
6006                    "\n\t\t: [-font font=Times]"
6007                    "\n\t\t: [-noupdate]"
6008                    "\n\t\t: Display text label at specified position.",
6009     __FILE__, VDrawText, group);
6010
6011   theCommands.Add("vdrawsphere",
6012     "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]\n",
6013     __FILE__,VDrawSphere,group);
6014
6015   theCommands.Add ("vsetlocation",
6016                    "vsetlocation [-noupdate|-update] name x y z"
6017                    "\n\t\t: Set new location for an interactive object.",
6018         __FILE__, VSetLocation, group);
6019
6020   theCommands.Add (
6021     "vcomputehlr",
6022     "vcomputehlr: shape hlrname [ eyex eyey eyez lookx looky lookz ]",
6023     __FILE__, VComputeHLR, group);
6024
6025   theCommands.Add("vdrawparray",
6026     "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id ]",
6027     __FILE__,VDrawPArray,group);
6028
6029   theCommands.Add("vconnect", 
6030     "vconnect : assembly_name Xo Yo Zo object1 object2 ..."
6031     "  Makes an assembly of object instances located in point (Xo Yo Zo).",
6032     __FILE__, VConnect, group);
6033
6034   theCommands.Add("vconnectto",
6035     "vconnectto : instance_name Xo Yo Zo object [-nodisplay|-noupdate|-update]"
6036     "  Makes an instance 'instance_name' of 'object' with position (Xo Yo Zo)."
6037     "\n\t\t:   -nodisplay - only creates interactive object, but not displays it",
6038     __FILE__, VConnectTo,group);
6039
6040   theCommands.Add("vdisconnect",
6041     "vdisconnect assembly_name (object_name | object_number | 'all')"
6042     "  Disconnects all objects from assembly or disconnects object by name or number (use vlistconnected to enumerate assembly children).",
6043     __FILE__,VDisconnect,group);
6044
6045   theCommands.Add("vaddconnected",
6046     "vaddconnected assembly_name object_name"
6047     "Adds object to assembly.",
6048     __FILE__,VAddConnected,group);
6049
6050   theCommands.Add("vlistconnected",
6051     "vlistconnected assembly_name"
6052     "Lists objects in assembly.",
6053     __FILE__,VListConnected,group);
6054
6055
6056   theCommands.Add("vselmode", 
6057     "vselmode : [object] mode_number is_turned_on=(1|0)\n"
6058     "  switches selection mode for the determined object or\n"
6059     "  for all objects in context.\n"
6060     "  mode_number is non-negative integer that has different\n"
6061     "    meaning for different interactive object classes.\n"
6062     "    For shapes the following mode_number values are allowed:\n"
6063     "      0 - shape\n"
6064     "      1 - vertex\n"
6065     "      2 - edge\n"
6066     "      3 - wire\n"
6067     "      4 - face\n"
6068     "      5 - shell\n"
6069     "      6 - solid\n"
6070     "      7 - compsolid\n"
6071     "      8 - compound\n"
6072     "  is_turned_on is:\n"
6073     "    1 if mode is to be switched on\n"
6074     "    0 if mode is to be switched off\n", 
6075     __FILE__, VSetSelectionMode, group);
6076
6077   theCommands.Add("vselnext",
6078     "vselnext : hilight next detected",
6079     __FILE__, VSelectionNext, group);
6080
6081   theCommands.Add("vselprev",
6082     "vselnext : hilight previous detected",
6083     __FILE__, VSelectionPrevious, group);
6084
6085   theCommands.Add("vtriangle",
6086     "vtriangle Name PointName PointName PointName", 
6087     __FILE__, VTriangle,group);
6088
6089   theCommands.Add("vsegment",
6090     "vsegment Name PointName PointName", 
6091     __FILE__, VSegment,group);
6092
6093   theCommands.Add("vobjzlayer",
6094     "vobjzlayer : set/get object [layerid] - set or get z layer id for the interactive object",
6095     __FILE__, VObjZLayer, group);
6096   
6097   theCommands.Add("vpolygonoffset",
6098     "vpolygonoffset : [object [mode factor units]] - sets/gets polygon offset parameters for an object, without arguments prints the default values",
6099     __FILE__, VPolygonOffset, group);
6100
6101   theCommands.Add ("vshowfaceboundary",
6102     "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]]"
6103     "- turns on/off drawing of face boundaries for ais object "
6104     "and defines boundary line style.",
6105     __FILE__, VShowFaceBoundary, group);
6106
6107   theCommands.Add ("vmarkerstest",
6108                    "vmarkerstest: name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n",
6109                    __FILE__, VMarkersTest, group);
6110
6111   theCommands.Add ("text2brep",
6112                    "text2brep: res text fontName fontSize [x=0.0 y=0.0 z=0.0 composite=1 {regular,bold,italic,bolditalic=regular}]\n",
6113                    __FILE__, TextToBRep, group);
6114   theCommands.Add ("vfont",
6115                             "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]"
6116                    "\n\t\t:        [find fontName [regular,bold,italic,bolditalic=undefined]]",
6117                    __FILE__, VFont, group);
6118   
6119   theCommands.Add ("vsetedgetype",
6120                    "vsetedgetype usage:\n"
6121                    "vsetedgetype ShapeName [-force] [-type {solid, dash, dot}] [-color R G B] "
6122                    "\n\t\t:        Sets edges type and color for input shape",
6123                    __FILE__, VSetEdgeType, group);
6124
6125   theCommands.Add ("vunsetedgetype",
6126                    "vunsetedgetype usage:\n"
6127                    "vunsetedgetype ShapeName [-force]"
6128                    "\n\t\t:        Unsets edges type and color for input shape",
6129                    __FILE__, VUnsetEdgeType, group);
6130
6131   theCommands.Add ("vvertexmode",
6132                    "vvertexmode [name | -set {isolated | all | inherited} [name1 name2 ...]]\n"
6133                    "vvertexmode - prints the default vertex draw mode\n"
6134                    "vvertexmode name - prints the vertex draw mode of the given object\n"
6135                    "vvertexmode -set {isolated | all | inherited} - sets the default vertex draw mode and updates the mode for all displayed objects\n"
6136                    "vvertexmode -set {isolated | all | inherited} name1 name2 ... - sets the vertex draw mode for the specified object(s)\n",
6137                    __FILE__, VVertexMode, group);
6138
6139   theCommands.Add ("vpointcloud",
6140                    "vpointcloud name shape [-randColor] [-normals] [-noNormals]"
6141                    "\n\t\t: Create an interactive object for arbitary set of points"
6142                    "\n\t\t: from triangulated shape."
6143                    "\n"
6144                    "vpointcloud name x y z r npts {surface|volume}\n"
6145                    "            ... [-randColor] [-normals] [-noNormals]"
6146                    "\n\t\t: Create arbitrary set of points (npts) randomly distributed"
6147                    "\n\t\t: on spheric surface or within spheric volume (x y z r)."
6148                    "\n\t\t:"
6149                    "\n\t\t: Additional options:"
6150                    "\n\t\t:  -randColor - generate random color per point"
6151                    "\n\t\t:  -normals   - generate normal per point (default)"
6152                    "\n\t\t:  -noNormals - do not generate normal per point"
6153                    "\n",
6154                    __FILE__, VPointCloud, group);
6155
6156   theCommands.Add("vlocreset",
6157     "vlocreset name1 name2 ...\n\t\t  remove object local transformation",
6158     __FILE__,
6159     LocalTransformPresentation, group);
6160
6161   theCommands.Add("vlocmove",
6162     "vlocmove name1 name2 ... name\n\t\t  set local transform to match transform of 'name'",
6163     __FILE__,
6164     LocalTransformPresentation, group);
6165
6166   theCommands.Add("vloctranslate",
6167     "vloctranslate name1 name2 ... dx dy dz\n\t\t  applies translation to local transformation",
6168     __FILE__,
6169     LocalTransformPresentation, group);
6170
6171   theCommands.Add("vlocrotate",
6172     "vlocrotate name1 name2 ... x y z dx dy dz angle\n\t\t  applies rotation to local transformation",
6173     __FILE__,
6174     LocalTransformPresentation, group);
6175
6176   theCommands.Add("vlocmirror",
6177     "vlocmirror name x y z dx dy dz\n\t\t  applies mirror to local transformation",
6178     __FILE__,
6179     LocalTransformPresentation, group);
6180
6181   theCommands.Add("vlocscale",
6182     "vlocscale name x y z scale\n\t\t  applies scale to local transformation",
6183     __FILE__,
6184     LocalTransformPresentation, group);
6185
6186   theCommands.Add("vpriority",
6187     "vpriority [-noupdate|-update] name [value]\n\t\t  prints or sets the display priority for an object",
6188     __FILE__,
6189     VPriority, group);
6190 }