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