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