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