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