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