8e05ff422d8851f1ef8f2a0e3fd94a552302c0d3
[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 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif
20
21 #include <ViewerTest.hxx>
22
23 #include <string.h>
24
25 #include <Quantity_NameOfColor.hxx>
26 #include <Draw_Interpretor.hxx>
27 #include <Draw.hxx>
28 #include <Draw_Appli.hxx>
29 #include <DBRep.hxx>
30
31 #include <Font_BRepFont.hxx>
32 #include <Font_FontMgr.hxx>
33 #include <OSD_Chronometer.hxx>
34 #include <TCollection_AsciiString.hxx>
35 #include <Visual3d_View.hxx>
36 #include <V3d_Viewer.hxx>
37 #include <V3d_View.hxx>
38 #include <V3d.hxx>
39
40 #include <AIS_Shape.hxx>
41 #include <AIS_DisplayMode.hxx>
42 #include <TColStd_MapOfInteger.hxx>
43 #include <AIS_MapOfInteractive.hxx>
44 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
45 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
46 #include <ViewerTest_EventManager.hxx>
47
48 #include <TopoDS_Solid.hxx>
49 #include <BRepTools.hxx>
50 #include <BRep_Builder.hxx>
51 #include <TopAbs_ShapeEnum.hxx>
52
53 #include <TopoDS.hxx>
54 #include <BRep_Tool.hxx>
55 #include <TopExp_Explorer.hxx>
56
57 #include <BRepAdaptor_Curve.hxx>
58 #include <BRepAdaptor_Surface.hxx>
59
60 #include <TopAbs.hxx>
61 #include <TopExp.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Face.hxx>
65
66 #include <Draw_Window.hxx>
67 #include <AIS_ListIteratorOfListOfInteractive.hxx>
68 #include <AIS_ListOfInteractive.hxx>
69 #include <AIS_DisplayMode.hxx>
70 #include <AIS_Shape.hxx>
71
72 #include <AIS_InteractiveContext.hxx>
73 #include <Geom_Plane.hxx>
74 #include <gp_Pln.hxx>
75 #include <TCollection_ExtendedString.hxx>
76 #include <TCollection_HAsciiString.hxx>
77 #include <GC_MakePlane.hxx>
78 #include <gp_Circ.hxx>
79 #include <AIS_Axis.hxx>
80 #include <Geom_Axis2Placement.hxx>
81 #include <Geom_Axis1Placement.hxx>
82 #include <AIS_Trihedron.hxx>
83 #include <AIS_Axis.hxx>
84 #include <gp_Trsf.hxx>
85 #include <TopLoc_Location.hxx>
86
87 #include <HLRAlgo_Projector.hxx>
88 #include <HLRBRep_PolyAlgo.hxx>
89 #include <HLRBRep_PolyHLRToShape.hxx>
90 #include <Aspect_Window.hxx>
91
92 #include <Graphic3d_ArrayOfPoints.hxx>
93 #include <Graphic3d_ArrayOfSegments.hxx>
94 #include <Graphic3d_ArrayOfPolylines.hxx>
95 #include <Graphic3d_ArrayOfTriangles.hxx>
96 #include <Graphic3d_ArrayOfTriangleFans.hxx>
97 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
98 #include <Graphic3d_ArrayOfQuadrangles.hxx>
99 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
100 #include <Graphic3d_ArrayOfPolygons.hxx>
101 #include <Graphic3d_AspectMarker3d.hxx>
102 #include <Graphic3d_Group.hxx>
103 #include <Standard_Real.hxx>
104
105 #include <AIS_Circle.hxx>
106 #include <AIS_Drawer.hxx>
107 #include <BRepBuilderAPI_MakeEdge.hxx>
108 #include <BRepBuilderAPI_MakeFace.hxx>
109 #include <BRepBuilderAPI_MakeWire.hxx>
110 #include <Geom_Circle.hxx>
111 #include <GC_MakeCircle.hxx>
112 #include <Prs3d_Presentation.hxx>
113 #include <Select3D_SensitiveCircle.hxx>
114 #include <SelectMgr_EntityOwner.hxx>
115 #include <SelectMgr_Selection.hxx>
116 #include <StdFail_NotDone.hxx>
117 #include <StdPrs_ShadedShape.hxx>
118 #include <TopoDS_Wire.hxx>
119
120 #include <AIS_ConnectedShape.hxx>
121 #include <AIS_MultipleConnectedInteractive.hxx>
122 #include <AIS_MultipleConnectedShape.hxx>
123 #include <TopLoc_Location.hxx>
124 #include <TColStd_ListOfInteger.hxx>
125 #include <TColStd_ListIteratorOfListOfInteger.hxx>
126
127 #include <Select3D_SensitiveTriangle.hxx>
128 #include <Select3D_SensitiveCurve.hxx>
129 #include <Select3D_SensitivePoint.hxx>
130 #include <BRepAdaptor_Curve.hxx>
131 #include <StdPrs_Curve.hxx>
132
133 #include <BRepExtrema_ExtPC.hxx>
134 #include <BRepExtrema_ExtPF.hxx>
135
136 #include <Prs3d_VertexDrawMode.hxx>
137 #include <Prs3d_LineAspect.hxx>
138 #include <Prs3d_PointAspect.hxx>
139
140 #include <Image_AlienPixMap.hxx>
141 #include <TColStd_HArray1OfAsciiString.hxx>
142
143 #ifdef HAVE_STRINGS_H
144 #include <strings.h>
145 #endif
146
147 #ifdef WNT
148 #define _CRT_SECURE_NO_DEPRECATE
149 #pragma warning (disable:4996)
150 #endif
151
152 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
153 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
154                                            const Handle(AIS_InteractiveObject)& theAISObj,
155                                            Standard_Boolean theReplaceIfExists = Standard_True);
156 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
157 extern Handle(AIS_InteractiveContext)& TheAISContext();
158
159
160 //==============================================================================
161 //function : Vtrihedron 2d
162 //purpose  : Create a plane with a 2D  trihedron from a faceselection
163 //Draw arg : vtri2d  name
164 //==============================================================================
165 #include <AIS_PlaneTrihedron.hxx>
166
167
168
169 static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
170
171 {
172   // Verification des arguments
173   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
174
175   // Declarations
176   Standard_Integer myCurrentIndex;
177   // Fermeture des contextes
178   TheAISContext()->CloseAllContexts();
179   // Ouverture d'un contexte local et recuperation de son index.
180   TheAISContext()->OpenLocalContext();
181   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
182   // On active les modes de selections faces.
183   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
184   di<<" Select a face ."<<"\n";
185
186   // Boucle d'attente waitpick.
187   Standard_Integer argccc = 5;
188   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
189   const char **argvvv = (const char **) bufff;
190   while (ViewerMainLoop( argccc, argvvv) ) { }
191   // fin de la boucle
192
193   TopoDS_Shape ShapeB;
194   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
195     ShapeB = TheAISContext()->SelectedShape();
196   }
197
198   TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
199
200   // Construction du Plane
201   // recuperation des edges des faces.
202   TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
203
204   TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
205   // declarations
206   gp_Pnt A,B,C;
207
208   // si il y a plusieurs edges
209   if (FaceExpB.More() ) {
210     FaceExpB.Next();
211     TopoDS_Edge EdgeC=TopoDS::Edge(FaceExpB.Current() );
212     BRepAdaptor_Curve theCurveB(EdgeB);
213     BRepAdaptor_Curve theCurveC(EdgeC);
214     A=theCurveC.Value(0.1);
215     B=theCurveC.Value(0.9);
216     C=theCurveB.Value(0.5);
217   }
218   else {
219     // FaceB a 1 unique edge courbe
220     BRepAdaptor_Curve theCurveB(EdgeB);
221     A=theCurveB.Value(0.1);
222     B=theCurveB.Value(0.9);
223     C=theCurveB.Value(0.5);
224   }
225   // Construction du Geom_Plane
226   GC_MakePlane MkPlane(A,B,C);
227   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
228
229   // Construction de l'AIS_PlaneTrihedron
230   Handle(AIS_PlaneTrihedron) theAISPlaneTri= new AIS_PlaneTrihedron(theGeomPlane );
231
232   // Fermeture du contexte local.
233   TheAISContext()->CloseLocalContext(myCurrentIndex);
234
235   // on le display & bind
236   TheAISContext()->Display(theAISPlaneTri );
237   GetMapOfAIS().Bind ( theAISPlaneTri ,argv[1]);
238
239   return 0;
240 }
241
242
243
244 //==============================================================================
245 //function : VTriherdron
246 //purpose  : Create a trihedron. If no arguments are set, the default
247 //           trihedron (Oxyz) is created.
248 //Draw arg : vtrihedron  name  [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw]
249 //==============================================================================
250
251 static int VTrihedron (Draw_Interpretor& theDi,
252                        Standard_Integer  theArgsNb,
253                        const char**      theArgVec)
254 {
255   if (theArgsNb != 2 && theArgsNb != 5 && theArgsNb != 11)
256   {
257     theDi << theArgVec[0] << " Syntax error\n";
258     return 1;
259   }
260
261   gp_Pnt anOrigin (0.0, 0.0, 0.0);
262   gp_Dir aDirZ = gp::DZ();
263   gp_Dir aDirX = gp::DX();
264   Standard_Integer anArgIter = 2; // 1st is an IO name
265   if (anArgIter < theArgsNb)
266   {
267     anOrigin.SetX (Draw::Atof (theArgVec[anArgIter++]));
268     anOrigin.SetY (Draw::Atof (theArgVec[anArgIter++]));
269     anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter++]));
270     if (anArgIter < theArgsNb)
271     {
272       Standard_Real aX = Draw::Atof (theArgVec[anArgIter++]);
273       Standard_Real aY = Draw::Atof (theArgVec[anArgIter++]);
274       Standard_Real aZ = Draw::Atof (theArgVec[anArgIter++]);
275       aDirZ.SetCoord (aX, aY, aZ);
276
277       aX = Draw::Atof (theArgVec[anArgIter++]);
278       aY = Draw::Atof (theArgVec[anArgIter++]);
279       aZ = Draw::Atof (theArgVec[anArgIter++]);
280       aDirX.SetCoord (aX, aY, aZ);
281     }
282   }
283
284   if (!aDirZ.IsNormal (aDirX, M_PI / 180.0))
285   {
286     theDi << theArgVec[0] << " - VectorX is not normal to VectorZ\n";
287     return 1;
288   }
289
290   Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (anOrigin, aDirZ, aDirX);
291   Handle(AIS_Trihedron) aShape = new AIS_Trihedron (aPlacement);
292   VDisplayAISObject (theArgVec[1], aShape);
293   return 0;
294 }
295
296 //==============================================================================
297 //function : VSize
298 //author   : ege
299 //purpose  : Change the size of a named or selected trihedron
300 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
301 //           if no value, the value is set at 100 by default
302 //Draw arg : vsize [name] [size]
303 //==============================================================================
304
305 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
306
307 {
308   // Declaration de booleens
309   Standard_Boolean             ThereIsName;
310   Standard_Boolean             ThereIsCurrent;
311   Standard_Real                value;
312   Standard_Boolean             hascol;
313
314   Quantity_NameOfColor         col = Quantity_NOC_BLACK ;
315
316   // Verification des arguments
317   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error"<<"\n"; return 1;}
318
319   // Verification du nombre d'arguments
320   if (argc==1)      {ThereIsName=Standard_False;value=100;}
321   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
322   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
323
324   // On ferme le contexte local pour travailler dans le contexte global
325   if(TheAISContext()->HasOpenedContext())
326     TheAISContext()->CloseLocalContext();
327
328   // On set le booleen ThereIsCurrent
329   if (TheAISContext() -> NbCurrents() > 0) {ThereIsCurrent=Standard_True;}
330   else {ThereIsCurrent=Standard_False;}
331
332
333
334   //===============================================================
335   // Il n'y a pas de nom  mais des objets selectionnes
336   //===============================================================
337   if (!ThereIsName && ThereIsCurrent)
338   {
339
340     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
341       it (GetMapOfAIS());
342
343     while ( it.More() ) {
344
345       Handle(AIS_InteractiveObject) aShape=
346         Handle(AIS_InteractiveObject)::DownCast(it.Key1());
347
348       if (!aShape.IsNull() &&  TheAISContext()->IsCurrent(aShape) )
349       {
350
351         // On verifie que l'AIS InteraciveObject selectionne est bien
352         // un AIS_Trihedron
353         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
354
355           if (aShape->HasColor()) {
356             hascol=Standard_True;
357
358             // On recupere la couleur de aShape
359             col=aShape->Color();}
360
361           else hascol=Standard_False;
362
363           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
364           // pour lui appliquer la methode SetSize()
365           Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
366
367           // C'est bien un triedre,on chage sa valeur!
368           aTrihedron->SetSize(value);
369
370           // On donne la couleur au Trihedron
371           if(hascol)   aTrihedron->SetColor(col);
372           else         aTrihedron->UnsetColor();
373
374
375           // The trihedron hasn't be errased from the map
376           // so you just have to redisplay it
377           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
378
379         }
380
381       }
382
383       it.Next();
384     }
385
386     TheAISContext() ->UpdateCurrentViewer();
387   }
388
389   //===============================================================
390   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
391   //===============================================================
392
393
394
395   //===============================================================
396   // Il y a un nom de triedre passe en argument
397   //===============================================================
398   if (ThereIsName) {
399     TCollection_AsciiString name=argv[1];
400
401     // on verifie que ce nom correspond bien a une shape
402     Standard_Boolean IsBound= GetMapOfAIS().IsBound2(name);
403
404     if (IsBound) {
405
406       // on recupere la shape dans la map des objets displayes
407       Handle(AIS_InteractiveObject) aShape =
408         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
409
410       // On verifie que l'AIS InteraciveObject est bien
411       // un AIS_Trihedron
412       if (!aShape.IsNull() &&
413         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
414       {
415
416         if (aShape->HasColor()) {
417           hascol=Standard_True;
418
419           // On recupere la couleur de aShape
420           col=aShape->Color();}
421
422         else hascol=Standard_False;
423
424         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
425         // pour lui appliquer la methode SetSize()
426         Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
427
428         // C'est bien un triedre,on chage sa valeur
429         aTrihedron->SetSize(value);
430
431         // On donne la couleur au Trihedron
432         if(hascol)   aTrihedron->SetColor(col);
433         else         aTrihedron->UnsetColor();
434
435         // The trihedron hasn't be errased from the map
436         // so you just have to redisplay it
437         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
438
439         TheAISContext() ->UpdateCurrentViewer();
440       }
441     }
442   }
443   return 0;
444 }
445
446
447 //==============================================================================
448
449 //==============================================================================
450 //function : VPlaneTrihedron
451 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
452 //Draw arg : vplanetri  name
453 //==============================================================================
454 #include <AIS_Plane.hxx>
455
456
457
458 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
459
460 {
461   // Verification des arguments
462   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
463
464   // Declarations
465   Standard_Integer myCurrentIndex;
466   // Fermeture des contextes locaux
467   TheAISContext()->CloseAllContexts();
468
469   // On recupere tous les trihedrons de la GetMapOfAIS()
470   // et on active le mode de selection par face.
471   // =================================================
472
473   // Ouverture d'un contexte local et recuperation de son index.
474   TheAISContext()->OpenLocalContext(Standard_False);
475   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
476
477   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
478     it (GetMapOfAIS());
479   while(it.More()){
480     Handle(AIS_InteractiveObject) ShapeA =
481       Handle(AIS_InteractiveObject)::DownCast(it.Key1());
482     // On verifie que c'est bien un trihedron
483     if (!ShapeA.IsNull() &&
484       ShapeA->Type()==AIS_KOI_Datum  && ShapeA->Signature()==3  ) {
485         // on le downcast
486         Handle(AIS_Trihedron) TrihedronA =((*(Handle(AIS_Trihedron)*)&ShapeA));
487         // on le charge dans le contexte et on active le mode Plane.
488         TheAISContext()->Load(TrihedronA,0,Standard_False);
489         TheAISContext()->Activate(TrihedronA,3);
490       }
491       it.Next();
492   }
493
494   di<<" Select a plane."<<"\n";
495   // Boucle d'attente waitpick.
496   Standard_Integer argccc = 5;
497   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
498   const char **argvvv = (const char **) bufff;
499   while (ViewerMainLoop( argccc, argvvv) ) { }
500   // fin de la boucle
501
502   Handle(AIS_InteractiveObject) theIOB;
503   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
504     theIOB = TheAISContext()->Interactive();
505   }
506   // on le downcast
507   Handle(AIS_Plane) PlaneB =((*(Handle(AIS_Plane)*)&theIOB));
508
509   // Fermeture du contexte local.
510   TheAISContext()->CloseLocalContext(myCurrentIndex);
511
512   // on le display & bind
513   TheAISContext()->Display(PlaneB );
514   GetMapOfAIS().Bind ( PlaneB ,argv[1]);
515
516   return 0;
517 }
518
519
520
521 //==============================================================================
522 // Fonction        First click      2de click
523 //
524 // vaxis           vertex           vertex
525 //                 edge             None
526 // vaxispara       edge             vertex
527 // vaxisortho      edge             Vertex
528 // vaxisinter      Face             Face
529 //==============================================================================
530
531 //==============================================================================
532 //function : VAxisBuilder
533 //purpose  :
534 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
535 //==============================================================================
536 #include <TopoDS_Edge.hxx>
537 #include <TopoDS_Vertex.hxx>
538 #include <TopExp.hxx>
539 #include <Geom_Line.hxx>
540
541 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
542 {
543   // Declarations
544   Standard_Boolean HasArg;
545   TCollection_AsciiString name;
546   Standard_Integer MyCurrentIndex;
547
548   // Verification
549   if (argc<2 || argc>8 ) {di<<" Syntaxe error"<<"\n";return 1;}
550   if (argc==8) HasArg=Standard_True;
551   else HasArg=Standard_False;
552
553   name=argv[1];
554   // Fermeture des contextes
555   TheAISContext()->CloseAllContexts();
556
557   // Cas ou il y a des arguments
558   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
559   if (HasArg) {
560     Standard_Real coord[6];
561     for(Standard_Integer i=0;i<=5;i++){
562       coord[i]=Draw::Atof(argv[2+i]);
563     }
564     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
565
566     gp_Vec myVect (p1,p2);
567     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
568     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
569     GetMapOfAIS().Bind (TheAxis,name);
570     TheAISContext()->Display(TheAxis);
571   }
572
573   // Pas d'arguments
574   else {
575     // fonction vaxis
576     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
577     if ( !strcasecmp(argv[0], "vaxis")) {
578       TheAISContext()->OpenLocalContext();
579       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
580
581       // Active le mode edge et le mode vertex
582       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
583       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
584       di<<" Select an edge or a vertex."<<"\n";
585
586       // Boucle d'attente waitpick.
587       Standard_Integer argcc = 5;
588       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
589       const char **argvv = (const char **) buff;
590       while (ViewerMainLoop( argcc, argvv) ) { }
591       // fin de la boucle
592
593       // recuperation de la shape.
594       TopoDS_Shape ShapeA;
595       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
596         ShapeA = TheAISContext()->SelectedShape();
597       }
598       // recuperation de l'AIS_InteractiveObject
599       //Handle(AIS_InteractiveObject) myAISio=TheAISContext()->Current();
600       // down cast en AIS_Point si sig et type
601       // AIS_Point -> Geom_Pnt ....
602
603       if (ShapeA.ShapeType()==TopAbs_VERTEX) {
604         // on desactive le mode edge
605         TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
606         di<<" Select a different vertex."<<"\n";
607
608         TopoDS_Shape ShapeB;
609         do {
610           // Boucle d'attente waitpick.
611           Standard_Integer argccc = 5;
612           const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
613           const char **argvvv = (const char **) bufff;
614           while (ViewerMainLoop( argccc, argvvv) ) { }
615           // fin de la boucle
616           for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
617             ShapeB = TheAISContext()->SelectedShape();
618           }
619
620
621         } while(ShapeB.IsSame(ShapeA) );
622
623         // Fermeture du context local
624         TheAISContext()->CloseLocalContext(MyCurrentIndex);
625
626         // Construction de l'axe
627         gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
628         gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
629         gp_Vec   V (A,B);
630         gp_Dir   D (V);
631         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
632         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
633         GetMapOfAIS().Bind (TheAxis,name);
634         TheAISContext()->Display(TheAxis);
635       }
636       else {
637         // Un unique edge (ShapeA) a ete picke
638         // Fermeture du context local
639         TheAISContext()->CloseLocalContext(MyCurrentIndex);
640         // Constuction de l'axe
641         TopoDS_Edge    ed =TopoDS::Edge(ShapeA);
642         TopoDS_Vertex  Va,Vb;
643         TopExp::Vertices(ed,Va,Vb );
644         gp_Pnt A=BRep_Tool::Pnt(Va);
645         gp_Pnt B=BRep_Tool::Pnt(Vb);
646         gp_Vec  V (A,B);
647         gp_Dir   D (V);
648         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
649         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
650         GetMapOfAIS().Bind (TheAxis,name);
651         TheAISContext()->Display(TheAxis);
652       }
653
654     }
655
656     // Fonction axispara
657     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
658     else if ( !strcasecmp(argv[0], "vaxispara")) {
659
660       TheAISContext()->OpenLocalContext();
661       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
662
663       // Active le mode edge
664       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
665       di<<" Select an edge."<<"\n";
666
667       // Boucle d'attente waitpick.
668       Standard_Integer argcc = 5;
669       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
670       const char **argvv = (const char **) buff;
671       while (ViewerMainLoop( argcc, argvv) ) { }
672       // fin de la boucle
673
674       TopoDS_Shape ShapeA;
675       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
676         ShapeA = TheAISContext()->SelectedShape();
677       }
678       // Active le mode vertex et deactive edges
679       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
680       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
681       di<<" Select a vertex."<<"\n";
682
683       // Boucle d'attente waitpick.
684       Standard_Integer argccc = 5;
685       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
686       const char **argvvv = (const char **) bufff;
687       while (ViewerMainLoop( argccc, argvvv) ) { }
688       // fin de la boucle
689
690       // On peut choisir un pnt sur l'edge
691       TopoDS_Shape ShapeB;
692       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
693         ShapeB = TheAISContext()->SelectedShape();
694       }
695       // Fermeture du context local
696       TheAISContext()->CloseLocalContext(MyCurrentIndex);
697
698       // Construction de l'axe
699       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
700       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
701       TopoDS_Vertex  Va,Vc;
702       TopExp::Vertices(ed,Va,Vc );
703       gp_Pnt A=BRep_Tool::Pnt(Va);
704       gp_Pnt C=BRep_Tool::Pnt(Vc);
705       gp_Vec  V (A,C);
706       gp_Dir   D (V);
707       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
708       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
709       GetMapOfAIS().Bind (TheAxis,name);
710       TheAISContext()->Display(TheAxis);
711
712     }
713
714     // Fonction axisortho
715     else  {
716       TheAISContext()->OpenLocalContext();
717       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
718
719       // Active le mode edge
720       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
721       di<<" Select an edge."<<"\n";
722
723       // Boucle d'attente waitpick.
724       Standard_Integer argcc = 5;
725       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
726       const char **argvv = (const char **) buff;
727       while (ViewerMainLoop( argcc, argvv) ) { }
728       // fin de la boucle
729
730       TopoDS_Shape ShapeA;
731       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
732         ShapeA = TheAISContext()->SelectedShape();
733       }
734       // Active le mode vertex et deactive edges
735       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
736       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
737       di<<" Slect a vertex."<<"\n";
738
739       // Boucle d'attente waitpick.
740       Standard_Integer argccc = 5;
741       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
742       const char **argvvv = (const char **) bufff;
743       while (ViewerMainLoop( argccc, argvvv) ) { }
744       // fin de la boucle
745
746       // On peut choisir un pnt sur l'edge
747       TopoDS_Shape ShapeB;
748       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
749         ShapeB = TheAISContext()->SelectedShape();
750       }
751       // Fermeture du context local
752       TheAISContext()->CloseLocalContext(MyCurrentIndex);
753
754       // Construction de l'axe
755       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
756       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
757       TopoDS_Vertex  Va,Vc;
758       TopExp::Vertices(ed,Va,Vc );
759       gp_Pnt A=BRep_Tool::Pnt(Va);
760       gp_Pnt C=BRep_Tool::Pnt(Vc);
761       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
762       gp_Vec  V (A,E);
763       gp_Dir   D (V);
764       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
765       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
766       GetMapOfAIS().Bind (TheAxis,name);
767       TheAISContext()->Display(TheAxis);
768
769     }
770
771   }
772   return 0;
773 }
774
775
776 //==============================================================================
777 // Fonction        First click      Result
778 //
779 // vpoint          vertex           AIS_Point=Vertex
780 //                 edge             AIS_Point=Middle of the edge
781 //==============================================================================
782
783 //==============================================================================
784 //function : VPointBuilder
785 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
786 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
787 //==============================================================================
788 #include <TopoDS_Edge.hxx>
789 #include <TopoDS_Vertex.hxx>
790 #include <TopExp.hxx>
791 #include <AIS_Point.hxx>
792 #include <Geom_CartesianPoint.hxx>
793
794 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
795 {
796   // Declarations
797   Standard_Boolean HasArg;
798   TCollection_AsciiString name;
799   Standard_Integer myCurrentIndex;
800
801   // Verification
802   if (argc<2 || argc>5 ) {di<<" Syntaxe error"<<"\n";return 1;}
803   if (argc==5) HasArg=Standard_True;
804   else HasArg=Standard_False;
805
806   name=argv[1];
807   // Fermeture des contextes
808   TheAISContext()->CloseAllContexts();
809
810   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
811   if (HasArg) {
812     Standard_Real thecoord[3];
813     for(Standard_Integer i=0;i<=2;i++)
814       thecoord[i]=Draw::Atof(argv[2+i]);
815     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
816     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
817     GetMapOfAIS().Bind (myAISPoint,name);
818     TheAISContext()->Display(myAISPoint);
819   }
820
821   // Il n'a pas d'arguments
822   else {
823     TheAISContext()->OpenLocalContext();
824     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
825
826     // Active le mode Vertex et Edges
827     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
828     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
829     di<<" Select a vertex or an edge(build the middle)"<<"\n";
830
831     // Boucle d'attente waitpick.
832     Standard_Integer argcc = 5;
833     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
834     const char **argvv = (const char **) buff;
835     while (ViewerMainLoop( argcc, argvv) ) { }
836     // fin de la boucle
837
838     TopoDS_Shape ShapeA;
839     for (TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
840       ShapeA= TheAISContext()->SelectedShape();
841     }
842
843     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
844       // Un vertex a ete selectionne
845       // Fermeture du context local
846       TheAISContext()->CloseLocalContext(myCurrentIndex);
847
848       // Construction du point
849       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) );
850       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
851       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
852       GetMapOfAIS().Bind(myAISPoint,name);
853       TheAISContext()->Display(myAISPoint);
854     }
855     else {
856       // Un Edge a ete selectionne
857       // Fermeture du context local
858       TheAISContext()->CloseLocalContext(myCurrentIndex);
859
860       // Construction du point milieu de l'edge
861       TopoDS_Edge myEdge=TopoDS::Edge(ShapeA);
862       TopoDS_Vertex myVertexA,myVertexB;
863       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
864       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
865       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
866       // M est le milieu de [AB]
867       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
868       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
869       GetMapOfAIS().Bind(myAISPointM,name);
870       TheAISContext()->Display(myAISPointM);
871     }
872
873   }
874   return 0;
875
876 }
877
878 //==============================================================================
879 // Function        1st click   2de click  3de click
880 // vplane          Vertex      Vertex     Vertex
881 //                 Vertex      Edge
882 //                 Edge        Vertex
883 //                 Face
884 // vplanepara      Face        Vertex
885 //                 Vertex      Face
886 // vplaneortho     Face        Edge
887 //                 Edge        Face
888 //==============================================================================
889
890 //==============================================================================
891 //function : VPlaneBuilder
892 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
893 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
894 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
895 //                            [PlaneName] [PointName] [TypeOfSensitivity]
896 //==============================================================================
897
898 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
899                                        Standard_Integer argc,
900                                        const char** argv)
901 {
902   // Declarations
903   Standard_Boolean hasArg;
904   TCollection_AsciiString aName;
905   Standard_Integer aCurrentIndex;
906
907   // Verification
908   if (argc<2 || argc>6 )
909   {
910     std::cout<<" Syntax error\n";
911     return 1;
912   }
913   if (argc == 6 || argc==5 || argc==4)
914     hasArg=Standard_True;
915   else 
916     hasArg=Standard_False;
917
918   aName=argv[1];
919   // Close all contexts
920   TheAISContext()->CloseAllContexts();
921
922   // There are some arguments
923   if (hasArg)
924   {
925     if (!GetMapOfAIS().IsBound2(argv[2] ))
926     {
927       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
928       return 1;
929     }
930     // Get shape from map
931     Handle(AIS_InteractiveObject) aShapeA =
932       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2] ));
933
934     // The first argument is an AIS_Point
935     if (!aShapeA.IsNull() &&
936         aShapeA->Type()==AIS_KOI_Datum &&
937         aShapeA->Signature()==1)
938     {
939         // The second argument must also be an AIS_Point
940         if (argc<5 || !GetMapOfAIS().IsBound2(argv[3]))
941         {
942           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
943           return 1;
944         }
945         // Get shape from map
946         Handle(AIS_InteractiveObject) aShapeB =
947           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
948         // If B is not an AIS_Point
949         if (aShapeB.IsNull() ||
950           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
951         {
952           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
953           return 1;
954         }
955         // The third object is an AIS_Point
956         if (!GetMapOfAIS().IsBound2(argv[4]) ) 
957         {
958           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
959           return 1; 
960         }
961         // Get shape from map
962         Handle(AIS_InteractiveObject) aShapeC =
963           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
964         // If C is not an AIS_Point
965         if (aShapeC.IsNull() ||
966           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
967         {
968           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
969           return 1;
970         }
971
972         // Treatment of objects A, B, C
973         // Downcast an AIS_IO to AIS_Point
974         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
975         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
976         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
977
978         Handle(Geom_CartesianPoint ) aCartPointA = 
979           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
980
981         Handle(Geom_CartesianPoint ) aCartPointB = 
982           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
983
984         Handle(Geom_CartesianPoint ) aCartPointC = 
985           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
986
987         // Verification that the three points are different
988         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
989            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
990            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
991         {
992           // B=A
993           std::cout<<"vplane error: same points"<<"\n";return 1;
994         }
995         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
996            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
997            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
998         {
999           // C=A
1000           std::cout<<"vplane error: same points"<<"\n";return 1;
1001         }
1002         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
1003            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
1004            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
1005         {
1006           // C=B
1007           std::cout<<"vplane error: same points"<<"\n";return 1;
1008         }
1009
1010         gp_Pnt A = aCartPointA->Pnt();
1011         gp_Pnt B = aCartPointB->Pnt();
1012         gp_Pnt C = aCartPointC->Pnt();
1013
1014         // Construction of AIS_Plane
1015         GC_MakePlane MkPlane (A,B,C);
1016         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1017         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1018         GetMapOfAIS().Bind (anAISPlane,aName );
1019         if (argc == 6)
1020         {
1021           Standard_Integer aType = Draw::Atoi (argv[5]);
1022           if (aType != 0 && aType != 1)
1023           {
1024             std::cout << "vplane error: wrong type of sensitivity!\n"
1025                       << "Should be one of the following values:\n"
1026                       << "0 - Interior\n"
1027                       << "1 - Boundary"
1028                       << std::endl;
1029             return 1;
1030           }
1031           else
1032           {
1033             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1034           }
1035         }
1036         TheAISContext()->Display(anAISPlane);
1037       }
1038
1039       // The first argument is an AIS_Axis
1040       // Creation of a plane orthogonal to the axis through a point
1041     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1042       // The second argument should be an AIS_Point
1043       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3] ) )
1044       {
1045         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1046         return 1;
1047       }
1048       // Get shape from map
1049       Handle(AIS_InteractiveObject) aShapeB =
1050         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1051       // If B is not an AIS_Point
1052       if (aShapeB.IsNull() ||
1053         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1054       {
1055         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1056         return 1;
1057       }
1058
1059       // Treatment of objects A and B
1060       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1061       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1062
1063       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1064       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1065
1066       gp_Ax1 anAxis = aGeomLineA->Position();
1067       Handle(Geom_CartesianPoint) aCartPointB = 
1068         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1069
1070       gp_Dir D =anAxis.Direction();
1071       gp_Pnt B = aCartPointB->Pnt();
1072
1073       // Construction of AIS_Plane
1074       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1075       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1076       GetMapOfAIS().Bind (anAISPlane,aName );
1077       if (argc == 5)
1078       {
1079         Standard_Integer aType = Draw::Atoi (argv[4]);
1080         if (aType != 0 && aType != 1)
1081         {
1082           std::cout << "vplane error: wrong type of sensitivity!\n"
1083                     << "Should be one of the following values:\n"
1084                     << "0 - Interior\n"
1085                     << "1 - Boundary"
1086                     << std::endl;
1087           return 1;
1088         }
1089         else
1090         {
1091           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1092         }
1093       }
1094       TheAISContext()->Display(anAISPlane);
1095
1096     }
1097     // The first argumnet is an AIS_Plane
1098     // Creation of a plane parallel to the plane passing through the point
1099     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1100     {
1101       // The second argument should be an AIS_Point
1102       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3]))
1103       {
1104         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1105         return 1;
1106       }
1107       // Get shape from map
1108       Handle(AIS_InteractiveObject) aShapeB =
1109         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1110       // B should be an AIS_Point
1111       if (aShapeB.IsNull() ||
1112          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1113       {
1114         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1115         return 1;
1116       }
1117
1118       // Treatment of objects A and B
1119       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1120       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1121
1122       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1123       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1124
1125       Handle(Geom_CartesianPoint) aCartPointB = 
1126         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1127       gp_Pnt B= aCartPointB->Pnt();
1128
1129       // Construction of an AIS_Plane
1130       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1131       GetMapOfAIS().Bind (anAISPlane, aName);
1132       if (argc == 5)
1133       {
1134         Standard_Integer aType = Draw::Atoi (argv[4]);
1135         if (aType != 0 && aType != 1)
1136         {
1137           std::cout << "vplane error: wrong type of sensitivity!\n"
1138                     << "Should be one of the following values:\n"
1139                     << "0 - Interior\n"
1140                     << "1 - Boundary"
1141                     << std::endl;
1142           return 1;
1143         }
1144         else
1145         {
1146           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1147         }
1148       }
1149       TheAISContext()->Display(anAISPlane);
1150     }
1151     // Error
1152     else
1153     {
1154       std::cout<<"vplane: error 1st object is not an AIS\n";
1155       return 1;
1156     }
1157   }
1158   // There are no arguments
1159   else 
1160   {
1161     // Function vplane
1162     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1163     if (!strcasecmp(argv[0], "vplane"))
1164     {
1165       TheAISContext()->OpenLocalContext();
1166       aCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1167
1168       // Active modes Vertex, Edge and Face
1169       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1170       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1171       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1172       std::cout<<"Select a vertex, a face or an edge\n";
1173
1174       // Wait for picking
1175       Standard_Integer argcc = 5;
1176       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1177       const char **argvv = (const char **) buff;
1178       while (ViewerMainLoop( argcc, argvv) ) { }
1179       // end of the loop
1180
1181       TopoDS_Shape aShapeA;
1182       for (TheAISContext()->InitSelected();
1183            TheAISContext()->MoreSelected();
1184            TheAISContext()->NextSelected())
1185       {
1186         aShapeA = TheAISContext()->SelectedShape();
1187       }
1188
1189       // aShapeA is a Vertex
1190       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1191       {
1192         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1193         std::cout<<" Select an edge or a different vertex\n";
1194
1195         // Wait for picking
1196         Standard_Integer argccc = 5;
1197         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1198         const char **argvvv = (const char **) bufff;
1199         while (ViewerMainLoop( argccc, argvvv) ) { }
1200         // end of the loop
1201
1202         TopoDS_Shape aShapeB;
1203         for (TheAISContext()->InitSelected();
1204           TheAISContext()->MoreSelected();
1205           TheAISContext()->NextSelected())
1206         {
1207           aShapeB = TheAISContext()->SelectedShape();
1208         }
1209         // aShapeB is a Vertex
1210         if (aShapeB.ShapeType()==TopAbs_VERTEX)
1211         {
1212           // A and B are the same
1213           if (aShapeB.IsSame(aShapeA))
1214           {
1215             std::cout<<" vplane: error, same points selected\n";
1216             return 1;
1217           }
1218           TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1219           std::cout<<" Select a different vertex\n";
1220
1221           // Wait for picking
1222           Standard_Integer argcccc = 5;
1223           const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1224           const char **argvvvv = (const char **) buffff;
1225           while (ViewerMainLoop( argcccc, argvvvv) ) { }
1226           // end of the loop
1227
1228           TopoDS_Shape aShapeC;
1229           for (TheAISContext()->InitSelected();
1230                TheAISContext()->MoreSelected();
1231                TheAISContext()->NextSelected())
1232           {
1233             aShapeC = TheAISContext()->SelectedShape();
1234           }
1235           // aShapeC is the same as A or B
1236           if (aShapeC.IsSame(aShapeA)||aShapeC.IsSame(aShapeB))
1237           {
1238             std::cout<<" vplane: error, same points selected\n";
1239             return 1;
1240           }
1241
1242           // Close the local context
1243           TheAISContext()->CloseLocalContext(aCurrentIndex);
1244
1245           // Construction of plane
1246           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1247           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1248           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1249           GC_MakePlane MkPlane(A, B, C);
1250           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1251           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1252           GetMapOfAIS().Bind (anAISPlane, aName);
1253           TheAISContext()->Display(anAISPlane);
1254         }
1255         // ShapeB is an edge
1256         else
1257         {
1258           // Verify that the vertex is not on the edge ShapeB
1259           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1260           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1261
1262           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1263           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1264           {
1265             // The vertex is on the edge
1266             std::cout<<" vplane: error point is on the edge\n";
1267             return 1;
1268           }
1269           else
1270           {
1271             // Close the local context
1272             TheAISContext()->CloseLocalContext(aCurrentIndex);
1273             // Construction of plane
1274             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1275             TopoDS_Vertex aVBa, aVBb;
1276             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1277             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1278             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1279             GC_MakePlane MkPlane (A, aBa, aBb);
1280             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1281             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1282             GetMapOfAIS().Bind (anAISPlane, aName);
1283             TheAISContext()->Display(anAISPlane);
1284           }
1285         }
1286       }
1287       // aShapeA is an edge
1288       else if (aShapeA.ShapeType()==TopAbs_EDGE)
1289       {
1290         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1291         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1292         std::cout<<" Select a vertex that don't belong to the edge\n";
1293
1294         // Wait for picking
1295         Standard_Integer argccc = 5;
1296         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1297         const char **argvvv = (const char **) bufff;
1298         while (ViewerMainLoop( argccc, argvvv) ) { }
1299         // end of the loop
1300
1301         TopoDS_Shape aShapeB;
1302         for (TheAISContext()->InitSelected();
1303              TheAISContext()->MoreSelected();
1304              TheAISContext()->NextSelected())
1305         {
1306           aShapeB = TheAISContext()->SelectedShape();
1307         }
1308         // aShapeB should be a Vertex
1309         // Check that the vertex aShapeB is not on the edge
1310         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1311         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1312
1313         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1314         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1315         {
1316           // The vertex is on the edge
1317           std::cout<<" vplane: error point is on the edge\n";
1318           return 1;
1319         }
1320         else
1321         {
1322           // Close the local context
1323           TheAISContext()->CloseLocalContext(aCurrentIndex);
1324           // Construction of plane
1325           gp_Pnt B = BRep_Tool::Pnt(aVertB);
1326           TopoDS_Vertex aVAa, aVAb;
1327           TopExp::Vertices(anEdgeA, aVAa, aVAb);
1328           gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1329           gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1330           GC_MakePlane MkPlane (B,Aa,Ab);
1331           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1332           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1333           GetMapOfAIS().Bind (anAISPlane ,aName);
1334           TheAISContext()->Display(anAISPlane);
1335         }
1336       }
1337       // aShapeA is a Face
1338       else
1339       {
1340         // Close the local context: nothing to select
1341         TheAISContext()->CloseLocalContext(aCurrentIndex);
1342         // Construction of plane
1343         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1344         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1345         if (aSurface.GetType()==GeomAbs_Plane)
1346         {
1347           gp_Pln aPlane = aSurface.Plane();
1348           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1349           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1350           GetMapOfAIS().Bind (anAISPlane, aName);
1351           TheAISContext()->Display(anAISPlane);
1352         }
1353         else
1354         {
1355           std::cout<<" vplane: error\n";
1356           return 1;
1357         }
1358       }
1359     }
1360
1361     // Function vPlanePara
1362     // ===================
1363     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1364     else if (!strcasecmp(argv[0], "vplanepara"))
1365     {
1366       TheAISContext()->OpenLocalContext();
1367       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1368
1369       // Activate modes Vertex and Face
1370       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1371       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1372       std::cout<<" Select a vertex or a face\n";
1373
1374       // Wait for picking
1375       Standard_Integer argcc = 5;
1376       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1377       const char **argvv = (const char **) buff;
1378       while (ViewerMainLoop( argcc, argvv) ) { }
1379       // end of the loop
1380
1381       TopoDS_Shape aShapeA;
1382       for (TheAISContext()->InitSelected();
1383            TheAISContext()->MoreSelected();
1384            TheAISContext()->NextSelected())
1385       {
1386         aShapeA = TheAISContext()->SelectedShape();
1387       }
1388
1389       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1390       {
1391         // aShapeA is a vertex
1392         // Deactivate the mode Vertex
1393         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1));
1394         std::cout<<" Select a face\n";
1395
1396         // Wait for picking
1397         Standard_Integer argccc = 5;
1398         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1399         const char **argvvv = (const char **) bufff;
1400         while (ViewerMainLoop( argccc, argvvv) ) { }
1401         // end of the loop
1402
1403         TopoDS_Shape aShapeB;
1404         for (TheAISContext()->InitSelected();
1405              TheAISContext()->MoreSelected();
1406              TheAISContext()->NextSelected())
1407         {
1408           // A vertex ShapeA can be on Face ShapeB
1409           aShapeB = TheAISContext()->SelectedShape();
1410         }
1411
1412         // Close the local context
1413         TheAISContext()->CloseLocalContext(aCurrentIndex);
1414
1415         // Construction of plane
1416         gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1417
1418         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1419         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1420         if (aSurface.GetType()==GeomAbs_Plane )
1421         {
1422           gp_Pln aPlane = aSurface.Plane();
1423           // Construct a plane parallel to aGeomPlane through A
1424           aPlane.SetLocation(A);
1425           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1426           Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1427           GetMapOfAIS().Bind (aAISPlane ,aName);
1428           TheAISContext()->Display(aAISPlane);
1429         }
1430         else
1431         {
1432           std::cout<<" vplanepara: error\n";
1433           return 1;
1434         }
1435       }
1436       else
1437       {
1438         // ShapeA is a Face
1439         // Deactive the mode Face
1440         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1441         std::cout<<" Select a vertex\n";
1442
1443         // Wait for picking
1444         Standard_Integer argccc = 5;
1445         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1446         const char **argvvv = (const char **) bufff;
1447         while (ViewerMainLoop( argccc, argvvv) ) { }
1448         // end of the loop
1449
1450         TopoDS_Shape aShapeB;
1451         for (TheAISContext()->InitSelected();
1452              TheAISContext()->MoreSelected();
1453              TheAISContext()->NextSelected())
1454         {
1455           // A vertex ShapeB can be on Face ShapeA
1456           aShapeB = TheAISContext()->SelectedShape();
1457         }
1458         // Close the local context
1459         TheAISContext()->CloseLocalContext(aCurrentIndex);
1460
1461         // Construction of plane
1462         gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1463
1464         TopoDS_Face aFace=TopoDS::Face(aShapeA);
1465         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1466         if (aSurface.GetType()==GeomAbs_Plane )
1467         {
1468           gp_Pln aPlane = aSurface.Plane();
1469           aPlane.SetLocation(B);
1470           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1471           // Construct a plane parallel to aGeomPlane through B
1472           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, B);
1473           GetMapOfAIS().Bind (anAISPlane, aName);
1474           TheAISContext()->Display(anAISPlane);
1475         }
1476         else
1477         {
1478           std::cout<<" vplanepara: error"<<"\n";return 1;
1479         }
1480       }
1481     }
1482
1483     // Function vplaneortho
1484     // ====================
1485     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1486     else
1487     {
1488       TheAISContext()->OpenLocalContext();
1489       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1490
1491       // Activate the modes Edge and Face
1492       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1493       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1494       std::cout<<" Select a face and an edge coplanar\n";
1495
1496       // Wait for picking
1497       Standard_Integer argcc = 5;
1498       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1499       const char **argvv = (const char **) buff;
1500       while (ViewerMainLoop( argcc, argvv) ) { }
1501       // end of the loop
1502
1503       TopoDS_Shape aShapeA;
1504       for (TheAISContext()->InitSelected();
1505            TheAISContext()->MoreSelected();
1506            TheAISContext()->NextSelected())
1507       {
1508         aShapeA = TheAISContext()->SelectedShape();
1509       }
1510
1511       if (aShapeA.ShapeType()==TopAbs_EDGE )
1512       {
1513         // ShapeA is an edge, deactivate the mode Edge...
1514         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1515         std::cout<<" Select a face\n";
1516
1517         // Wait for picking
1518         Standard_Integer argccc = 5;
1519         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1520         const char **argvvv = (const char **) bufff;
1521         while (ViewerMainLoop( argccc, argvvv) ) { }
1522         // end of the loop
1523
1524         TopoDS_Shape aShapeB;
1525         for (TheAISContext()->InitSelected();
1526              TheAISContext()->MoreSelected();
1527              TheAISContext()->NextSelected())
1528         {
1529           // Edge ShapeA can be on Face ShapeB
1530           aShapeB = TheAISContext()->SelectedShape();
1531         }
1532
1533         // Close the local context
1534         TheAISContext()->CloseLocalContext(aCurrentIndex);
1535
1536         // Construction of plane
1537         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1538         TopoDS_Vertex aVAa, aVAb;
1539         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1540         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1541         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1542         gp_Vec ab (Aa,Ab);
1543
1544         gp_Dir Dab (ab);
1545         // Creation of rotation axis
1546         gp_Ax1 aRotAxis (Aa,Dab);
1547
1548         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1549         // The edge must be parallel to the face
1550         BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1551         BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1552         // Compare to heights
1553         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1554             >Precision::Confusion())
1555         {
1556           // the edge is not parallel to the face
1557           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1558           return 1;
1559         }
1560         // the edge is OK
1561         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1562         if (aSurface.GetType()==GeomAbs_Plane)
1563         {
1564           gp_Pln aPlane = aSurface.Plane();
1565           // It rotates a half turn round the axis of rotation
1566           aPlane.Rotate(aRotAxis , M_PI/2);
1567
1568           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1569           // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1570           gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1571           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1572           GetMapOfAIS().Bind (anAISPlane, aName);
1573           TheAISContext()->Display(anAISPlane);
1574         }
1575         else
1576         {
1577           std::cout<<" vplaneortho: error\n";
1578           return 1;
1579         }
1580       }
1581       else
1582       {
1583         // ShapeA is a Face, deactive the mode Face.
1584         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1585         std::cout<<" Select an edge\n";
1586
1587         // Wait for picking
1588         Standard_Integer argccc = 5;
1589         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1590         const char **argvvv = (const char **) bufff;
1591         while (ViewerMainLoop( argccc, argvvv) ) { }
1592         // end of the loop
1593
1594         TopoDS_Shape aShapeB;
1595         for (TheAISContext()->InitSelected();
1596              TheAISContext()->MoreSelected();
1597              TheAISContext()->NextSelected())
1598         {
1599           // Edge ShapeB can be on Face ShapeA
1600           aShapeB = TheAISContext()->SelectedShape();
1601         }
1602         // Close the local context
1603         TheAISContext()->CloseLocalContext(aCurrentIndex);
1604
1605         // Construction of plane
1606         TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1607         TopoDS_Vertex aVBa, aVBb;
1608         TopExp::Vertices(anEdgeB, aVBa, aVBb);
1609         gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1610         gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1611         gp_Vec ab (aBa,aBb);
1612         gp_Dir Dab (ab);
1613         // Creation of rotation axe
1614         gp_Ax1 aRotAxis (aBa,Dab);
1615
1616         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1617         // The edge must be parallel to the face
1618         BRepExtrema_ExtPF aHeightA (aVBa, aFace);
1619         BRepExtrema_ExtPF aHeightB (aVBb, aFace);
1620         // Comparing the two heights
1621         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1622             >Precision::Confusion())
1623         {
1624           // the edge is not parallel to the face
1625           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1626           return 1;
1627         }
1628         // The edge is OK
1629         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1630         if (aSurface.GetType()==GeomAbs_Plane)
1631         {
1632           gp_Pln aPlane = aSurface.Plane();
1633           // It rotates a half turn round the axis of rotation
1634           aPlane.Rotate(aRotAxis , M_PI/2);
1635           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1636           // constructed aGeomPlane parallel to a plane containing the edge theGeomPlane (center mid-edge)
1637           gp_Pnt aMiddle ((aBa.X()+aBb.X() )/2 , (aBa.Y()+aBb.Y() )/2 , (aBa.Z()+aBb.Z() )/2 );
1638           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1639           GetMapOfAIS().Bind (anAISPlane ,aName);
1640           TheAISContext()->Display(anAISPlane);
1641         }
1642         else
1643         {
1644           std::cout<<" vplaneortho: error\n";
1645           return 1;
1646         }
1647       }
1648     }
1649   }
1650   return 0;
1651 }
1652
1653 //===============================================================================================
1654 //function : VChangePlane
1655 //purpose  :
1656 //===============================================================================================
1657 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1658 {
1659   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1660   if (aContextAIS.IsNull())
1661   {
1662     std::cout << theArgVec[0] << "AIS context is not available.\n";
1663     return 1;
1664   }
1665
1666   if (theArgsNb < 3 || theArgsNb > 11)
1667   {
1668     std::cerr << theArgVec[0] 
1669               << ": incorrect number of command arguments.\n"
1670               << "Type help for more information.\n";
1671     return 1;
1672   }
1673
1674   TCollection_AsciiString aName (theArgVec[1]);
1675
1676   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1677     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1678     : NULL;
1679
1680   if ( aPlane.IsNull() )
1681   {
1682     std::cout << theArgVec[0] 
1683               << ": there is no interactive plane with the given name."
1684               << "Type help for more information.\n";
1685     return 1;
1686   }
1687
1688   Standard_Real aCenterX = aPlane->Center().X();
1689   Standard_Real aCenterY = aPlane->Center().Y();
1690   Standard_Real aCenterZ = aPlane->Center().Z();
1691
1692   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1693   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1694   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1695
1696   Standard_Real aSizeX = 0.0;
1697   Standard_Real aSizeY = 0.0;
1698   aPlane->Size (aSizeX, aSizeY);
1699   Standard_Boolean isUpdate = Standard_True;
1700
1701   TCollection_AsciiString aPName, aPValue;
1702   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1703   {
1704     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1705     TCollection_AsciiString anArgCase = anArg;
1706     anArgCase.UpperCase();
1707     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1708     {
1709       aPName.UpperCase();
1710       if (aPName.IsEqual ("X"))
1711       {
1712         aCenterX = aPValue.RealValue();
1713       }
1714       else if (aPName.IsEqual ("Y"))
1715       {
1716         aCenterY = aPValue.RealValue();
1717       }
1718       else if (aPName.IsEqual ("Z"))
1719       {
1720         aCenterZ = aPValue.RealValue();
1721       }
1722       else if (aPName.IsEqual ("DX"))
1723       {
1724         aDirX = aPValue.RealValue();
1725       }
1726       else if (aPName.IsEqual ("DY"))
1727       {
1728         aDirY = aPValue.RealValue();
1729       }
1730       else if (aPName.IsEqual ("DZ"))
1731       {
1732         aDirZ = aPValue.RealValue();
1733       }
1734       else if (aPName.IsEqual ("SX"))
1735       {
1736         aSizeX = aPValue.RealValue();
1737       }
1738       else if (aPName.IsEqual ("SY"))
1739       {
1740         aSizeY = aPValue.RealValue();
1741       }
1742     }
1743     else if (anArg.IsEqual ("NOUPDATE"))
1744     {
1745       isUpdate = Standard_False;
1746     }
1747   }
1748
1749   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1750   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1751   aPlane->SetCenter (aCenterPnt);
1752   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1753   aPlane->SetSize (aSizeX, aSizeY);
1754
1755   if (isUpdate)
1756   {
1757     aContextAIS->Update (aPlane, Standard_True);
1758   }
1759
1760   return 0;
1761 }
1762
1763 //==============================================================================
1764 // Fonction  vline
1765 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1766 //==============================================================================
1767
1768 //==============================================================================
1769 //function : VLineBuilder
1770 //purpose  : Build an AIS_Line
1771 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1772 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1773 //==============================================================================
1774 #include <Geom_CartesianPoint.hxx>
1775 #include <AIS_Line.hxx>
1776
1777
1778 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1779 {
1780   Standard_Integer myCurrentIndex;
1781   // Verifications
1782   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct "<<"\n";return 1; }
1783   // Fermeture des contextes
1784   TheAISContext()->CloseAllContexts();
1785
1786   // On recupere les parametres
1787   Handle(AIS_InteractiveObject) theShapeA;
1788   Handle(AIS_InteractiveObject) theShapeB;
1789
1790   // Parametres: AIS_Point AIS_Point
1791   // ===============================
1792   if (argc==4) {
1793     theShapeA=
1794       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
1795     // On verifie que c'est bien une AIS_Point
1796     if (!theShapeA.IsNull() &&
1797       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1798         // on recupere le deuxieme AIS_Point
1799         theShapeB=
1800           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1801         if (theShapeA.IsNull() ||
1802           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1803         {
1804           di <<"vline error: wrong type of 2de argument."<<"\n";
1805           return 1;
1806         }
1807       }
1808     else {di <<"vline error: wrong type of 1st argument."<<"\n";return 1; }
1809     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1810     Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA;
1811     Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB;
1812
1813     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1814     Handle(Geom_CartesianPoint ) myCartPointA= *((Handle(Geom_CartesianPoint)*)&  myGeomPointBA);
1815     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1816
1817     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1818     Handle(Geom_CartesianPoint ) myCartPointB= *((Handle(Geom_CartesianPoint)*)&  myGeomPointB);
1819     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1820
1821     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1822       // B=A
1823       di<<"vline error: same points"<<"\n";return 1;
1824     }
1825     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1826     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1827     GetMapOfAIS().Bind(theAISLine,argv[1] );
1828     TheAISContext()->Display(theAISLine );
1829
1830   }
1831
1832   // Parametres 6 Reals
1833   // ==================
1834
1835   else if (argc==8) {
1836     // On verifie que les deux points ne sont pas confondus
1837
1838     Standard_Real coord[6];
1839     for(Standard_Integer i=0;i<=2;i++){
1840       coord[i]=Draw::Atof(argv[2+i]);
1841       coord[i+3]=Draw::Atof(argv[5+i]);
1842     }
1843
1844     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1845     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1846
1847     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1848     GetMapOfAIS().Bind(theAISLine,argv[1] );
1849     TheAISContext()->Display(theAISLine );
1850
1851   }
1852
1853   // Pas de parametres: Selection dans le viewer.
1854   // ============================================
1855
1856   else {
1857     TheAISContext()->OpenLocalContext();
1858     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1859
1860     // Active le mode Vertex.
1861     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1862     di<<" Select a vertex "<<"\n";
1863
1864     // Boucle d'attente waitpick.
1865     Standard_Integer argcc = 5;
1866     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1867     const char **argvv = (const char **) buff;
1868     while (ViewerMainLoop( argcc, argvv) ) { }
1869     // fin de la boucle
1870
1871     TopoDS_Shape ShapeA;
1872     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1873       ShapeA = TheAISContext()->SelectedShape();
1874     }
1875
1876     // ShapeA est un Vertex
1877     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
1878
1879       di<<" Select a different vertex."<<"\n";
1880
1881       TopoDS_Shape ShapeB;
1882       do {
1883
1884         // Boucle d'attente waitpick.
1885         Standard_Integer argccc = 5;
1886         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1887         const char **argvvv = (const char **) bufff;
1888         while (ViewerMainLoop( argccc, argvvv) ) { }
1889         // fin de la boucle
1890
1891         for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1892           ShapeB = TheAISContext()->SelectedShape();
1893         }
1894
1895
1896       } while(ShapeB.IsSame(ShapeA) );
1897
1898       // Fermeture du context local
1899       TheAISContext()->CloseLocalContext(myCurrentIndex);
1900
1901       // Construction de la line
1902       gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
1903       gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
1904
1905       Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1906       Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1907
1908       Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1909       GetMapOfAIS().Bind(theAISLine,argv[1] );
1910       TheAISContext()->Display(theAISLine );
1911
1912     }
1913     else  {
1914       di<<"vline error."<<"\n";
1915     }
1916
1917   }
1918
1919   return 0;
1920 }
1921
1922 //==============================================================================
1923 // class   : FilledCircle
1924 // purpose : creates filled circle based on AIS_InteractiveObject 
1925 //           and Geom_Circle.
1926 //           This class is used to check method Matches() of class 
1927 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1928 //           because none of AIS classes provides creation of 
1929 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1930 //           (look method ComputeSelection() )
1931 //============================================================================== 
1932
1933 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1934 {
1935   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
1936   gp_Circ aCirc(anAxes, theRadius);
1937   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
1938   return aCircle;
1939 }
1940
1941 DEFINE_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1942
1943 class FilledCircle : public AIS_InteractiveObject 
1944 {
1945 public:
1946     // CASCADE RTTI
1947     DEFINE_STANDARD_RTTI(FilledCircle); 
1948
1949     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1950     FilledCircle(Handle(Geom_Circle) theCircle);
1951
1952 private:
1953     TopoDS_Face ComputeFace();
1954
1955     // Virtual methods implementation
1956     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1957                   const Handle(Prs3d_Presentation)& thePresentation,
1958                   const Standard_Integer theMode);
1959
1960     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1961                            const Standard_Integer theMode);
1962
1963 protected:
1964     Handle(Geom_Circle) myCircle;
1965     Standard_Boolean myFilledStatus;
1966
1967 }; 
1968
1969 IMPLEMENT_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1970 IMPLEMENT_STANDARD_RTTIEXT(FilledCircle, AIS_InteractiveObject)
1971
1972 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1973 {
1974   myCircle = CreateCircle(theCenter, theRadius);
1975   myFilledStatus = Standard_True;
1976 }
1977
1978 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1979 {
1980   myCircle = theCircle;
1981   myFilledStatus = Standard_True;
1982 }
1983
1984 TopoDS_Face FilledCircle::ComputeFace() 
1985 {
1986   // Create edge from myCircle 
1987   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1988   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1989
1990   // Create wire from anEdge 
1991   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1992   TopoDS_Wire aWire = aWireMaker.Wire();
1993
1994   // Create face from aWire
1995   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1996   TopoDS_Face aFace = aFaceMaker.Face();
1997
1998   return aFace;
1999 }
2000
2001 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
2002                            const Handle(Prs3d_Presentation) &thePresentation, 
2003                            const Standard_Integer theMode) 
2004 {
2005   thePresentation->Clear();
2006
2007   TopoDS_Face aFace = ComputeFace();
2008
2009   if (aFace.IsNull()) return;
2010   if (theMode != 0) return;
2011
2012   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
2013 }
2014
2015 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2016                                     const Standard_Integer /*theMode*/)
2017 {
2018   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2019   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2020       myCircle, myFilledStatus);
2021   theSelection->Add(aSensitiveCircle);
2022 }
2023
2024 //==============================================================================
2025 // Fonction  vcircle
2026 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2027 //==============================================================================
2028
2029 //==============================================================================
2030 //function : VCircleBuilder
2031 //purpose  : Build an AIS_Circle
2032 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2033 //                              PointName PointName PointName IsFilled
2034 //==============================================================================
2035
2036 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2037                     TCollection_AsciiString theName, 
2038                     Standard_Boolean isFilled) 
2039 {
2040   Handle(AIS_InteractiveObject) aCircle;
2041   if (isFilled) 
2042   {
2043     aCircle = new FilledCircle(theGeomCircle);
2044   }
2045   else
2046   {
2047     aCircle = new AIS_Circle(theGeomCircle);
2048     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2049   }
2050
2051   // Check if there is an object with given name
2052   // and remove it from context
2053   if (GetMapOfAIS().IsBound2(theName)) 
2054   {
2055     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
2056     Handle(AIS_InteractiveObject) anInterObj = 
2057          Handle(AIS_InteractiveObject)::DownCast(anObj);
2058     TheAISContext()->Remove(anInterObj, Standard_False);
2059     GetMapOfAIS().UnBind2(theName);
2060    }
2061
2062    // Bind the circle to its name
2063    GetMapOfAIS().Bind(aCircle, theName);
2064
2065    // Display the circle
2066    TheAISContext()->Display(aCircle);
2067   
2068 }
2069
2070 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2071 {
2072   Standard_Integer myCurrentIndex;
2073   // Verification of the arguments
2074   if (argc>6 || argc<2) 
2075   { 
2076     std::cout << "vcircle error: expect 4 arguments.\n"; 
2077     return 1; // TCL_ERROR 
2078   }
2079   TheAISContext()->CloseAllContexts();
2080
2081   // There are all arguments
2082   if (argc == 6) 
2083   {
2084     // Get arguments
2085     TCollection_AsciiString aName(argv[1]);
2086     Standard_Boolean isFilled = (Standard_Boolean)Draw::Atoi(argv[5]);
2087
2088     Handle(AIS_InteractiveObject) theShapeA;
2089     Handle(AIS_InteractiveObject) theShapeB;
2090
2091     theShapeA =
2092       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2093     theShapeB =
2094       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2095
2096
2097     // Arguments: AIS_Point AIS_Point AIS_Point
2098     // ========================================
2099     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2100       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2101     {
2102       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2103       {
2104         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2105         return 1; // TCL_ERROR 
2106       }
2107       // The third object must be a point
2108       Handle(AIS_InteractiveObject) theShapeC =
2109         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2110       if (theShapeC.IsNull() ||
2111         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2112       {
2113         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2114         return 1; // TCL_ERROR 
2115       }
2116         // tag
2117         // Verify that the three points are different
2118         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2119         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2120         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2121         
2122         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2123         Handle(Geom_CartesianPoint) myCartPointA = 
2124           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2125
2126         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2127         Handle(Geom_CartesianPoint) myCartPointB =
2128           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2129
2130         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2131         Handle(Geom_CartesianPoint) myCartPointC =
2132           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2133
2134         // Test A=B
2135         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2136             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2137             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2138         {
2139           std::cout << "vcircle error: Same points.\n"; 
2140           return 1; // TCL_ERROR 
2141         }
2142         // Test A=C
2143         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2144             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2145             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2146         {
2147           std::cout << "vcircle error: Same points.\n"; 
2148           return 1; // TCL_ERROR 
2149         }
2150         // Test B=C
2151         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2152             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2153             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2154         {
2155           std::cout << "vcircle error: Same points.\n"; 
2156           return 1;// TCL_ERROR 
2157         }
2158         // Construction of the circle
2159         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2160           myCartPointB->Pnt(), myCartPointC->Pnt() );
2161         Handle (Geom_Circle) theGeomCircle;
2162         try 
2163         {
2164           theGeomCircle = Cir.Value();
2165         }
2166         catch (StdFail_NotDone)
2167         {
2168           std::cout << "vcircle error: can't create circle\n";
2169           return -1; // TCL_ERROR
2170         }
2171         
2172         DisplayCircle(theGeomCircle, aName, isFilled);
2173     }
2174
2175     // Arguments: AIS_Plane AIS_Point Real
2176     // ===================================
2177     else if (theShapeA->Type() == AIS_KOI_Datum && 
2178       theShapeA->Signature() == 7 ) 
2179     {
2180       if (theShapeB->Type() != AIS_KOI_Datum || 
2181         theShapeB->Signature() != 1 ) 
2182       {
2183         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2184         return 1; // TCL_ERROR 
2185       }
2186       // Check that the radius is >= 0
2187       if (Draw::Atof(argv[4]) <= 0 ) 
2188       {
2189         std::cout << "vcircle error: the radius must be >=0.\n"; 
2190         return 1; // TCL_ERROR 
2191       }
2192
2193       // Recover the normal to the plane
2194       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2195       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2196
2197       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2198       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2199       Handle(Geom_CartesianPoint) myCartPointB = 
2200         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2201
2202       gp_Pln mygpPlane = myGeomPlane->Pln();
2203       gp_Ax1 thegpAxe = mygpPlane.Axis();
2204       gp_Dir theDir = thegpAxe.Direction();
2205       gp_Pnt theCenter = myCartPointB->Pnt();
2206       Standard_Real TheR = Draw::Atof(argv[4]);
2207       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2208       Handle (Geom_Circle) theGeomCircle;
2209       try 
2210       {
2211         theGeomCircle = Cir.Value();
2212       }
2213       catch (StdFail_NotDone)
2214       {
2215         std::cout << "vcircle error: can't create circle\n";
2216         return -1; // TCL_ERROR
2217       }
2218
2219       DisplayCircle(theGeomCircle, aName, isFilled);
2220
2221     }
2222
2223     // Error
2224     else
2225     {
2226       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2227       return 1; // TCL_ERROR 
2228     }
2229
2230   }
2231   // No arguments: selection in the viewer
2232   // =========================================
2233   else 
2234   {
2235     // Get the name of the circle 
2236     TCollection_AsciiString aName(argv[1]);
2237
2238     TheAISContext()->OpenLocalContext();
2239     myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
2240
2241     // Activate selection mode for vertices and faces
2242     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2243     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2244     std::cout << " Select a vertex or a face\n";
2245
2246     // Wait for picking
2247     Standard_Integer argcc = 5;
2248     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2249     const char **argvv = (const char **) buff;
2250     while (ViewerMainLoop( argcc, argvv) ) { }
2251     // end of the loop
2252
2253     TopoDS_Shape ShapeA;
2254     for(TheAISContext()->InitSelected(); 
2255       TheAISContext()->MoreSelected(); 
2256       TheAISContext()->NextSelected() ) 
2257     {
2258       ShapeA = TheAISContext()->SelectedShape();
2259     }
2260
2261     // ShapeA is a Vertex
2262     if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
2263     {
2264       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2265       std::cout << " Select a different vertex\n";
2266
2267       TopoDS_Shape ShapeB;
2268       do 
2269       {
2270         // Wait for picking
2271         Standard_Integer argccc = 5;
2272         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2273         const char **argvvv = (const char **) bufff;
2274         while (ViewerMainLoop( argccc, argvvv) ) { }
2275         // end of the loop
2276
2277         for(TheAISContext()->InitSelected(); 
2278           TheAISContext()->MoreSelected(); 
2279           TheAISContext()->NextSelected() ) 
2280         {
2281           ShapeB = TheAISContext()->SelectedShape();
2282         }
2283       } while(ShapeB.IsSame(ShapeA) );
2284
2285       // Selection of ShapeC
2286       std::cout << " Select the last vertex\n";
2287       TopoDS_Shape ShapeC;
2288       do 
2289       {
2290         // Wait for picking
2291         Standard_Integer argcccc = 5;
2292         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2293         const char **argvvvv = (const char **) buffff;
2294         while (ViewerMainLoop( argcccc, argvvvv) ) { }
2295         // end of the loop
2296
2297         for(TheAISContext()->InitSelected(); 
2298           TheAISContext()->MoreSelected(); 
2299           TheAISContext()->NextSelected() ) 
2300         {
2301           ShapeC = TheAISContext()->SelectedShape();
2302         }
2303       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
2304       
2305       // Get isFilled
2306       Standard_Boolean isFilled;
2307       std::cout << "Enter filled status (0 or 1)\n";
2308       cin >> isFilled;
2309
2310       // Close the local context
2311       TheAISContext()->CloseLocalContext(myCurrentIndex);
2312
2313       // Construction of the circle
2314       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
2315       gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2316       gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
2317
2318       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2319       Handle (Geom_Circle) theGeomCircle;
2320       try 
2321       {
2322         theGeomCircle = Cir.Value();
2323       }
2324       catch (StdFail_NotDone)
2325       {
2326         std::cout << "vcircle error: can't create circle\n";
2327         return -1; // TCL_ERROR
2328       }
2329
2330       DisplayCircle(theGeomCircle, aName, isFilled);
2331
2332     }
2333     // Shape is a face
2334     else
2335     {
2336       std::cout << " Select a vertex (in your face)\n";
2337       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2338
2339       TopoDS_Shape ShapeB;
2340       // Wait for picking
2341       Standard_Integer argccc = 5;
2342       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2343       const char **argvvv = (const char **) bufff;
2344       while (ViewerMainLoop( argccc, argvvv) ) { }
2345       // end of the loop
2346
2347       for(TheAISContext()->InitSelected(); 
2348         TheAISContext()->MoreSelected(); 
2349         TheAISContext()->NextSelected() ) 
2350       {
2351         ShapeB = TheAISContext()->SelectedShape();
2352       }
2353
2354       // Recover the radius 
2355       Standard_Real theRad;
2356       do 
2357       {
2358         std::cout << " Enter the value of the radius:\n";
2359         cin >> theRad;
2360       } while (theRad <= 0);
2361       
2362       // Get filled status
2363       Standard_Boolean isFilled;
2364       std::cout << "Enter filled status (0 or 1)\n";
2365       cin >> isFilled;
2366
2367       // Close the local context
2368       TheAISContext()->CloseLocalContext(myCurrentIndex);
2369       // Construction of the circle
2370
2371       // Recover the normal to the plane. tag
2372       TopoDS_Face myFace = TopoDS::Face(ShapeA);
2373       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2374       gp_Pln myPlane = mySurface.Plane();
2375       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2376       gp_Pln mygpPlane = theGeomPlane->Pln();
2377       gp_Ax1 thegpAxe = mygpPlane.Axis();
2378       gp_Dir theDir = thegpAxe.Direction();
2379
2380       // Recover the center
2381       gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2382
2383       // Construct the circle
2384       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2385       Handle (Geom_Circle) theGeomCircle;
2386       try 
2387       {
2388         theGeomCircle = Cir.Value();
2389       }
2390       catch (StdFail_NotDone)
2391       {
2392         std::cout << "vcircle error: can't create circle\n";
2393         return -1; // TCL_ERROR
2394       }
2395
2396       DisplayCircle(theGeomCircle, aName, isFilled);
2397       
2398     }
2399
2400   }
2401
2402   return 0;
2403 }
2404
2405
2406 //===============================================================================================
2407 //function : VDrawText
2408 //author   : psn
2409 //purpose  : Create a text.
2410 //Draw arg : vdrawtext  name  [X] [Y] [Z] [R] [G] [B] [hor_align] [ver_align] [angle] [zoomable]
2411 //===============================================================================================
2412 #include <Graphic3d_Group.hxx>
2413 #include <Graphic3d_Structure.hxx>
2414 #include <Graphic3d_AspectText3d.hxx>
2415 #include <Graphic3d_AspectFillArea3d.hxx>
2416 #include <Graphic3d_StructureManager.hxx>
2417 #include <Graphic3d_VerticalTextAlignment.hxx>
2418 #include <Graphic3d_HorizontalTextAlignment.hxx>
2419
2420 #include <Font_NameOfFont.hxx>
2421
2422 #include <Visual3d_ViewManager.hxx>
2423
2424 #include <Standard_DefineHandle.hxx>
2425
2426 #include <Prs3d_Root.hxx>
2427 #include <Prs3d_Text.hxx>
2428 #include <Prs3d_TextAspect.hxx>
2429 #include <Prs3d_ShadingAspect.hxx>
2430 #include <PrsMgr_PresentationManager3d.hxx>
2431
2432 #include <TCollection_ExtendedString.hxx>
2433 #include <TCollection_AsciiString.hxx>
2434
2435 #include <gp_Pnt.hxx>
2436 #include <Quantity_NameOfColor.hxx>
2437 #include <Quantity_Color.hxx>
2438
2439
2440 DEFINE_STANDARD_HANDLE(MyTextClass, AIS_InteractiveObject)
2441
2442 class MyTextClass:public AIS_InteractiveObject
2443 {
2444 public:
2445   // CASCADE RTTI
2446   DEFINE_STANDARD_RTTI(MyTextClass );
2447
2448   MyTextClass(){};
2449
2450   MyTextClass
2451     (
2452       const TCollection_ExtendedString& , const gp_Pnt& ,
2453       Quantity_Color color,
2454       Standard_Integer aHJust,
2455       Standard_Integer aVJust ,
2456       Standard_Real Angle ,
2457       Standard_Boolean Zoom ,
2458       Standard_Real  Height,
2459       Font_FontAspect FontAspect,
2460       Standard_CString Font
2461     );
2462
2463 private:
2464
2465   void Compute (  const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
2466                   const Handle(Prs3d_Presentation)& aPresentation,
2467                   const Standard_Integer aMode);
2468
2469   void ComputeSelection (  const Handle(SelectMgr_Selection)& /*aSelection*/,
2470                            const Standard_Integer /*aMode*/){} ;
2471
2472 protected:
2473   TCollection_ExtendedString          aText;
2474   gp_Pnt                              aPosition;
2475   Standard_Real                       Red;
2476   Standard_Real                       Green;
2477   Standard_Real                       Blue;
2478   Standard_Real                       aAngle;
2479   Standard_Real                       aHeight;
2480   Standard_Boolean                    aZoomable;
2481   Quantity_Color                      aColor;
2482   TCollection_AsciiString             aFont;
2483   Font_FontAspect                     aFontAspect;
2484   Graphic3d_HorizontalTextAlignment   aHJustification;
2485   Graphic3d_VerticalTextAlignment     aVJustification;
2486 };
2487
2488
2489
2490 IMPLEMENT_STANDARD_HANDLE(MyTextClass, AIS_InteractiveObject)
2491 IMPLEMENT_STANDARD_RTTIEXT(MyTextClass, AIS_InteractiveObject)
2492
2493
2494 MyTextClass::MyTextClass( const TCollection_ExtendedString& text, const gp_Pnt& position,
2495                           Quantity_Color    color       = Quantity_NOC_YELLOW,
2496                           Standard_Integer  aHJust      = Graphic3d_HTA_LEFT,
2497                           Standard_Integer  aVJust      = Graphic3d_VTA_BOTTOM,
2498                           Standard_Real     angle       = 0.0 ,
2499                           Standard_Boolean  zoomable    = Standard_True,
2500                           Standard_Real     height      = 12.,
2501                           Font_FontAspect   fontAspect  = Font_FA_Regular,
2502                           Standard_CString  font        = "Courier")
2503 {
2504   aText           = text;
2505   aPosition       = position;
2506   aHJustification = Graphic3d_HorizontalTextAlignment(aHJust);
2507   aVJustification = Graphic3d_VerticalTextAlignment(aVJust);
2508   aAngle          = angle;
2509   aZoomable       = zoomable;
2510   aHeight         = height;
2511   aColor          = color;
2512   aFontAspect     = fontAspect;
2513   aFont           = font;
2514 };
2515
2516
2517
2518 //////////////////////////////////////////////////////////////////////////////
2519 void MyTextClass::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
2520                           const Handle(Prs3d_Presentation)& aPresentation,
2521                           const Standard_Integer /*aMode*/)
2522 {
2523
2524   aPresentation->Clear();
2525
2526   Handle(Prs3d_TextAspect) asp = myDrawer->TextAspect();
2527
2528   asp->SetFont(aFont.ToCString());
2529   asp->SetColor(aColor);
2530   asp->SetHeight(aHeight); // I am changing the myHeight value
2531
2532   asp->SetHorizontalJustification(aHJustification);
2533   asp->SetVerticalJustification(aVJustification);
2534   asp->Aspect()->SetTextZoomable(aZoomable);
2535   asp->Aspect()->SetTextAngle(aAngle);
2536   asp->Aspect()->SetTextFontAspect(aFontAspect);
2537   Prs3d_Text::Draw(aPresentation, asp, aText, aPosition);
2538
2539   /* This comment code is worked
2540   Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
2541   Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
2542   Graphic3d_Vertex vertices_text;
2543   vertices_text.SetCoord(aPosition.X(),aPosition.Y(),aPosition.Y());
2544   TheGroup->SetPrimitivesAspect(aspect);
2545   TheGroup->Text(aText,vertices_text,aHeight,Standard_True);
2546   */
2547 };
2548
2549 static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2550 {
2551   // Check arguments
2552   if (argc < 14)
2553   {
2554     di<<"Error: "<<argv[0]<<" - invalid number of arguments\n";
2555     di<<"Usage: type help "<<argv[0]<<"\n";
2556     return 1; //TCL_ERROR
2557   }
2558
2559   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2560
2561   // Create 3D view if it doesn't exist
2562   if ( aContext.IsNull() )
2563   {
2564     ViewerTest::ViewerInit();
2565     aContext = ViewerTest::GetAISContext();
2566     if( aContext.IsNull() )
2567     {
2568       di << "Error: Cannot create a 3D view\n";
2569       return 1; //TCL_ERROR
2570     }
2571   }
2572
2573   // Text position
2574   const Standard_Real X = Draw::Atof(argv[2]);
2575   const Standard_Real Y = Draw::Atof(argv[3]);
2576   const Standard_Real Z = Draw::Atof(argv[4]);
2577   const gp_Pnt pnt(X,Y,Z);
2578
2579   // Text color
2580   const Quantity_Parameter R = Draw::Atof(argv[5])/255.;
2581   const Quantity_Parameter G = Draw::Atof(argv[6])/255.;
2582   const Quantity_Parameter B = Draw::Atof(argv[7])/255.;
2583   const Quantity_Color aColor( R, G, B, Quantity_TOC_RGB );
2584
2585   // Text alignment
2586   const int hor_align = Draw::Atoi(argv[8]);
2587   const int ver_align = Draw::Atoi(argv[9]);
2588
2589   // Text angle
2590   const Standard_Real angle = Draw::Atof(argv[10]);
2591
2592   // Text zooming
2593   const Standard_Boolean zoom = Draw::Atoi(argv[11]);
2594
2595   // Text height
2596   const Standard_Real height = Draw::Atof(argv[12]);
2597
2598   // Text aspect
2599   const Font_FontAspect aspect = Font_FontAspect(Draw::Atoi(argv[13]));
2600
2601   // Text font
2602   TCollection_AsciiString font;
2603   if(argc < 15)
2604     font.AssignCat("Courier");
2605   else
2606     font.AssignCat(argv[14]);
2607
2608   // Text is multibyte
2609   const Standard_Boolean isMultibyte = (argc < 16)? Standard_False : (Draw::Atoi(argv[15]) != 0);
2610
2611   // Read text string
2612   TCollection_ExtendedString name;
2613   if (isMultibyte)
2614   {
2615     const char *str = argv[1];
2616     while ( *str || *(str+1)=='\x0A' || *(str+1)=='\x0B' || *(str+1)=='\x0C' || *(str+1)=='\x0D'
2617                  || *(str+1)=='\x07' || *(str+1)=='\x08' || *(str+1)=='\x09' )
2618     {
2619       unsigned short c1 = *str++;
2620       unsigned short c2 = *str++;
2621       if (!c2) break;
2622       name += (Standard_ExtCharacter)((c1 << 8) | c2);
2623     }
2624   }
2625   else
2626   {
2627     name += argv[1];
2628   }
2629
2630   if (name.Length())
2631   {
2632     Handle(MyTextClass) myT = new MyTextClass(name,pnt,aColor,hor_align,ver_align,angle,zoom,height,aspect,font.ToCString());
2633     aContext->Display(myT,Standard_True);
2634   }
2635
2636   return 0;
2637 }
2638
2639 #include <math.h>
2640 #include <gp_Pnt.hxx>
2641 #include <Graphic3d_ArrayOfPoints.hxx>
2642 #include <Graphic3d_ArrayOfPrimitives.hxx>
2643 #include <Graphic3d_ArrayOfTriangles.hxx>
2644 #include <Poly_Array1OfTriangle.hxx>
2645 #include <Poly_Triangle.hxx>
2646 #include <Poly_Triangulation.hxx>
2647 #include <TColgp_Array1OfPnt.hxx>
2648 #include <TShort_Array1OfShortReal.hxx>
2649 #include <TShort_HArray1OfShortReal.hxx>
2650
2651 #include <AIS_Triangulation.hxx>
2652 #include <StdPrs_ToolShadedShape.hxx>
2653 #include <Poly_Connect.hxx>
2654 #include <TColgp_Array1OfDir.hxx>
2655 #include <Graphic3d_GraphicDriver.hxx>
2656
2657 #include <TColStd_Array1OfInteger.hxx>
2658 #include <TColStd_HArray1OfInteger.hxx>
2659 #include <Prs3d_ShadingAspect.hxx>
2660 #include <Graphic3d_MaterialAspect.hxx>
2661 #include <Graphic3d_AspectFillArea3d.hxx>
2662
2663 #include <BRepPrimAPI_MakeCylinder.hxx>
2664 #include <TopoDS_Shape.hxx>
2665 #include <TopExp_Explorer.hxx>
2666 #include <TopAbs.hxx>
2667 #include <StdSelect_ShapeTypeFilter.hxx>
2668
2669
2670 //===============================================================================================
2671 //function : CalculationOfSphere
2672 //author   : psn
2673 //purpose  : Create a Sphere
2674 //===============================================================================================
2675
2676 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2677                                                   int res ,
2678                                                   double Radius ){
2679   double mRadius = Radius;
2680   double mCenter[3] = {X,Y,Z};
2681   int mThetaResolution;
2682   int mPhiResolution;
2683   double mStartTheta = 0;//StartTheta;
2684   double mEndTheta = 360;//EndTheta;
2685   double mStartPhi = 0;//StartPhi;
2686   double mEndPhi = 180;//EndPhi;
2687   res = res < 4 ? 4 : res;
2688
2689   mThetaResolution = res;
2690   mPhiResolution = res;
2691
2692   int i, j;
2693   int jStart, jEnd, numOffset;
2694   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2695   double startTheta, endTheta, startPhi, endPhi;
2696   int base, numPoles=0, thetaResolution, phiResolution;
2697
2698   int pts[3];
2699   int piece = -1;
2700   int numPieces = 1;
2701   if ( numPieces > mThetaResolution ) {
2702     numPieces = mThetaResolution;
2703   }
2704
2705   int localThetaResolution =  mThetaResolution;
2706   double localStartTheta =  mStartTheta;
2707   double localEndTheta =  mEndTheta;
2708
2709   while ( localEndTheta < localStartTheta ) {
2710     localEndTheta += 360.0;
2711   }
2712
2713   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2714
2715   // Change the ivars based on pieces.
2716   int start, end;
2717   start = piece * localThetaResolution / numPieces;
2718   end = (piece+1) * localThetaResolution / numPieces;
2719   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2720   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2721   localThetaResolution = end - start;
2722
2723   // Create north pole if needed
2724   int number_point = 0;
2725   int number_pointArray = 0;
2726
2727   if ( mStartPhi <= 0.0 ) {
2728     number_pointArray++;
2729     numPoles++;
2730   }
2731   if ( mEndPhi >= 180.0 ) {
2732     number_pointArray++;
2733     numPoles++;
2734   }
2735
2736   // Check data, determine increments, and convert to radians
2737   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2738   startTheta *= M_PI  / 180.0;
2739   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2740   endTheta *= M_PI  / 180.0;
2741
2742
2743   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2744   startPhi *= M_PI  / 180.0;
2745   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2746   endPhi *= M_PI  / 180.0;
2747
2748   phiResolution =  mPhiResolution - numPoles;
2749   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2750   thetaResolution = localThetaResolution;
2751   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2752     ++localThetaResolution;
2753   }
2754   deltaTheta = (endTheta - startTheta) / thetaResolution;
2755
2756   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2757   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2758
2759   // Create intermediate points
2760   for ( i = 0; i < localThetaResolution; i++ ) {
2761     for ( j = jStart; j < jEnd; j++ ) {
2762         number_pointArray++;
2763     }
2764   }
2765
2766   //Generate mesh connectivity
2767   base = phiResolution * localThetaResolution;
2768
2769   int number_triangle = 0 ;
2770   if ( mStartPhi <= 0.0 ) { // around north pole
2771     number_triangle += localThetaResolution;
2772   }
2773
2774   if ( mEndPhi >= 180.0 ) { // around south pole
2775     number_triangle += localThetaResolution;
2776   }
2777
2778   // bands in-between poles
2779   for ( i=0; i < localThetaResolution; i++){
2780     for ( j=0; j < (phiResolution-1); j++){
2781        number_triangle +=2;
2782     }
2783   }
2784
2785   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2786   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2787   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2788
2789   if (  mStartPhi <= 0.0 ){
2790       x[0] =  mCenter[0];
2791       x[1] =  mCenter[1];
2792       x[2] =  mCenter[2] +  mRadius;
2793       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2794   }
2795
2796   // Create south pole if needed
2797   if (  mEndPhi >= 180.0 ){
2798       x[0] =  mCenter[0];
2799       x[1] =  mCenter[1];
2800       x[2] =  mCenter[2] -  mRadius;
2801       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2802   }
2803
2804   number_point = 3;
2805   for ( i=0; i < localThetaResolution; i++){
2806     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2807     for ( j = jStart; j < jEnd; j++){
2808         phi = startPhi + j*deltaPhi;
2809         radius =  mRadius * sin((double)phi);
2810         n[0] = radius * cos((double)theta);
2811         n[1] = radius * sin((double)theta);
2812         n[2] =  mRadius * cos((double)phi);
2813         x[0] = n[0] +  mCenter[0];
2814         x[1] = n[1] +  mCenter[1];
2815         x[2] = n[2] +  mCenter[2];
2816         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2817         number_point++;
2818       }
2819     }
2820
2821   numPoles = 3;
2822   number_triangle = 1;
2823   if ( mStartPhi <= 0.0 ){// around north pole
2824     for (i=0; i < localThetaResolution; i++){
2825         pts[0] = phiResolution*i + numPoles;
2826         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2827         pts[2] = 1;
2828         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2829         number_triangle++;
2830       }
2831     }
2832
2833   if (  mEndPhi >= 180.0 ){ // around south pole
2834     numOffset = phiResolution - 1 + numPoles;
2835     for (i=0; i < localThetaResolution; i++){
2836         pts[0] = phiResolution*i + numOffset;
2837         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2838         pts[1] = numPoles - 1;
2839         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2840         number_triangle++;
2841       }
2842     }
2843
2844   // bands in-between poles
2845
2846   for (i=0; i < localThetaResolution; i++){
2847     for (j=0; j < (phiResolution-1); j++){
2848         pts[0] = phiResolution*i + j + numPoles;
2849         pts[1] = pts[0] + 1;
2850         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2851         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2852         number_triangle++;
2853         pts[1] = pts[2];
2854         pts[2] = pts[1] - 1;
2855         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2856         number_triangle++;
2857       }
2858     }
2859
2860   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2861
2862   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2863
2864   Standard_Integer index[3];
2865   Standard_Real Tol = Precision::Confusion();
2866
2867   gp_Dir Nor;
2868   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2869       gp_XYZ eqPlan(0, 0, 0);
2870       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2871         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2872         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2873         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2874         gp_XYZ vv = v1^v2;
2875         Standard_Real mod = vv.Modulus();
2876         if(mod < Tol) continue;
2877         eqPlan += vv/mod;
2878       }
2879
2880       Standard_Real modmax = eqPlan.Modulus();
2881
2882       if(modmax > Tol)
2883         Nor = gp_Dir(eqPlan);
2884       else
2885         Nor = gp_Dir(0., 0., 1.);
2886
2887       Standard_Integer j = (i - PointsOfArray.Lower()) * 3;
2888       Normals->SetValue(j + 1, (Standard_ShortReal)Nor.X());
2889       Normals->SetValue(j + 2, (Standard_ShortReal)Nor.Y());
2890       Normals->SetValue(j + 3, (Standard_ShortReal)Nor.Z());
2891   }
2892
2893   delete pc;
2894   polyTriangulation->SetNormals(Normals);
2895
2896   return polyTriangulation;
2897 }
2898
2899 //===============================================================================================
2900 //function : VDrawSphere
2901 //author   : psn
2902 //purpose  : Create an AIS shape.
2903 //===============================================================================================
2904 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2905 {
2906   // check for errors
2907   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2908   if (aContextAIS.IsNull())
2909   {
2910     std::cout << "Call vinit before!\n";
2911     return 1;
2912   }
2913   else if (argc < 3)
2914   {
2915     std::cout << "Use: " << argv[0]
2916               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2917     return 1;
2918   }
2919
2920   // read the arguments
2921   TCollection_AsciiString aShapeName (argv[1]);
2922   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2923   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2924   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2925   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
2926   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
2927   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
2928   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
2929
2930   // remove AIS object with given name from map
2931   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
2932
2933   if (toPrintInfo)
2934     std::cout << "Compute Triangulation...\n";
2935   Handle(AIS_Triangulation) aShape
2936     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2937                                                   aResolution,
2938                                                   aRadius));
2939   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2940   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2941
2942   // stupid initialization of Green color in RGBA space as integer
2943   // probably wrong for big-endian CPUs
2944   Standard_Integer aRed    = 0;
2945   Standard_Integer aGreen  = 255;
2946   Standard_Integer aBlue   = 0;
2947   Standard_Integer anAlpha = 0; // not used
2948   Standard_Integer aColorInt = aRed;
2949   aColorInt += aGreen  << 8;
2950   aColorInt += aBlue   << 16;
2951   aColorInt += anAlpha << 24;
2952
2953   // setup colors array per vertex
2954   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2955   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2956   {
2957     aColorArray->SetValue (aNodeId, aColorInt);
2958   }
2959   aShape->SetColors (aColorArray);
2960
2961   // show statistics
2962   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2963   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2964   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2965   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2966   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
2967   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
2968   aTotalSize >>= 20; //MB
2969   aNormalsSize >>= 20;
2970   aColorsSize >>= 20;
2971   aTrianglesSize >>= 20;
2972   aPolyConnectSize >>= 20;
2973   if (toPrintInfo)
2974   {
2975     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
2976       << "NumberOfTriangles: " << aNumberTriangles << "\n"
2977       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
2978       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
2979       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
2980       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
2981   }
2982
2983   // Setting material properties, very important for desirable visual result!
2984   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
2985   aMat.SetAmbient (0.2);
2986   aMat.SetSpecular (0.5);
2987   Handle(Graphic3d_AspectFillArea3d) anAspect
2988     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
2989                                       Quantity_NOC_RED,
2990                                       Quantity_NOC_YELLOW,
2991                                       Aspect_TOL_SOLID,
2992                                       1.0,
2993                                       aMat,
2994                                       aMat);
2995   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
2996   if (toShowEdges)
2997   {
2998     anAspect->SetEdgeOn();
2999   }
3000   else
3001   {
3002     anAspect->SetEdgeOff();
3003   }
3004   aShAsp->SetAspect (anAspect);
3005   aShape->Attributes()->SetShadingAspect (aShAsp);
3006
3007   VDisplayAISObject (aShapeName, aShape);
3008   return 0;
3009 }
3010
3011 //=============================================================================
3012 //function : VComputeHLR
3013 //purpose  :
3014 //=============================================================================
3015
3016 static int VComputeHLR (Draw_Interpretor& di,
3017                         Standard_Integer argc,
3018                         const char** argv)
3019 {
3020   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3021
3022   if (aContextAIS.IsNull ())
3023   {
3024     di << "Please call vinit before\n";
3025     return 1;
3026   }
3027
3028   if ( argc != 3 &&  argc != 12 )
3029   {
3030     di << "Usage: " << argv[0] << " ShapeName HlrName "
3031        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]" << "\n"
3032        << "                    ShapeName - name of the initial shape\n"
3033        << "                    HlrName - result hlr object from initial shape\n"
3034        << "                    eye, dir are eye position and look direction\n"
3035        << "                    up is the look up direction vector\n"
3036        << "                    Use vtop to see projected hlr shape\n";
3037     return 1;
3038   }
3039
3040   // shape and new object name
3041   TCollection_AsciiString aShapeName (argv[1]);
3042   TCollection_AsciiString aHlrName (argv[2]);
3043
3044   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3045   if (aSh.IsNull()) 
3046   {
3047     BRep_Builder aBrepBuilder;
3048     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3049     if (aSh.IsNull ())
3050     {
3051       di << "No shape with name " << argv[1] << " found\n";
3052       return 1;
3053     }
3054   }
3055
3056   if (GetMapOfAIS ().IsBound2 (aHlrName))
3057   {
3058     di << "Presentable object with name " << argv[2] << " already exists\n";
3059     return 1;
3060   }
3061
3062   // close local context
3063   if (aContextAIS->HasOpenedContext ())
3064     aContextAIS->CloseLocalContext ();
3065
3066   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3067   HLRBRep_PolyHLRToShape aHLRToShape;
3068
3069   gp_Pnt anEye;
3070   gp_Dir aDir;
3071   gp_Ax2 aProjAx;
3072   if (argc == 9)
3073   {
3074     gp_Dir anUp;
3075
3076     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3077     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3078     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3079     aProjAx.SetLocation (anEye);
3080     aProjAx.SetDirection (aDir);
3081     aProjAx.SetYDirection (anUp);
3082   }
3083   else
3084   {
3085     gp_Dir aRight;
3086
3087     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3088     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3089     Standard_Integer aWidth, aHeight;
3090     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3091     Standard_Real aRightX, aRightY, aRightZ;
3092     aView->Window()->Size (aWidth, aHeight);
3093
3094     aView->ConvertWithProj (aWidth, aHeight/2, 
3095                             aRightX, aRightY, aRightZ,
3096                             aDirX, aDirY, aDirZ);
3097
3098     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3099                             aCentX, aCentY, aCentZ,
3100                             aDirX, aDirY, aDirZ);
3101
3102     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3103     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3104     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3105     aProjAx.SetLocation (anEye);
3106     aProjAx.SetDirection (aDir);
3107     aProjAx.SetXDirection (aRight);
3108   }
3109
3110   HLRAlgo_Projector aProjector (aProjAx);
3111   aPolyAlgo->Projector (aProjector);
3112   aPolyAlgo->Load (aSh);
3113   aPolyAlgo->Update ();
3114
3115   aHLRToShape.Update (aPolyAlgo);
3116
3117   // make hlr shape from input shape
3118   TopoDS_Compound aHlrShape;
3119   BRep_Builder aBuilder;
3120   aBuilder.MakeCompound (aHlrShape);
3121
3122   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3123   if (!aCompound.IsNull ())
3124   {
3125     aBuilder.Add (aHlrShape, aCompound);
3126   }
3127   
3128   // extract visible outlines
3129   aCompound = aHLRToShape.OutLineVCompound();
3130   if (!aCompound.IsNull ())
3131   {
3132     aBuilder.Add (aHlrShape, aCompound);
3133   }
3134
3135   // create an AIS shape and display it
3136   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3137   GetMapOfAIS().Bind (anObject, aHlrName);
3138   aContextAIS->Display (anObject);
3139
3140   aContextAIS->UpdateCurrentViewer ();
3141
3142   return 0;
3143 }
3144
3145 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3146 // manipulating and displaying such an array with AIS context
3147 DEFINE_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3148 class MyPArrayObject : public AIS_InteractiveObject
3149 {
3150
3151 public:
3152
3153   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3154                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3155   {
3156     myArrayDescription = theArrayDescription;
3157     myMarkerAspect = theMarkerAspect;
3158   }
3159
3160   DEFINE_STANDARD_RTTI(MyPArrayObject);
3161
3162 private:
3163
3164   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3165                 const Handle(Prs3d_Presentation)& aPresentation,
3166                 const Standard_Integer aMode);
3167
3168   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3169                          const Standard_Integer /*theMode*/);
3170
3171   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3172                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3173                           Standard_Integer &theArgIndex,
3174                           Standard_Integer theArgCount,
3175                           Standard_Integer theMaxArgs);
3176
3177 protected:
3178
3179   Handle(TColStd_HArray1OfAsciiString) myArrayDescription;
3180   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3181
3182 };
3183
3184 IMPLEMENT_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3185 IMPLEMENT_STANDARD_RTTIEXT(MyPArrayObject, AIS_InteractiveObject)
3186
3187 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3188                               const Handle(Prs3d_Presentation)& aPresentation,
3189                               const Standard_Integer /*aMode*/)
3190 {
3191
3192   // Parsing array description
3193   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3194   Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
3195   hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
3196
3197   Standard_Integer anArgIndex = 0;
3198   Standard_Integer anArgsCount = myArrayDescription->Length();
3199   TCollection_AsciiString anArrayType = myArrayDescription->Value (anArgIndex++);
3200
3201   TCollection_AsciiString aCommand;
3202   while (anArgIndex < anArgsCount)
3203   {
3204     aCommand = myArrayDescription->Value (anArgIndex);
3205     aCommand.LowerCase();
3206
3207     // vertex command
3208     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3209     {
3210       // vertex has a normal or normal with color or texel
3211       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3212         hasNormals = Standard_True;
3213
3214       // vertex has a color
3215       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3216         hasVColors = Standard_True;
3217
3218       // vertex has a texel
3219       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3220         hasTexels = Standard_True;
3221
3222       aVertexNum++;
3223     }
3224     // bound command
3225     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3226     {
3227       // bound has color
3228       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3229         hasBColors = Standard_True;
3230
3231       aBoundNum++;
3232     }
3233     // edge command
3234     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3235     {
3236       aEdgeNum++;
3237     }
3238     // unknown command
3239     else
3240       anArgIndex++;
3241   }
3242
3243   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3244   if (anArrayType == "points")
3245   {
3246     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3247   }
3248   else if (anArrayType == "segments")
3249     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3250   else if (anArrayType == "polylines")
3251     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3252                                               hasVColors, hasBColors);
3253   else if (anArrayType == "triangles")
3254     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3255                                               hasVColors, hasTexels);
3256   else if (anArrayType == "trianglefans")
3257     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3258                                                  hasNormals, hasVColors,
3259                                                  hasBColors, hasTexels);
3260   else if (anArrayType == "trianglestrips")
3261     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3262                                                    hasNormals, hasVColors,
3263                                                    hasBColors, hasTexels);
3264   else if (anArrayType == "quads")
3265     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3266                                                 hasNormals, hasVColors,
3267                                                 hasTexels);
3268   else if (anArrayType == "quadstrips")
3269     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3270                                                      hasNormals, hasVColors,
3271                                                      hasBColors, hasTexels);
3272   else if (anArrayType == "polygons")
3273     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3274                                              hasNormals, hasVColors, hasBColors,
3275                                              hasTexels);
3276
3277   anArgIndex = 1;
3278   while (anArgIndex < anArgsCount)
3279   {
3280     aCommand = myArrayDescription->Value (anArgIndex);
3281     aCommand.LowerCase();
3282     if (!aCommand.IsAscii())
3283       break;
3284
3285     // vertex command
3286     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3287     {
3288       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3289                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
3290                           myArrayDescription->Value (anArgIndex - 1).RealValue());
3291       const Standard_Integer aVertIndex = anArray->VertexNumber();
3292
3293       // vertex has a normal or normal with color or texel
3294       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3295         anArray->SetVertexNormal (aVertIndex,
3296                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
3297                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
3298                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
3299       
3300       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3301         anArray->SetVertexColor (aVertIndex,
3302                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
3303                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3304                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3305       
3306       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3307         anArray->SetVertexTexel (aVertIndex,
3308                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3309                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3310     }
3311     // bounds command
3312     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3313     {
3314       Standard_Integer aVertCount = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3315
3316       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3317         anArray->AddBound (aVertCount,
3318                            myArrayDescription->Value (anArgIndex - 3).RealValue(),
3319                            myArrayDescription->Value (anArgIndex - 2).RealValue(),
3320                            myArrayDescription->Value (anArgIndex - 1).RealValue());
3321
3322       else
3323         anArray->AddBound (aVertCount);
3324     }
3325     // edge command
3326     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3327     {
3328       const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3329       anArray->AddEdge (aVertIndex);
3330     }
3331     // unknown command
3332     else
3333       anArgIndex++;
3334   }
3335
3336   aPresentation->Clear();
3337   if (!myMarkerAspect.IsNull())
3338   {
3339     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
3340   }
3341   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
3342 }
3343
3344 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3345                                        const Standard_Integer /*theMode*/)
3346 {
3347   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
3348
3349   Standard_Integer anArgIndex = 1;
3350   while (anArgIndex < myArrayDescription->Length())
3351   {
3352     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, myArrayDescription->Length()))
3353     {
3354       gp_Pnt aPoint (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3355                      myArrayDescription->Value (anArgIndex - 2).RealValue(),
3356                      myArrayDescription->Value (anArgIndex - 1).RealValue());
3357       Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
3358       theSelection->Add (aSensetivePoint);
3359     }
3360     else
3361     {
3362       anArgIndex++;
3363     }
3364   }
3365 }
3366
3367 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3368                                        const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3369                                        Standard_Integer &theArgIndex,
3370                                        Standard_Integer theArgCount,
3371                                        Standard_Integer theMaxArgs)
3372 {
3373   // check if there is more elements than expected
3374   if (theArgIndex >= theMaxArgs)
3375     return false;
3376
3377   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3378   aStrCommand.LowerCase();
3379   if (aStrCommand.Search(theCommand) != 1 ||
3380       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3381     return false;
3382
3383   // go to the first data element
3384   theArgIndex++;
3385
3386   // check data if it can be converted to numeric
3387   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3388   {
3389     aStrCommand = theArgsArray->Value (theArgIndex);
3390     if (!aStrCommand.IsRealValue())
3391       return false;
3392   }
3393
3394   return true;
3395 }
3396
3397 //=============================================================================
3398 //function : VDrawPArray
3399 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3400 //=============================================================================
3401
3402 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3403 {
3404   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3405   if (aContextAIS.IsNull())
3406   {
3407     di << "Call vinit before!\n";
3408     return 1;
3409   }
3410   else if (argc < 3)
3411   {
3412     di << "Use: " << argv[0] << " Name TypeOfArray"
3413        << " [vertex] ... [bounds] ... [edges]\n"
3414        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
3415        << "                trianglefans | trianglestrips | quads |\n"
3416        << "                quadstrips | polygons }\n"
3417        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
3418        << " [texel={ 't' tx ty }] } \n"
3419        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
3420        << "  edges={ 'e' vertex_id }\n";
3421     return 1;
3422   }
3423
3424   // read the arguments
3425   Standard_Integer aArgIndex = 1;
3426   TCollection_AsciiString aName (argv[aArgIndex++]);
3427   TCollection_AsciiString anArrayType (argv[aArgIndex++]);
3428
3429   Standard_Boolean hasVertex = Standard_False;
3430
3431   Handle(TColStd_HArray1OfAsciiString) anArgsArray = new TColStd_HArray1OfAsciiString (0, argc - 2);
3432   anArgsArray->SetValue (0, anArrayType);
3433
3434   if (anArrayType != "points"         &&
3435       anArrayType != "segments"       &&
3436       anArrayType != "polylines"      &&
3437       anArrayType != "triangles"      &&
3438       anArrayType != "trianglefans"   &&
3439       anArrayType != "trianglestrips" &&
3440       anArrayType != "quads"          &&
3441       anArrayType != "quadstrips"     &&
3442       anArrayType != "polygons")
3443   {
3444     di << "Unexpected type of primitives array\n";
3445     return 1;
3446   }
3447
3448   TCollection_AsciiString aCommand;
3449   for (Standard_Integer anArgIndex = 3; anArgIndex < argc; anArgIndex++)
3450   {
3451     aCommand = argv[anArgIndex];
3452     aCommand.LowerCase();
3453     if (!aCommand.IsAscii())
3454     {
3455       di << "Unexpected argument: #" << aArgIndex - 1 << " , "
3456          << "should be an array element: 'v', 'b', 'e' \n";
3457       break;
3458     }
3459
3460     if (aCommand == "v")
3461     {
3462       hasVertex = Standard_True;
3463     }
3464
3465     anArgsArray->SetValue (anArgIndex - 2, aCommand);
3466   }
3467
3468   if (!hasVertex)
3469   {
3470     di << "You should pass any verticies in the list of array elements\n";
3471     return 1;
3472   }
3473
3474   Handle(Graphic3d_AspectMarker3d)    anAspPoints;
3475   if (anArrayType == "points")
3476   {
3477     anAspPoints = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
3478   }
3479
3480   // create primitives array object
3481   Handle(MyPArrayObject) aPObject = new MyPArrayObject (anArgsArray, anAspPoints);
3482
3483   // register the object in map
3484   VDisplayAISObject (aName, aPObject);
3485
3486   return 0;
3487 }
3488
3489 //=======================================================================
3490 //function : VSetLocation
3491 //purpose  : Change location of AIS interactive object
3492 //=======================================================================
3493
3494 static Standard_Integer VSetLocation (Draw_Interpretor& di,
3495                                       Standard_Integer argc,
3496                                       const char ** argv)
3497 {
3498   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3499   if (aContext.IsNull())
3500   {
3501     di << argv[0] << "ERROR : use 'vinit' command before " << "\n";
3502     return 1;
3503   }
3504
3505   if (argc != 5)
3506   {
3507     di << "ERROR : Usage : " << argv[0] << " name x y z; new location" << "\n";
3508     return 1;
3509   }
3510
3511   TCollection_AsciiString aName (argv[1]);
3512   Standard_Real aX = Draw::Atof (argv[2]);
3513   Standard_Real aY = Draw::Atof (argv[3]);
3514   Standard_Real aZ = Draw::Atof (argv[4]);
3515
3516   // find object
3517   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3518   Handle(AIS_InteractiveObject) anIObj;
3519   if (!aMap.IsBound2 (aName))
3520   {
3521     di << "Use 'vdisplay' before" << "\n";
3522     return 1;
3523   }
3524   else
3525   {
3526     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
3527
3528     // not an AIS_InteractiveObject
3529     if (anIObj.IsNull())
3530     {
3531       di << argv[1] << " : Not an AIS interactive object" << "\n";
3532       return 1;
3533     }
3534
3535     gp_Trsf aTrsf;
3536     aTrsf.SetTranslation (gp_Vec (aX, aY, aZ));
3537     TopLoc_Location aLocation (aTrsf);
3538     aContext->SetLocation (anIObj, aLocation);
3539     aContext->UpdateCurrentViewer();
3540   }
3541
3542   return 0;
3543 }
3544
3545 //===============================================================================================
3546 //function : VConnect
3547 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3548 //Draw arg : vconnect name Xo Yo Zo Xu Xv Xw Zu Zv Zw object1 object2 ... [color=NAME]
3549 //===============================================================================================
3550
3551 static Standard_Integer VConnect(Draw_Interpretor& /*di*/, 
3552                                  Standard_Integer argc, 
3553                                  const char ** argv) 
3554 {
3555   // Check the viewer
3556   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3557   if (aContext.IsNull())
3558   {
3559     std::cout << "vconnect error : call vinit before\n";
3560     return 1; // TCL_ERROR
3561   }
3562   // Check argumnets 
3563   if (argc < 12)
3564   {
3565     std::cout << "vconnect error: expect at least 11 arguments\n";
3566     return 1; // TCL_ERROR
3567   }
3568
3569   // Get values
3570   Standard_Integer anArgIter = 1;
3571   TCollection_AsciiString aName (argv[anArgIter++]);
3572   Handle(AIS_InteractiveObject) anOriginObject;
3573   TCollection_AsciiString aColorString (argv[argc-1]);
3574   Standard_CString aColorName = "";
3575   Standard_Boolean hasColor = Standard_False;
3576   if (aColorString.Search ("color=") != -1)
3577   {
3578     hasColor = Standard_True;
3579     aColorString.Remove (1, 6);
3580     aColorName = aColorString.ToCString();
3581   }
3582   Handle(AIS_InteractiveObject) anObject;
3583
3584   // AIS_ConnectedInteractive
3585   if (argc == 12 || (argc == 13 && hasColor))
3586   {
3587     TCollection_AsciiString anOriginObjectName(argv[11]);
3588     if (aName.IsEqual (anOriginObjectName))
3589     {
3590       std::cout << "vconnect error: equal names for connected objects\n"; 
3591       return 1; // TCL_ERROR
3592     }
3593     if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3594     {
3595       Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3596       anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3597       if (anOriginObject.IsNull())
3598       {
3599         std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3600         return 1; // TCL_ERROR
3601       }
3602     }
3603     else
3604     {
3605       Standard_CString aName = anOriginObjectName.ToCString();
3606       TopoDS_Shape aTDShape = DBRep::Get (aName);
3607       if (aTDShape.IsNull())
3608       {
3609         std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3610         return 1; // TCL_ERROR
3611       }
3612       anOriginObject = new AIS_Shape (aTDShape);
3613       if (hasColor)
3614       {
3615         anOriginObject->SetColor (ViewerTest::GetColorFromName (aColorName));
3616       }
3617     }
3618   }
3619   // AIS_MultipleConnectedInteractive
3620   else
3621   {
3622     const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
3623     for (Standard_Integer i = 11; i < aNbShapes; ++i)
3624     {
3625       TCollection_AsciiString anOriginObjectName (argv[i]);
3626       if (aName.IsEqual (anOriginObjectName))
3627       {
3628         std::cout << "vconnect error: equal names for connected objects\n";
3629         continue;
3630       }
3631       if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3632       {
3633         Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3634         anObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3635         if (anObject.IsNull())
3636         {
3637           std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3638           continue;
3639         }
3640       }
3641       else
3642       {
3643         Standard_CString aName = anOriginObjectName.ToCString();
3644         TopoDS_Shape aTDShape = DBRep::Get (aName);
3645         if (aTDShape.IsNull())
3646         {
3647           std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3648           continue;
3649         }
3650         anObject = new AIS_Shape (aTDShape);
3651         anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
3652       }
3653       if (anOriginObject.IsNull())
3654       {
3655         anOriginObject = new AIS_MultipleConnectedInteractive();
3656         Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject)->Connect (anObject);
3657       }
3658       else
3659       {
3660         Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject)->Connect (anObject);
3661       }
3662     }
3663     if (anOriginObject.IsNull())
3664     {
3665       std::cout << "vconect error : can't connect input objects\n";
3666       return 1; // TCL_ERROR
3667     }
3668   }
3669
3670   // Get location data
3671   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3672   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3673   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3674   Standard_Real aXu = Draw::Atof (argv[anArgIter++]);
3675   Standard_Real aXv = Draw::Atof (argv[anArgIter++]);
3676   Standard_Real aXw = Draw::Atof (argv[anArgIter++]);
3677   Standard_Real aZu = Draw::Atof (argv[anArgIter++]);
3678   Standard_Real aZv = Draw::Atof (argv[anArgIter++]);
3679   Standard_Real aZw = Draw::Atof (argv[anArgIter++]);
3680
3681   // Create transformation
3682   gp_Pnt aPoint(aXo, aYo, aZo);
3683   gp_Dir anXDir(aXu, aXv, aXw), aZDir(aZu, aZv, aZw);
3684   if(!anXDir.IsNormal(aZDir, Precision::Angular()))
3685   {
3686     std::cout << "vconnect error : XDir expects to be normal to ZDir\n"; 
3687     return 1; // TCL_ERROR
3688   } 
3689   gp_Ax3 anAx3(aPoint, aZDir, anXDir); 
3690   gp_Trsf aTrsf; 
3691   aTrsf.SetTransformation(anAx3); 
3692   TopLoc_Location aLocation(aTrsf);
3693
3694   // Create connected object
3695   Handle(AIS_ConnectedInteractive) aConnected = new AIS_ConnectedInteractive();
3696   Handle(AIS_MultipleConnectedInteractive) anOrigin = Handle(AIS_MultipleConnectedInteractive)::DownCast(anOriginObject);
3697   if (anOrigin.IsNull())
3698   {
3699     aConnected->Connect (anOriginObject, aLocation);
3700   }
3701   else
3702   {
3703     aConnected->Connect (anOrigin, aLocation);
3704   }
3705
3706   // Check if there is another object with given name
3707   // and remove it from context
3708   if(GetMapOfAIS().IsBound2(aName))
3709   {
3710     Handle(AIS_InteractiveObject) anObj = 
3711       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3712     TheAISContext()->Remove(anObj, Standard_False);
3713     GetMapOfAIS().UnBind2(aName);
3714   }
3715
3716   // Bind connected object to its name
3717   GetMapOfAIS().Bind (aConnected, aName);
3718
3719   // Display connected object
3720   TheAISContext()->Display (aConnected);
3721
3722   return 0;
3723 }
3724
3725 //===============================================================================================
3726 //function : VConnectShape
3727 //purpose  : Creates and displays AIS_ConnectedShape from input shape and location 
3728 //Draw arg : vconnectsh name Xo Yo Zo Xu Xv Xw Zu Zv Zw shape1 shape2 ... [color=NAME]
3729 //===============================================================================================
3730
3731 static Standard_Integer VConnectShape(Draw_Interpretor& /*di*/, 
3732                                       Standard_Integer argc, 
3733                                       const char ** argv) 
3734 {
3735   // Check the viewer
3736   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3737   if (aContext.IsNull())
3738   {
3739     std::cout << "vconnectsh error : call vinit before\n";
3740     return 1; // TCL_ERROR
3741   }
3742   // Check argumnets
3743   if (argc < 12)
3744   {
3745     std::cout << "vconnectsh error: expect at least 11 arguments\n";
3746     return 1; // TCL_ERROR
3747   }
3748
3749   // Get values
3750   Standard_Integer anArgIter = 1;
3751   TCollection_AsciiString aName (argv[anArgIter++]);
3752   Handle(AIS_InteractiveObject) anOriginShape;
3753   TCollection_AsciiString aColorString(argv[argc-1]);
3754   Standard_CString aColorName = "";
3755   Standard_Boolean hasColor = Standard_False;
3756   if (aColorString.Search ("color=") != -1)
3757   {
3758     hasColor = Standard_True;
3759     aColorString.Remove (1, 6);
3760     aColorName = aColorString.ToCString();
3761   }
3762   Handle(AIS_Shape) aShape;
3763
3764   // AIS_ConnectedShape
3765   if (argc == 12 || (argc == 13 && hasColor))
3766   {
3767     TCollection_AsciiString anOriginShapeName (argv[11]);
3768     if (aName.IsEqual (anOriginShapeName))
3769     {
3770       std::cout << "vconnectsh error: equal names for connected shapes\n";
3771       return 1; // TCL_ERROR
3772     }
3773     if (GetMapOfAIS().IsBound2 (anOriginShapeName))
3774     {
3775       Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginShapeName);
3776       anOriginShape = Handle(AIS_Shape)::DownCast(anObj);
3777       if (anOriginShape.IsNull())
3778       {
3779         std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n!";
3780         return 1; // TCL_ERROR
3781       }
3782     }
3783     else
3784     {
3785       Standard_CString aName = anOriginShapeName.ToCString();
3786       TopoDS_Shape aTDShape = DBRep::Get (aName);
3787       if (aTDShape.IsNull())
3788       {
3789         std::cout << "vconnectsh error: object " << anOriginShapeName << " doesn't exist\n";
3790         return 1; // TCL_ERROR
3791       }
3792       anOriginShape = new AIS_Shape (aTDShape);
3793       if (hasColor)
3794       {
3795         anOriginShape->SetColor (ViewerTest::GetColorFromName (aColorName));
3796       }
3797     }
3798   }
3799   // AIS_MultipleConnectedShape
3800   else
3801   {
3802     const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
3803     for (Standard_Integer i = 11; i < aNbShapes; ++i)
3804     {
3805       TCollection_AsciiString anOriginShapeName (argv[i]);
3806       if (aName.IsEqual (anOriginShapeName))
3807       {
3808         std::cout << "vconnectsh error: equal names for connected shapes\n";
3809         continue;
3810       }
3811       if (GetMapOfAIS().IsBound2 (anOriginShapeName))
3812       {
3813         Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginShapeName);
3814         aShape = Handle(AIS_Shape)::DownCast(anObj);
3815         if (aShape.IsNull())
3816         {
3817           std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n";
3818           continue;
3819         }
3820       }
3821       else
3822       {
3823         Standard_CString aName = anOriginShapeName.ToCString();
3824         TopoDS_Shape aTDShape = DBRep::Get (aName);
3825         if (aTDShape.IsNull())
3826         {
3827           std::cout << "vconnectsh error: object " << anOriginShapeName << " doesn't exist\n";
3828           continue;
3829         }
3830         aShape = new AIS_Shape (aTDShape);
3831         if (hasColor)
3832         {
3833           aShape->SetColor (ViewerTest::GetColorFromName (aColorName));
3834         }
3835       }
3836       if (anOriginShape.IsNull())
3837       {
3838         anOriginShape = new AIS_MultipleConnectedShape (aShape->Shape());
3839         Handle(AIS_MultipleConnectedShape)::DownCast(anOriginShape)->Connect (aShape);
3840       }
3841       else
3842       {
3843         Handle(AIS_MultipleConnectedShape)::DownCast(anOriginShape)->Connect (aShape);
3844       }
3845     }
3846     if (anOriginShape.IsNull())
3847     {
3848       std::cout << "vconectsh error : can't connect input objects\n";
3849       return 1; // TCL_ERROR
3850     }
3851   }
3852
3853   // Get location data  
3854   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3855   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3856   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3857   Standard_Real aXu = Draw::Atof (argv[anArgIter++]);
3858   Standard_Real aXv = Draw::Atof (argv[anArgIter++]);
3859   Standard_Real aXw = Draw::Atof (argv[anArgIter++]);
3860   Standard_Real aZu = Draw::Atof (argv[anArgIter++]);
3861   Standard_Real aZv = Draw::Atof (argv[anArgIter++]);
3862   Standard_Real aZw = Draw::Atof (argv[anArgIter++]);
3863
3864   // Create transformation
3865   gp_Pnt aPoint(aXo, aYo, aZo);
3866   gp_Dir anXDir(aXu, aXv, aXw), aZDir(aZu, aZv, aZw);
3867   if(!anXDir.IsNormal(aZDir, Precision::Angular()))
3868   {
3869     std::cout << "vconnectsh error : XDir expects to be normal to ZDir\n"; 
3870     return 1; // TCL_ERROR
3871   } 
3872   gp_Ax3 anAx3(aPoint, aZDir, anXDir); 
3873   gp_Trsf aTrsf; 
3874   aTrsf.SetTransformation(anAx3); 
3875   TopLoc_Location aLocation(aTrsf);
3876
3877   // Create connected shape
3878   Handle(AIS_ConnectedInteractive) aConnected;
3879   Handle(AIS_Shape) anOrigin = Handle(AIS_Shape)::DownCast(anOriginShape);
3880   if (!anOrigin.IsNull())
3881   {
3882     aConnected = new AIS_ConnectedShape (anOrigin);
3883     aConnected->Connect (anOrigin, aLocation);
3884   }
3885   else
3886   {
3887     aConnected = new AIS_ConnectedInteractive();
3888     aConnected->Connect (anOriginShape, aLocation);
3889   }
3890
3891   // Check if there is another object with given name
3892   // and remove it from context
3893   if(GetMapOfAIS().IsBound2(aName))
3894   {
3895     Handle(AIS_InteractiveObject) anObj = 
3896       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3897     TheAISContext()->Remove(anObj, Standard_False);
3898     GetMapOfAIS().UnBind2(aName);
3899   }
3900
3901   // Bind connected shape to its name
3902   GetMapOfAIS().Bind (aConnected, aName);
3903
3904   // Display connected shape
3905   TheAISContext()->Display (aConnected);
3906
3907   return 0;
3908 }
3909
3910 namespace
3911 {
3912   //! Checks if theMode is already turned on for theObj.
3913   static Standard_Boolean InList (const Handle(AIS_InteractiveContext)& theAISContext,
3914                                   const Handle(AIS_InteractiveObject)&  theObj,
3915                                   const Standard_Integer                theMode)
3916   {
3917     TColStd_ListOfInteger anActiveModes;
3918     theAISContext->ActivatedModes (theObj, anActiveModes);
3919     for (TColStd_ListIteratorOfListOfInteger aModeIt (anActiveModes); aModeIt.More(); aModeIt.Next())
3920     {
3921       if (aModeIt.Value() == theMode)
3922       {
3923         return Standard_True;
3924       }
3925     }
3926     return Standard_False;
3927   }
3928 };
3929
3930 //===============================================================================================
3931 //function : VSetSelectionMode
3932 //purpose  : Sets input selection mode for input object or for all displayed objects 
3933 //Draw arg : vselmode [object] mode On/Off (1/0)
3934 //===============================================================================================
3935 static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
3936                                            Standard_Integer  theArgc,
3937                                            const char**      theArgv)
3938 {
3939   // Check errors
3940   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3941   if (anAISContext.IsNull())
3942   {
3943     std::cerr << "Call vinit before!\n";
3944     return 1;
3945   }
3946
3947   // Check the arguments
3948   if (theArgc != 3 && theArgc != 4)
3949   {
3950     std::cerr << "vselmode error : expects at least 2 arguments.\n"
3951               << "Type help "<< theArgv[0] <<" for more information.";
3952     return 1;
3953   }
3954
3955   // get objects to change selection mode
3956   AIS_ListOfInteractive aTargetIOs;
3957   if (theArgc == 3)
3958   {
3959     anAISContext->DisplayedObjects (aTargetIOs);
3960   }
3961   else
3962   {
3963     // Check if there is an object with given name in context
3964     const TCollection_AsciiString aNameIO (theArgv[1]);
3965     if (GetMapOfAIS().IsBound2 (aNameIO))
3966     {
3967       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aNameIO));
3968       if (anIO.IsNull())
3969       {
3970         std::cerr << "vselmode error : object name is used for non AIS viewer\n"; 
3971         return&n