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