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