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