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