e68451557e0fb8df2df78661077e8150833d510f
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
1 // Created on: 1998-11-12
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ViewerTest.hxx>
18
19 #include <Quantity_NameOfColor.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <Draw.hxx>
22 #include <Draw_Appli.hxx>
23 #include <DBRep.hxx>
24
25 #include <Font_BRepFont.hxx>
26 #include <Font_FontMgr.hxx>
27 #include <OSD_Chronometer.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <Visual3d_View.hxx>
30 #include <V3d_Viewer.hxx>
31 #include <V3d_View.hxx>
32 #include <V3d.hxx>
33
34 #include <AIS_Shape.hxx>
35 #include <AIS_DisplayMode.hxx>
36 #include <AIS_PointCloud.hxx>
37 #include <TColStd_MapOfInteger.hxx>
38 #include <AIS_MapOfInteractive.hxx>
39 #include <ViewerTest_AutoUpdater.hxx>
40 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
41 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
42 #include <ViewerTest_EventManager.hxx>
43
44 #include <TopoDS_Solid.hxx>
45 #include <BRepTools.hxx>
46 #include <BRep_Builder.hxx>
47 #include <TopAbs_ShapeEnum.hxx>
48
49 #include <TopoDS.hxx>
50 #include <BRep_Tool.hxx>
51 #include <TopExp_Explorer.hxx>
52
53 #include <BRepAdaptor_Curve.hxx>
54 #include <BRepAdaptor_Surface.hxx>
55
56 #include <TopAbs.hxx>
57 #include <TopExp.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Face.hxx>
61
62 #include <Draw_Window.hxx>
63 #include <AIS_ListIteratorOfListOfInteractive.hxx>
64 #include <AIS_ListOfInteractive.hxx>
65 #include <AIS_DisplayMode.hxx>
66 #include <AIS_Shape.hxx>
67
68 #include <AIS_InteractiveContext.hxx>
69 #include <Geom_Plane.hxx>
70 #include <gp_Pln.hxx>
71 #include <TCollection_ExtendedString.hxx>
72 #include <TCollection_HAsciiString.hxx>
73 #include <GC_MakePlane.hxx>
74 #include <gp_Circ.hxx>
75 #include <AIS_Axis.hxx>
76 #include <Geom_Axis2Placement.hxx>
77 #include <Geom_Axis1Placement.hxx>
78 #include <AIS_Trihedron.hxx>
79 #include <AIS_Axis.hxx>
80 #include <gp_Trsf.hxx>
81 #include <TopLoc_Location.hxx>
82
83 #include <HLRAlgo_Projector.hxx>
84 #include <HLRBRep_PolyAlgo.hxx>
85 #include <HLRBRep_PolyHLRToShape.hxx>
86 #include <Aspect_Window.hxx>
87
88 #include <Graphic3d_ArrayOfPoints.hxx>
89 #include <Graphic3d_ArrayOfSegments.hxx>
90 #include <Graphic3d_ArrayOfPolylines.hxx>
91 #include <Graphic3d_ArrayOfTriangles.hxx>
92 #include <Graphic3d_ArrayOfTriangleFans.hxx>
93 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
94 #include <Graphic3d_ArrayOfQuadrangles.hxx>
95 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
96 #include <Graphic3d_ArrayOfPolygons.hxx>
97 #include <Graphic3d_AspectMarker3d.hxx>
98 #include <Graphic3d_Group.hxx>
99 #include <Standard_Real.hxx>
100
101 #include <AIS_Circle.hxx>
102 #include <BRepBuilderAPI_MakeEdge.hxx>
103 #include <BRepBuilderAPI_MakeFace.hxx>
104 #include <BRepBuilderAPI_MakeWire.hxx>
105 #include <Geom_Circle.hxx>
106 #include <GC_MakeCircle.hxx>
107 #include <Prs3d_Presentation.hxx>
108 #include <Select3D_SensitiveCircle.hxx>
109 #include <SelectMgr_EntityOwner.hxx>
110 #include <SelectMgr_Selection.hxx>
111 #include <StdFail_NotDone.hxx>
112 #include <StdPrs_ShadedShape.hxx>
113 #include <TopoDS_Wire.hxx>
114
115 #include <AIS_MultipleConnectedInteractive.hxx>
116 #include <AIS_ConnectedInteractive.hxx>
117 #include <AIS_TextLabel.hxx>
118 #include <TopLoc_Location.hxx>
119 #include <TColStd_ListOfInteger.hxx>
120 #include <TColStd_ListIteratorOfListOfInteger.hxx>
121
122 #include <Select3D_SensitiveTriangle.hxx>
123 #include <Select3D_SensitiveCurve.hxx>
124 #include <Select3D_SensitivePoint.hxx>
125 #include <BRepAdaptor_Curve.hxx>
126 #include <StdPrs_Curve.hxx>
127
128 #include <BRepExtrema_ExtPC.hxx>
129 #include <BRepExtrema_ExtPF.hxx>
130
131 #include <Prs3d_Drawer.hxx>
132 #include <Prs3d_VertexDrawMode.hxx>
133 #include <Prs3d_LineAspect.hxx>
134 #include <Prs3d_PointAspect.hxx>
135
136 #include <Image_AlienPixMap.hxx>
137 #include <TColStd_HArray1OfAsciiString.hxx>
138
139 #ifdef _WIN32
140 # define _CRT_SECURE_NO_DEPRECATE
141 # pragma warning (disable:4996)
142 #endif
143
144 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
145 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
146                                            const Handle(AIS_InteractiveObject)& theAISObj,
147                                            Standard_Boolean theReplaceIfExists = Standard_True);
148 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
149 extern Handle(AIS_InteractiveContext)& TheAISContext();
150
151
152 //==============================================================================
153 //function : Vtrihedron 2d
154 //purpose  : Create a plane with a 2D  trihedron from a faceselection
155 //Draw arg : vtri2d  name
156 //==============================================================================
157 #include <AIS_PlaneTrihedron.hxx>
158
159
160
161 static int VTrihedron2D (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
162
163 {
164   // Verification des arguments
165   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
166
167   // Declarations
168   Standard_Integer myCurrentIndex;
169   // Fermeture des contextes
170   TheAISContext()->CloseAllContexts();
171   // Ouverture d'un contexte local et recuperation de son index.
172   TheAISContext()->OpenLocalContext();
173   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
174   // On active les modes de selections faces.
175   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
176   di<<" Select a face ."<<"\n";
177
178   // Boucle d'attente waitpick.
179   Standard_Integer argccc = 5;
180   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
181   const char **argvvv = (const char **) bufff;
182   while (ViewerMainLoop( argccc, argvvv) ) { }
183   // fin de la boucle
184
185   TopoDS_Shape ShapeB;
186   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
187     ShapeB = TheAISContext()->SelectedShape();
188   }
189
190   TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
191
192   // Construction du Plane
193   // recuperation des edges des faces.
194   TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
195
196   TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
197   // declarations
198   gp_Pnt A,B,C;
199
200   // si il y a plusieurs edges
201   if (FaceExpB.More() ) {
202     FaceExpB.Next();
203     TopoDS_Edge EdgeC=TopoDS::Edge(FaceExpB.Current() );
204     BRepAdaptor_Curve theCurveB(EdgeB);
205     BRepAdaptor_Curve theCurveC(EdgeC);
206     A=theCurveC.Value(0.1);
207     B=theCurveC.Value(0.9);
208     C=theCurveB.Value(0.5);
209   }
210   else {
211     // FaceB a 1 unique edge courbe
212     BRepAdaptor_Curve theCurveB(EdgeB);
213     A=theCurveB.Value(0.1);
214     B=theCurveB.Value(0.9);
215     C=theCurveB.Value(0.5);
216   }
217   // Construction du Geom_Plane
218   GC_MakePlane MkPlane(A,B,C);
219   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
220
221   // Construction de l'AIS_PlaneTrihedron
222   Handle(AIS_PlaneTrihedron) theAISPlaneTri= new AIS_PlaneTrihedron(theGeomPlane );
223
224   // Fermeture du contexte local.
225   TheAISContext()->CloseLocalContext(myCurrentIndex);
226
227   // on le display & bind
228   TheAISContext()->Display(theAISPlaneTri );
229   GetMapOfAIS().Bind ( theAISPlaneTri ,argv[1]);
230
231   return 0;
232 }
233
234
235
236 //==============================================================================
237 //function : VTriherdron
238 //purpose  : Create a trihedron. If no arguments are set, the default
239 //           trihedron (Oxyz) is created.
240 //Draw arg : vtrihedron  name  [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw]
241 //==============================================================================
242
243 static int VTrihedron (Draw_Interpretor& theDi,
244                        Standard_Integer  theArgsNb,
245                        const char**      theArgVec)
246 {
247   if (theArgsNb != 2 && theArgsNb != 5 && theArgsNb != 11)
248   {
249     theDi << theArgVec[0] << " Syntax error\n";
250     return 1;
251   }
252
253   gp_Pnt anOrigin (0.0, 0.0, 0.0);
254   gp_Dir aDirZ = gp::DZ();
255   gp_Dir aDirX = gp::DX();
256   Standard_Integer anArgIter = 2; // 1st is an IO name
257   if (anArgIter < theArgsNb)
258   {
259     anOrigin.SetX (Draw::Atof (theArgVec[anArgIter++]));
260     anOrigin.SetY (Draw::Atof (theArgVec[anArgIter++]));
261     anOrigin.SetZ (Draw::Atof (theArgVec[anArgIter++]));
262     if (anArgIter < theArgsNb)
263     {
264       Standard_Real aX = Draw::Atof (theArgVec[anArgIter++]);
265       Standard_Real aY = Draw::Atof (theArgVec[anArgIter++]);
266       Standard_Real aZ = Draw::Atof (theArgVec[anArgIter++]);
267       aDirZ.SetCoord (aX, aY, aZ);
268
269       aX = Draw::Atof (theArgVec[anArgIter++]);
270       aY = Draw::Atof (theArgVec[anArgIter++]);
271       aZ = Draw::Atof (theArgVec[anArgIter++]);
272       aDirX.SetCoord (aX, aY, aZ);
273     }
274   }
275
276   if (!aDirZ.IsNormal (aDirX, M_PI / 180.0))
277   {
278     theDi << theArgVec[0] << " - VectorX is not normal to VectorZ\n";
279     return 1;
280   }
281
282   Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (anOrigin, aDirZ, aDirX);
283   Handle(AIS_Trihedron) aShape = new AIS_Trihedron (aPlacement);
284   VDisplayAISObject (theArgVec[1], aShape);
285   return 0;
286 }
287
288 //==============================================================================
289 //function : VSize
290 //author   : ege
291 //purpose  : Change the size of a named or selected trihedron
292 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
293 //           if no value, the value is set at 100 by default
294 //Draw arg : vsize [name] [size]
295 //==============================================================================
296
297 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
298
299 {
300   // Declaration de booleens
301   Standard_Boolean             ThereIsName;
302   Standard_Boolean             ThereIsCurrent;
303   Standard_Real                value;
304   Standard_Boolean             hascol;
305
306   Quantity_NameOfColor         col = Quantity_NOC_BLACK ;
307
308   // Verification des arguments
309   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error"<<"\n"; return 1;}
310
311   // Verification du nombre d'arguments
312   if (argc==1)      {ThereIsName=Standard_False;value=100;}
313   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
314   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
315
316   // On ferme le contexte local pour travailler dans le contexte global
317   if(TheAISContext()->HasOpenedContext())
318     TheAISContext()->CloseLocalContext();
319
320   // On set le booleen ThereIsCurrent
321   if (TheAISContext() -> NbCurrents() > 0) {ThereIsCurrent=Standard_True;}
322   else {ThereIsCurrent=Standard_False;}
323
324
325
326   //===============================================================
327   // Il n'y a pas de nom  mais des objets selectionnes
328   //===============================================================
329   if (!ThereIsName && ThereIsCurrent)
330   {
331
332     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
333       it (GetMapOfAIS());
334
335     while ( it.More() ) {
336
337       Handle(AIS_InteractiveObject) aShape=
338         Handle(AIS_InteractiveObject)::DownCast(it.Key1());
339
340       if (!aShape.IsNull() &&  TheAISContext()->IsCurrent(aShape) )
341       {
342
343         // On verifie que l'AIS InteraciveObject selectionne est bien
344         // un AIS_Trihedron
345         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
346
347           if (aShape->HasColor()) {
348             hascol=Standard_True;
349
350             // On recupere la couleur de aShape
351             col=aShape->Color();}
352
353           else hascol=Standard_False;
354
355           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
356           // pour lui appliquer la methode SetSize()
357           Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
358
359           // C'est bien un triedre,on chage sa valeur!
360           aTrihedron->SetSize(value);
361
362           // On donne la couleur au Trihedron
363           if(hascol)   aTrihedron->SetColor(col);
364           else         aTrihedron->UnsetColor();
365
366
367           // The trihedron hasn't be errased from the map
368           // so you just have to redisplay it
369           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
370
371         }
372
373       }
374
375       it.Next();
376     }
377
378     TheAISContext() ->UpdateCurrentViewer();
379   }
380
381   //===============================================================
382   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
383   //===============================================================
384
385
386
387   //===============================================================
388   // Il y a un nom de triedre passe en argument
389   //===============================================================
390   if (ThereIsName) {
391     TCollection_AsciiString name=argv[1];
392
393     // on verifie que ce nom correspond bien a une shape
394     Standard_Boolean IsBound= GetMapOfAIS().IsBound2(name);
395
396     if (IsBound) {
397
398       // on recupere la shape dans la map des objets displayes
399       Handle(AIS_InteractiveObject) aShape =
400         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
401
402       // On verifie que l'AIS InteraciveObject est bien
403       // un AIS_Trihedron
404       if (!aShape.IsNull() &&
405         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
406       {
407
408         if (aShape->HasColor()) {
409           hascol=Standard_True;
410
411           // On recupere la couleur de aShape
412           col=aShape->Color();}
413
414         else hascol=Standard_False;
415
416         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
417         // pour lui appliquer la methode SetSize()
418         Handle(AIS_Trihedron) aTrihedron = *(Handle(AIS_Trihedron)*) &aShape;
419
420         // C'est bien un triedre,on chage sa valeur
421         aTrihedron->SetSize(value);
422
423         // On donne la couleur au Trihedron
424         if(hascol)   aTrihedron->SetColor(col);
425         else         aTrihedron->UnsetColor();
426
427         // The trihedron hasn't be errased from the map
428         // so you just have to redisplay it
429         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
430
431         TheAISContext() ->UpdateCurrentViewer();
432       }
433     }
434   }
435   return 0;
436 }
437
438
439 //==============================================================================
440
441 //==============================================================================
442 //function : VPlaneTrihedron
443 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
444 //Draw arg : vplanetri  name
445 //==============================================================================
446 #include <AIS_Plane.hxx>
447
448
449
450 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
451
452 {
453   // Verification des arguments
454   if ( argc!=2) {di<<argv[0]<<" error"<<"\n"; return 1;}
455
456   // Declarations
457   Standard_Integer myCurrentIndex;
458   // Fermeture des contextes locaux
459   TheAISContext()->CloseAllContexts();
460
461   // On recupere tous les trihedrons de la GetMapOfAIS()
462   // et on active le mode de selection par face.
463   // =================================================
464
465   // Ouverture d'un contexte local et recuperation de son index.
466   TheAISContext()->OpenLocalContext(Standard_False);
467   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
468
469   ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
470     it (GetMapOfAIS());
471   while(it.More()){
472     Handle(AIS_InteractiveObject) ShapeA =
473       Handle(AIS_InteractiveObject)::DownCast(it.Key1());
474     // On verifie que c'est bien un trihedron
475     if (!ShapeA.IsNull() &&
476       ShapeA->Type()==AIS_KOI_Datum  && ShapeA->Signature()==3  ) {
477         // on le downcast
478         Handle(AIS_Trihedron) TrihedronA =((*(Handle(AIS_Trihedron)*)&ShapeA));
479         // on le charge dans le contexte et on active le mode Plane.
480         TheAISContext()->Load(TrihedronA,0,Standard_False);
481         TheAISContext()->Activate(TrihedronA,3);
482       }
483       it.Next();
484   }
485
486   di<<" Select a plane."<<"\n";
487   // Boucle d'attente waitpick.
488   Standard_Integer argccc = 5;
489   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
490   const char **argvvv = (const char **) bufff;
491   while (ViewerMainLoop( argccc, argvvv) ) { }
492   // fin de la boucle
493
494   Handle(AIS_InteractiveObject) theIOB;
495   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
496     theIOB = TheAISContext()->Interactive();
497   }
498   // on le downcast
499   Handle(AIS_Plane) PlaneB =((*(Handle(AIS_Plane)*)&theIOB));
500
501   // Fermeture du contexte local.
502   TheAISContext()->CloseLocalContext(myCurrentIndex);
503
504   // on le display & bind
505   TheAISContext()->Display(PlaneB );
506   GetMapOfAIS().Bind ( PlaneB ,argv[1]);
507
508   return 0;
509 }
510
511
512
513 //==============================================================================
514 // Fonction        First click      2de click
515 //
516 // vaxis           vertex           vertex
517 //                 edge             None
518 // vaxispara       edge             vertex
519 // vaxisortho      edge             Vertex
520 // vaxisinter      Face             Face
521 //==============================================================================
522
523 //==============================================================================
524 //function : VAxisBuilder
525 //purpose  :
526 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
527 //==============================================================================
528 #include <TopoDS_Edge.hxx>
529 #include <TopoDS_Vertex.hxx>
530 #include <TopExp.hxx>
531 #include <Geom_Line.hxx>
532
533 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
534 {
535   // Declarations
536   Standard_Boolean HasArg;
537   TCollection_AsciiString name;
538   Standard_Integer MyCurrentIndex;
539
540   // Verification
541   if (argc<2 || argc>8 ) {di<<" Syntaxe error"<<"\n";return 1;}
542   if (argc==8) HasArg=Standard_True;
543   else HasArg=Standard_False;
544
545   name=argv[1];
546   // Fermeture des contextes
547   TheAISContext()->CloseAllContexts();
548
549   // Cas ou il y a des arguments
550   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
551   if (HasArg) {
552     Standard_Real coord[6];
553     for(Standard_Integer i=0;i<=5;i++){
554       coord[i]=Draw::Atof(argv[2+i]);
555     }
556     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
557
558     gp_Vec myVect (p1,p2);
559     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
560     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
561     GetMapOfAIS().Bind (TheAxis,name);
562     TheAISContext()->Display(TheAxis);
563   }
564
565   // Pas d'arguments
566   else {
567     // fonction vaxis
568     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
569     if ( !strcasecmp(argv[0], "vaxis")) {
570       TheAISContext()->OpenLocalContext();
571       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
572
573       // Active le mode edge et le mode vertex
574       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
575       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
576       di<<" Select an edge or a vertex."<<"\n";
577
578       // Boucle d'attente waitpick.
579       Standard_Integer argcc = 5;
580       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
581       const char **argvv = (const char **) buff;
582       while (ViewerMainLoop( argcc, argvv) ) { }
583       // fin de la boucle
584
585       // recuperation de la shape.
586       TopoDS_Shape ShapeA;
587       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
588         ShapeA = TheAISContext()->SelectedShape();
589       }
590       // recuperation de l'AIS_InteractiveObject
591       //Handle(AIS_InteractiveObject) myAISio=TheAISContext()->Current();
592       // down cast en AIS_Point si sig et type
593       // AIS_Point -> Geom_Pnt ....
594
595       if (ShapeA.ShapeType()==TopAbs_VERTEX) {
596         // on desactive le mode edge
597         TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
598         di<<" Select a different vertex."<<"\n";
599
600         TopoDS_Shape ShapeB;
601         do {
602           // Boucle d'attente waitpick.
603           Standard_Integer argccc = 5;
604           const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
605           const char **argvvv = (const char **) bufff;
606           while (ViewerMainLoop( argccc, argvvv) ) { }
607           // fin de la boucle
608           for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
609             ShapeB = TheAISContext()->SelectedShape();
610           }
611
612
613         } while(ShapeB.IsSame(ShapeA) );
614
615         // Fermeture du context local
616         TheAISContext()->CloseLocalContext(MyCurrentIndex);
617
618         // Construction de l'axe
619         gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
620         gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
621         gp_Vec   V (A,B);
622         gp_Dir   D (V);
623         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
624         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
625         GetMapOfAIS().Bind (TheAxis,name);
626         TheAISContext()->Display(TheAxis);
627       }
628       else {
629         // Un unique edge (ShapeA) a ete picke
630         // Fermeture du context local
631         TheAISContext()->CloseLocalContext(MyCurrentIndex);
632         // Constuction de l'axe
633         TopoDS_Edge    ed =TopoDS::Edge(ShapeA);
634         TopoDS_Vertex  Va,Vb;
635         TopExp::Vertices(ed,Va,Vb );
636         gp_Pnt A=BRep_Tool::Pnt(Va);
637         gp_Pnt B=BRep_Tool::Pnt(Vb);
638         gp_Vec  V (A,B);
639         gp_Dir   D (V);
640         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
641         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
642         GetMapOfAIS().Bind (TheAxis,name);
643         TheAISContext()->Display(TheAxis);
644       }
645
646     }
647
648     // Fonction axispara
649     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
650     else if ( !strcasecmp(argv[0], "vaxispara")) {
651
652       TheAISContext()->OpenLocalContext();
653       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
654
655       // Active le mode edge
656       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
657       di<<" Select an edge."<<"\n";
658
659       // Boucle d'attente waitpick.
660       Standard_Integer argcc = 5;
661       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
662       const char **argvv = (const char **) buff;
663       while (ViewerMainLoop( argcc, argvv) ) { }
664       // fin de la boucle
665
666       TopoDS_Shape ShapeA;
667       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
668         ShapeA = TheAISContext()->SelectedShape();
669       }
670       // Active le mode vertex et deactive edges
671       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
672       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
673       di<<" Select a vertex."<<"\n";
674
675       // Boucle d'attente waitpick.
676       Standard_Integer argccc = 5;
677       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
678       const char **argvvv = (const char **) bufff;
679       while (ViewerMainLoop( argccc, argvvv) ) { }
680       // fin de la boucle
681
682       // On peut choisir un pnt sur l'edge
683       TopoDS_Shape ShapeB;
684       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
685         ShapeB = TheAISContext()->SelectedShape();
686       }
687       // Fermeture du context local
688       TheAISContext()->CloseLocalContext(MyCurrentIndex);
689
690       // Construction de l'axe
691       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
692       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
693       TopoDS_Vertex  Va,Vc;
694       TopExp::Vertices(ed,Va,Vc );
695       gp_Pnt A=BRep_Tool::Pnt(Va);
696       gp_Pnt C=BRep_Tool::Pnt(Vc);
697       gp_Vec  V (A,C);
698       gp_Dir   D (V);
699       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
700       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
701       GetMapOfAIS().Bind (TheAxis,name);
702       TheAISContext()->Display(TheAxis);
703
704     }
705
706     // Fonction axisortho
707     else  {
708       TheAISContext()->OpenLocalContext();
709       MyCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
710
711       // Active le mode edge
712       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(2) );
713       di<<" Select an edge."<<"\n";
714
715       // Boucle d'attente waitpick.
716       Standard_Integer argcc = 5;
717       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
718       const char **argvv = (const char **) buff;
719       while (ViewerMainLoop( argcc, argvv) ) { }
720       // fin de la boucle
721
722       TopoDS_Shape ShapeA;
723       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
724         ShapeA = TheAISContext()->SelectedShape();
725       }
726       // Active le mode vertex et deactive edges
727       TheAISContext()->DeactivateStandardMode(AIS_Shape::SelectionType(2) );
728       TheAISContext()->ActivateStandardMode(AIS_Shape::SelectionType(1) );
729       di<<" Slect a vertex."<<"\n";
730
731       // Boucle d'attente waitpick.
732       Standard_Integer argccc = 5;
733       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
734       const char **argvvv = (const char **) bufff;
735       while (ViewerMainLoop( argccc, argvvv) ) { }
736       // fin de la boucle
737
738       // On peut choisir un pnt sur l'edge
739       TopoDS_Shape ShapeB;
740       for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
741         ShapeB = TheAISContext()->SelectedShape();
742       }
743       // Fermeture du context local
744       TheAISContext()->CloseLocalContext(MyCurrentIndex);
745
746       // Construction de l'axe
747       TopoDS_Edge    ed=TopoDS::Edge(ShapeA) ;
748       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
749       TopoDS_Vertex  Va,Vc;
750       TopExp::Vertices(ed,Va,Vc );
751       gp_Pnt A=BRep_Tool::Pnt(Va);
752       gp_Pnt C=BRep_Tool::Pnt(Vc);
753       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
754       gp_Vec  V (A,E);
755       gp_Dir   D (V);
756       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
757       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
758       GetMapOfAIS().Bind (TheAxis,name);
759       TheAISContext()->Display(TheAxis);
760
761     }
762
763   }
764   return 0;
765 }
766
767
768 //==============================================================================
769 // Fonction        First click      Result
770 //
771 // vpoint          vertex           AIS_Point=Vertex
772 //                 edge             AIS_Point=Middle of the edge
773 //==============================================================================
774
775 //==============================================================================
776 //function : VPointBuilder
777 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
778 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
779 //==============================================================================
780 #include <TopoDS_Edge.hxx>
781 #include <TopoDS_Vertex.hxx>
782 #include <TopExp.hxx>
783 #include <AIS_Point.hxx>
784 #include <Geom_CartesianPoint.hxx>
785
786 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
787 {
788   // Declarations
789   Standard_Boolean HasArg;
790   TCollection_AsciiString name;
791   Standard_Integer myCurrentIndex;
792
793   // Verification
794   if (argc<2 || argc>5 ) {di<<" Syntaxe error"<<"\n";return 1;}
795   if (argc==5) HasArg=Standard_True;
796   else HasArg=Standard_False;
797
798   name=argv[1];
799   // Fermeture des contextes
800   TheAISContext()->CloseAllContexts();
801
802   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
803   if (HasArg) {
804     Standard_Real thecoord[3];
805     for(Standard_Integer i=0;i<=2;i++)
806       thecoord[i]=Draw::Atof(argv[2+i]);
807     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
808     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
809     GetMapOfAIS().Bind (myAISPoint,name);
810     TheAISContext()->Display(myAISPoint);
811   }
812
813   // Il n'a pas d'arguments
814   else {
815     TheAISContext()->OpenLocalContext();
816     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
817
818     // Active le mode Vertex et Edges
819     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
820     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
821     di<<" Select a vertex or an edge(build the middle)"<<"\n";
822
823     // Boucle d'attente waitpick.
824     Standard_Integer argcc = 5;
825     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
826     const char **argvv = (const char **) buff;
827     while (ViewerMainLoop( argcc, argvv) ) { }
828     // fin de la boucle
829
830     TopoDS_Shape ShapeA;
831     for (TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
832       ShapeA= TheAISContext()->SelectedShape();
833     }
834
835     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
836       // Un vertex a ete selectionne
837       // Fermeture du context local
838       TheAISContext()->CloseLocalContext(myCurrentIndex);
839
840       // Construction du point
841       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA ) );
842       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
843       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
844       GetMapOfAIS().Bind(myAISPoint,name);
845       TheAISContext()->Display(myAISPoint);
846     }
847     else {
848       // Un Edge a ete selectionne
849       // Fermeture du context local
850       TheAISContext()->CloseLocalContext(myCurrentIndex);
851
852       // Construction du point milieu de l'edge
853       TopoDS_Edge myEdge=TopoDS::Edge(ShapeA);
854       TopoDS_Vertex myVertexA,myVertexB;
855       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
856       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
857       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
858       // M est le milieu de [AB]
859       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
860       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
861       GetMapOfAIS().Bind(myAISPointM,name);
862       TheAISContext()->Display(myAISPointM);
863     }
864
865   }
866   return 0;
867
868 }
869
870 //==============================================================================
871 // Function        1st click   2de click  3de click
872 // vplane          Vertex      Vertex     Vertex
873 //                 Vertex      Edge
874 //                 Edge        Vertex
875 //                 Face
876 // vplanepara      Face        Vertex
877 //                 Vertex      Face
878 // vplaneortho     Face        Edge
879 //                 Edge        Face
880 //==============================================================================
881
882 //==============================================================================
883 //function : VPlaneBuilder
884 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
885 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
886 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
887 //                            [PlaneName] [PointName] [TypeOfSensitivity]
888 //==============================================================================
889
890 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
891                                        Standard_Integer argc,
892                                        const char** argv)
893 {
894   // Declarations
895   Standard_Boolean hasArg;
896   TCollection_AsciiString aName;
897   Standard_Integer aCurrentIndex;
898
899   // Verification
900   if (argc<2 || argc>6 )
901   {
902     std::cout<<" Syntax error\n";
903     return 1;
904   }
905   if (argc == 6 || argc==5 || argc==4)
906     hasArg=Standard_True;
907   else 
908     hasArg=Standard_False;
909
910   aName=argv[1];
911   // Close all contexts
912   TheAISContext()->CloseAllContexts();
913
914   // There are some arguments
915   if (hasArg)
916   {
917     if (!GetMapOfAIS().IsBound2(argv[2] ))
918     {
919       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
920       return 1;
921     }
922     // Get shape from map
923     Handle(AIS_InteractiveObject) aShapeA =
924       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2] ));
925
926     // The first argument is an AIS_Point
927     if (!aShapeA.IsNull() &&
928         aShapeA->Type()==AIS_KOI_Datum &&
929         aShapeA->Signature()==1)
930     {
931         // The second argument must also be an AIS_Point
932         if (argc<5 || !GetMapOfAIS().IsBound2(argv[3]))
933         {
934           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
935           return 1;
936         }
937         // Get shape from map
938         Handle(AIS_InteractiveObject) aShapeB =
939           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
940         // If B is not an AIS_Point
941         if (aShapeB.IsNull() ||
942           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
943         {
944           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
945           return 1;
946         }
947         // The third object is an AIS_Point
948         if (!GetMapOfAIS().IsBound2(argv[4]) ) 
949         {
950           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
951           return 1; 
952         }
953         // Get shape from map
954         Handle(AIS_InteractiveObject) aShapeC =
955           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
956         // If C is not an AIS_Point
957         if (aShapeC.IsNull() ||
958           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
959         {
960           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
961           return 1;
962         }
963
964         // Treatment of objects A, B, C
965         // Downcast an AIS_IO to AIS_Point
966         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
967         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
968         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
969
970         Handle(Geom_CartesianPoint ) aCartPointA = 
971           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
972
973         Handle(Geom_CartesianPoint ) aCartPointB = 
974           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
975
976         Handle(Geom_CartesianPoint ) aCartPointC = 
977           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
978
979         // Verification that the three points are different
980         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
981            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
982            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
983         {
984           // B=A
985           std::cout<<"vplane error: same points"<<"\n";return 1;
986         }
987         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
988            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
989            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
990         {
991           // C=A
992           std::cout<<"vplane error: same points"<<"\n";return 1;
993         }
994         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
995            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
996            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
997         {
998           // C=B
999           std::cout<<"vplane error: same points"<<"\n";return 1;
1000         }
1001
1002         gp_Pnt A = aCartPointA->Pnt();
1003         gp_Pnt B = aCartPointB->Pnt();
1004         gp_Pnt C = aCartPointC->Pnt();
1005
1006         // Construction of AIS_Plane
1007         GC_MakePlane MkPlane (A,B,C);
1008         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1009         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1010         GetMapOfAIS().Bind (anAISPlane,aName );
1011         if (argc == 6)
1012         {
1013           Standard_Integer aType = Draw::Atoi (argv[5]);
1014           if (aType != 0 && aType != 1)
1015           {
1016             std::cout << "vplane error: wrong type of sensitivity!\n"
1017                       << "Should be one of the following values:\n"
1018                       << "0 - Interior\n"
1019                       << "1 - Boundary"
1020                       << std::endl;
1021             return 1;
1022           }
1023           else
1024           {
1025             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1026           }
1027         }
1028         TheAISContext()->Display(anAISPlane);
1029       }
1030
1031       // The first argument is an AIS_Axis
1032       // Creation of a plane orthogonal to the axis through a point
1033     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1034       // The second argument should be an AIS_Point
1035       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3] ) )
1036       {
1037         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1038         return 1;
1039       }
1040       // Get shape from map
1041       Handle(AIS_InteractiveObject) aShapeB =
1042         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1043       // If B is not an AIS_Point
1044       if (aShapeB.IsNull() ||
1045         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1046       {
1047         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1048         return 1;
1049       }
1050
1051       // Treatment of objects A and B
1052       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1053       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1054
1055       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1056       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1057
1058       gp_Ax1 anAxis = aGeomLineA->Position();
1059       Handle(Geom_CartesianPoint) aCartPointB = 
1060         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1061
1062       gp_Dir D =anAxis.Direction();
1063       gp_Pnt B = aCartPointB->Pnt();
1064
1065       // Construction of AIS_Plane
1066       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1067       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1068       GetMapOfAIS().Bind (anAISPlane,aName );
1069       if (argc == 5)
1070       {
1071         Standard_Integer aType = Draw::Atoi (argv[4]);
1072         if (aType != 0 && aType != 1)
1073         {
1074           std::cout << "vplane error: wrong type of sensitivity!\n"
1075                     << "Should be one of the following values:\n"
1076                     << "0 - Interior\n"
1077                     << "1 - Boundary"
1078                     << std::endl;
1079           return 1;
1080         }
1081         else
1082         {
1083           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1084         }
1085       }
1086       TheAISContext()->Display(anAISPlane);
1087
1088     }
1089     // The first argumnet is an AIS_Plane
1090     // Creation of a plane parallel to the plane passing through the point
1091     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1092     {
1093       // The second argument should be an AIS_Point
1094       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3]))
1095       {
1096         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1097         return 1;
1098       }
1099       // Get shape from map
1100       Handle(AIS_InteractiveObject) aShapeB =
1101         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1102       // B should be an AIS_Point
1103       if (aShapeB.IsNull() ||
1104          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1105       {
1106         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1107         return 1;
1108       }
1109
1110       // Treatment of objects A and B
1111       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1112       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1113
1114       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1115       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1116
1117       Handle(Geom_CartesianPoint) aCartPointB = 
1118         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1119       gp_Pnt B= aCartPointB->Pnt();
1120
1121       // Construction of an AIS_Plane
1122       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1123       GetMapOfAIS().Bind (anAISPlane, aName);
1124       if (argc == 5)
1125       {
1126         Standard_Integer aType = Draw::Atoi (argv[4]);
1127         if (aType != 0 && aType != 1)
1128         {
1129           std::cout << "vplane error: wrong type of sensitivity!\n"
1130                     << "Should be one of the following values:\n"
1131                     << "0 - Interior\n"
1132                     << "1 - Boundary"
1133                     << std::endl;
1134           return 1;
1135         }
1136         else
1137         {
1138           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1139         }
1140       }
1141       TheAISContext()->Display(anAISPlane);
1142     }
1143     // Error
1144     else
1145     {
1146       std::cout<<"vplane: error 1st object is not an AIS\n";
1147       return 1;
1148     }
1149   }
1150   // There are no arguments
1151   else 
1152   {
1153     // Function vplane
1154     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1155     if (!strcasecmp(argv[0], "vplane"))
1156     {
1157       TheAISContext()->OpenLocalContext();
1158       aCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1159
1160       // Active modes Vertex, Edge and Face
1161       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1162       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1163       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1164       std::cout<<"Select a vertex, a face or an edge\n";
1165
1166       // Wait for picking
1167       Standard_Integer argcc = 5;
1168       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1169       const char **argvv = (const char **) buff;
1170       while (ViewerMainLoop( argcc, argvv) ) { }
1171       // end of the loop
1172
1173       TopoDS_Shape aShapeA;
1174       for (TheAISContext()->InitSelected();
1175            TheAISContext()->MoreSelected();
1176            TheAISContext()->NextSelected())
1177       {
1178         aShapeA = TheAISContext()->SelectedShape();
1179       }
1180
1181       // aShapeA is a Vertex
1182       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1183       {
1184         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1185         std::cout<<" Select an edge or a different vertex\n";
1186
1187         // Wait for picking
1188         Standard_Integer argccc = 5;
1189         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1190         const char **argvvv = (const char **) bufff;
1191         while (ViewerMainLoop( argccc, argvvv) ) { }
1192         // end of the loop
1193
1194         TopoDS_Shape aShapeB;
1195         for (TheAISContext()->InitSelected();
1196           TheAISContext()->MoreSelected();
1197           TheAISContext()->NextSelected())
1198         {
1199           aShapeB = TheAISContext()->SelectedShape();
1200         }
1201         // aShapeB is a Vertex
1202         if (aShapeB.ShapeType()==TopAbs_VERTEX)
1203         {
1204           // A and B are the same
1205           if (aShapeB.IsSame(aShapeA))
1206           {
1207             std::cout<<" vplane: error, same points selected\n";
1208             return 1;
1209           }
1210           TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1211           std::cout<<" Select a different vertex\n";
1212
1213           // Wait for picking
1214           Standard_Integer argcccc = 5;
1215           const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1216           const char **argvvvv = (const char **) buffff;
1217           while (ViewerMainLoop( argcccc, argvvvv) ) { }
1218           // end of the loop
1219
1220           TopoDS_Shape aShapeC;
1221           for (TheAISContext()->InitSelected();
1222                TheAISContext()->MoreSelected();
1223                TheAISContext()->NextSelected())
1224           {
1225             aShapeC = TheAISContext()->SelectedShape();
1226           }
1227           // aShapeC is the same as A or B
1228           if (aShapeC.IsSame(aShapeA)||aShapeC.IsSame(aShapeB))
1229           {
1230             std::cout<<" vplane: error, same points selected\n";
1231             return 1;
1232           }
1233
1234           // Close the local context
1235           TheAISContext()->CloseLocalContext(aCurrentIndex);
1236
1237           // Construction of plane
1238           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1239           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1240           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1241           GC_MakePlane MkPlane(A, B, C);
1242           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1243           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1244           GetMapOfAIS().Bind (anAISPlane, aName);
1245           TheAISContext()->Display(anAISPlane);
1246         }
1247         // ShapeB is an edge
1248         else
1249         {
1250           // Verify that the vertex is not on the edge ShapeB
1251           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1252           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1253
1254           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1255           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1256           {
1257             // The vertex is on the edge
1258             std::cout<<" vplane: error point is on the edge\n";
1259             return 1;
1260           }
1261           else
1262           {
1263             // Close the local context
1264             TheAISContext()->CloseLocalContext(aCurrentIndex);
1265             // Construction of plane
1266             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1267             TopoDS_Vertex aVBa, aVBb;
1268             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1269             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1270             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1271             GC_MakePlane MkPlane (A, aBa, aBb);
1272             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1273             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1274             GetMapOfAIS().Bind (anAISPlane, aName);
1275             TheAISContext()->Display(anAISPlane);
1276           }
1277         }
1278       }
1279       // aShapeA is an edge
1280       else if (aShapeA.ShapeType()==TopAbs_EDGE)
1281       {
1282         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1283         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1284         std::cout<<" Select a vertex that don't belong to the edge\n";
1285
1286         // Wait for picking
1287         Standard_Integer argccc = 5;
1288         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1289         const char **argvvv = (const char **) bufff;
1290         while (ViewerMainLoop( argccc, argvvv) ) { }
1291         // end of the loop
1292
1293         TopoDS_Shape aShapeB;
1294         for (TheAISContext()->InitSelected();
1295              TheAISContext()->MoreSelected();
1296              TheAISContext()->NextSelected())
1297         {
1298           aShapeB = TheAISContext()->SelectedShape();
1299         }
1300         // aShapeB should be a Vertex
1301         // Check that the vertex aShapeB is not on the edge
1302         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1303         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1304
1305         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1306         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1307         {
1308           // The vertex is on the edge
1309           std::cout<<" vplane: error point is on the edge\n";
1310           return 1;
1311         }
1312         else
1313         {
1314           // Close the local context
1315           TheAISContext()->CloseLocalContext(aCurrentIndex);
1316           // Construction of plane
1317           gp_Pnt B = BRep_Tool::Pnt(aVertB);
1318           TopoDS_Vertex aVAa, aVAb;
1319           TopExp::Vertices(anEdgeA, aVAa, aVAb);
1320           gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1321           gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1322           GC_MakePlane MkPlane (B,Aa,Ab);
1323           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1324           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1325           GetMapOfAIS().Bind (anAISPlane ,aName);
1326           TheAISContext()->Display(anAISPlane);
1327         }
1328       }
1329       // aShapeA is a Face
1330       else
1331       {
1332         // Close the local context: nothing to select
1333         TheAISContext()->CloseLocalContext(aCurrentIndex);
1334         // Construction of plane
1335         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1336         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1337         if (aSurface.GetType()==GeomAbs_Plane)
1338         {
1339           gp_Pln aPlane = aSurface.Plane();
1340           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1341           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1342           GetMapOfAIS().Bind (anAISPlane, aName);
1343           TheAISContext()->Display(anAISPlane);
1344         }
1345         else
1346         {
1347           std::cout<<" vplane: error\n";
1348           return 1;
1349         }
1350       }
1351     }
1352
1353     // Function vPlanePara
1354     // ===================
1355     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1356     else if (!strcasecmp(argv[0], "vplanepara"))
1357     {
1358       TheAISContext()->OpenLocalContext();
1359       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1360
1361       // Activate modes Vertex and Face
1362       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1363       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1364       std::cout<<" Select a vertex or a face\n";
1365
1366       // Wait for picking
1367       Standard_Integer argcc = 5;
1368       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1369       const char **argvv = (const char **) buff;
1370       while (ViewerMainLoop( argcc, argvv) ) { }
1371       // end of the loop
1372
1373       TopoDS_Shape aShapeA;
1374       for (TheAISContext()->InitSelected();
1375            TheAISContext()->MoreSelected();
1376            TheAISContext()->NextSelected())
1377       {
1378         aShapeA = TheAISContext()->SelectedShape();
1379       }
1380
1381       if (aShapeA.ShapeType()==TopAbs_VERTEX )
1382       {
1383         // aShapeA is a vertex
1384         // Deactivate the mode Vertex
1385         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1));
1386         std::cout<<" Select a face\n";
1387
1388         // Wait for picking
1389         Standard_Integer argccc = 5;
1390         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1391         const char **argvvv = (const char **) bufff;
1392         while (ViewerMainLoop( argccc, argvvv) ) { }
1393         // end of the loop
1394
1395         TopoDS_Shape aShapeB;
1396         for (TheAISContext()->InitSelected();
1397              TheAISContext()->MoreSelected();
1398              TheAISContext()->NextSelected())
1399         {
1400           // A vertex ShapeA can be on Face ShapeB
1401           aShapeB = TheAISContext()->SelectedShape();
1402         }
1403
1404         // Close the local context
1405         TheAISContext()->CloseLocalContext(aCurrentIndex);
1406
1407         // Construction of plane
1408         gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1409
1410         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1411         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1412         if (aSurface.GetType()==GeomAbs_Plane )
1413         {
1414           gp_Pln aPlane = aSurface.Plane();
1415           // Construct a plane parallel to aGeomPlane through A
1416           aPlane.SetLocation(A);
1417           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1418           Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1419           GetMapOfAIS().Bind (aAISPlane ,aName);
1420           TheAISContext()->Display(aAISPlane);
1421         }
1422         else
1423         {
1424           std::cout<<" vplanepara: error\n";
1425           return 1;
1426         }
1427       }
1428       else
1429       {
1430         // ShapeA is a Face
1431         // Deactive the mode Face
1432         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1433         std::cout<<" Select a vertex\n";
1434
1435         // Wait for picking
1436         Standard_Integer argccc = 5;
1437         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1438         const char **argvvv = (const char **) bufff;
1439         while (ViewerMainLoop( argccc, argvvv) ) { }
1440         // end of the loop
1441
1442         TopoDS_Shape aShapeB;
1443         for (TheAISContext()->InitSelected();
1444              TheAISContext()->MoreSelected();
1445              TheAISContext()->NextSelected())
1446         {
1447           // A vertex ShapeB can be on Face ShapeA
1448           aShapeB = TheAISContext()->SelectedShape();
1449         }
1450         // Close the local context
1451         TheAISContext()->CloseLocalContext(aCurrentIndex);
1452
1453         // Construction of plane
1454         gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1455
1456         TopoDS_Face aFace=TopoDS::Face(aShapeA);
1457         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1458         if (aSurface.GetType()==GeomAbs_Plane )
1459         {
1460           gp_Pln aPlane = aSurface.Plane();
1461           aPlane.SetLocation(B);
1462           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1463           // Construct a plane parallel to aGeomPlane through B
1464           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, B);
1465           GetMapOfAIS().Bind (anAISPlane, aName);
1466           TheAISContext()->Display(anAISPlane);
1467         }
1468         else
1469         {
1470           std::cout<<" vplanepara: error"<<"\n";return 1;
1471         }
1472       }
1473     }
1474
1475     // Function vplaneortho
1476     // ====================
1477     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1478     else
1479     {
1480       TheAISContext()->OpenLocalContext();
1481       aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1482
1483       // Activate the modes Edge and Face
1484       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1485       TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1486       std::cout<<" Select a face and an edge coplanar\n";
1487
1488       // Wait for picking
1489       Standard_Integer argcc = 5;
1490       const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1491       const char **argvv = (const char **) buff;
1492       while (ViewerMainLoop( argcc, argvv) ) { }
1493       // end of the loop
1494
1495       TopoDS_Shape aShapeA;
1496       for (TheAISContext()->InitSelected();
1497            TheAISContext()->MoreSelected();
1498            TheAISContext()->NextSelected())
1499       {
1500         aShapeA = TheAISContext()->SelectedShape();
1501       }
1502
1503       if (aShapeA.ShapeType()==TopAbs_EDGE )
1504       {
1505         // ShapeA is an edge, deactivate the mode Edge...
1506         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2));
1507         std::cout<<" Select a face\n";
1508
1509         // Wait for picking
1510         Standard_Integer argccc = 5;
1511         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1512         const char **argvvv = (const char **) bufff;
1513         while (ViewerMainLoop( argccc, argvvv) ) { }
1514         // end of the loop
1515
1516         TopoDS_Shape aShapeB;
1517         for (TheAISContext()->InitSelected();
1518              TheAISContext()->MoreSelected();
1519              TheAISContext()->NextSelected())
1520         {
1521           // Edge ShapeA can be on Face ShapeB
1522           aShapeB = TheAISContext()->SelectedShape();
1523         }
1524
1525         // Close the local context
1526         TheAISContext()->CloseLocalContext(aCurrentIndex);
1527
1528         // Construction of plane
1529         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1530         TopoDS_Vertex aVAa, aVAb;
1531         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1532         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1533         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1534         gp_Vec ab (Aa,Ab);
1535
1536         gp_Dir Dab (ab);
1537         // Creation of rotation axis
1538         gp_Ax1 aRotAxis (Aa,Dab);
1539
1540         TopoDS_Face aFace = TopoDS::Face(aShapeB);
1541         // The edge must be parallel to the face
1542         BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1543         BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1544         // Compare to heights
1545         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1546             >Precision::Confusion())
1547         {
1548           // the edge is not parallel to the face
1549           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1550           return 1;
1551         }
1552         // the edge is OK
1553         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1554         if (aSurface.GetType()==GeomAbs_Plane)
1555         {
1556           gp_Pln aPlane = aSurface.Plane();
1557           // It rotates a half turn round the axis of rotation
1558           aPlane.Rotate(aRotAxis , M_PI/2);
1559
1560           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1561           // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1562           gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1563           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1564           GetMapOfAIS().Bind (anAISPlane, aName);
1565           TheAISContext()->Display(anAISPlane);
1566         }
1567         else
1568         {
1569           std::cout<<" vplaneortho: error\n";
1570           return 1;
1571         }
1572       }
1573       else
1574       {
1575         // ShapeA is a Face, deactive the mode Face.
1576         TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4));
1577         std::cout<<" Select an edge\n";
1578
1579         // Wait for picking
1580         Standard_Integer argccc = 5;
1581         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1582         const char **argvvv = (const char **) bufff;
1583         while (ViewerMainLoop( argccc, argvvv) ) { }
1584         // end of the loop
1585
1586         TopoDS_Shape aShapeB;
1587         for (TheAISContext()->InitSelected();
1588              TheAISContext()->MoreSelected();
1589              TheAISContext()->NextSelected())
1590         {
1591           // Edge ShapeB can be on Face ShapeA
1592           aShapeB = TheAISContext()->SelectedShape();
1593         }
1594         // Close the local context
1595         TheAISContext()->CloseLocalContext(aCurrentIndex);
1596
1597         // Construction of plane
1598         TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1599         TopoDS_Vertex aVBa, aVBb;
1600         TopExp::Vertices(anEdgeB, aVBa, aVBb);
1601         gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1602         gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1603         gp_Vec ab (aBa,aBb);
1604         gp_Dir Dab (ab);
1605         // Creation of rotation axe
1606         gp_Ax1 aRotAxis (aBa,Dab);
1607
1608         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1609         // The edge must be parallel to the face
1610         BRepExtrema_ExtPF aHeightA (aVBa, aFace);
1611         BRepExtrema_ExtPF aHeightB (aVBb, aFace);
1612         // Comparing the two heights
1613         if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1614             >Precision::Confusion())
1615         {
1616           // the edge is not parallel to the face
1617           std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1618           return 1;
1619         }
1620         // The edge is OK
1621         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1622         if (aSurface.GetType()==GeomAbs_Plane)
1623         {
1624           gp_Pln aPlane = aSurface.Plane();
1625           // It rotates a half turn round the axis of rotation
1626           aPlane.Rotate(aRotAxis , M_PI/2);
1627           Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1628           // constructed aGeomPlane parallel to a plane containing the edge theGeomPlane (center mid-edge)
1629           gp_Pnt aMiddle ((aBa.X()+aBb.X() )/2 , (aBa.Y()+aBb.Y() )/2 , (aBa.Z()+aBb.Z() )/2 );
1630           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1631           GetMapOfAIS().Bind (anAISPlane ,aName);
1632           TheAISContext()->Display(anAISPlane);
1633         }
1634         else
1635         {
1636           std::cout<<" vplaneortho: error\n";
1637           return 1;
1638         }
1639       }
1640     }
1641   }
1642   return 0;
1643 }
1644
1645 //===============================================================================================
1646 //function : VChangePlane
1647 //purpose  :
1648 //===============================================================================================
1649 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1650 {
1651   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1652   if (aContextAIS.IsNull())
1653   {
1654     std::cout << theArgVec[0] << "AIS context is not available.\n";
1655     return 1;
1656   }
1657
1658   if (theArgsNb < 3 || theArgsNb > 11)
1659   {
1660     std::cerr << theArgVec[0] 
1661               << ": incorrect number of command arguments.\n"
1662               << "Type help for more information.\n";
1663     return 1;
1664   }
1665
1666   TCollection_AsciiString aName (theArgVec[1]);
1667
1668   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1669     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1670     : NULL;
1671
1672   if ( aPlane.IsNull() )
1673   {
1674     std::cout << theArgVec[0] 
1675               << ": there is no interactive plane with the given name."
1676               << "Type help for more information.\n";
1677     return 1;
1678   }
1679
1680   Standard_Real aCenterX = aPlane->Center().X();
1681   Standard_Real aCenterY = aPlane->Center().Y();
1682   Standard_Real aCenterZ = aPlane->Center().Z();
1683
1684   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1685   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1686   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1687
1688   Standard_Real aSizeX = 0.0;
1689   Standard_Real aSizeY = 0.0;
1690   aPlane->Size (aSizeX, aSizeY);
1691   Standard_Boolean isUpdate = Standard_True;
1692
1693   TCollection_AsciiString aPName, aPValue;
1694   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1695   {
1696     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1697     TCollection_AsciiString anArgCase = anArg;
1698     anArgCase.UpperCase();
1699     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1700     {
1701       aPName.UpperCase();
1702       if (aPName.IsEqual ("X"))
1703       {
1704         aCenterX = aPValue.RealValue();
1705       }
1706       else if (aPName.IsEqual ("Y"))
1707       {
1708         aCenterY = aPValue.RealValue();
1709       }
1710       else if (aPName.IsEqual ("Z"))
1711       {
1712         aCenterZ = aPValue.RealValue();
1713       }
1714       else if (aPName.IsEqual ("DX"))
1715       {
1716         aDirX = aPValue.RealValue();
1717       }
1718       else if (aPName.IsEqual ("DY"))
1719       {
1720         aDirY = aPValue.RealValue();
1721       }
1722       else if (aPName.IsEqual ("DZ"))
1723       {
1724         aDirZ = aPValue.RealValue();
1725       }
1726       else if (aPName.IsEqual ("SX"))
1727       {
1728         aSizeX = aPValue.RealValue();
1729       }
1730       else if (aPName.IsEqual ("SY"))
1731       {
1732         aSizeY = aPValue.RealValue();
1733       }
1734     }
1735     else if (anArg.IsEqual ("NOUPDATE"))
1736     {
1737       isUpdate = Standard_False;
1738     }
1739   }
1740
1741   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1742   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1743   aPlane->SetCenter (aCenterPnt);
1744   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1745   aPlane->SetSize (aSizeX, aSizeY);
1746
1747   aContextAIS->Update (aPlane, isUpdate);
1748
1749   return 0;
1750 }
1751
1752 //==============================================================================
1753 // Fonction  vline
1754 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1755 //==============================================================================
1756
1757 //==============================================================================
1758 //function : VLineBuilder
1759 //purpose  : Build an AIS_Line
1760 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1761 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1762 //==============================================================================
1763 #include <Geom_CartesianPoint.hxx>
1764 #include <AIS_Line.hxx>
1765
1766
1767 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1768 {
1769   Standard_Integer myCurrentIndex;
1770   // Verifications
1771   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct "<<"\n";return 1; }
1772   // Fermeture des contextes
1773   TheAISContext()->CloseAllContexts();
1774
1775   // On recupere les parametres
1776   Handle(AIS_InteractiveObject) theShapeA;
1777   Handle(AIS_InteractiveObject) theShapeB;
1778
1779   // Parametres: AIS_Point AIS_Point
1780   // ===============================
1781   if (argc==4) {
1782     theShapeA=
1783       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
1784     // On verifie que c'est bien une AIS_Point
1785     if (!theShapeA.IsNull() &&
1786       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1787         // on recupere le deuxieme AIS_Point
1788         theShapeB=
1789           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1790         if (theShapeA.IsNull() ||
1791           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1792         {
1793           di <<"vline error: wrong type of 2de argument."<<"\n";
1794           return 1;
1795         }
1796       }
1797     else {di <<"vline error: wrong type of 1st argument."<<"\n";return 1; }
1798     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1799     Handle(AIS_Point) theAISPointA= *(Handle(AIS_Point)*)& theShapeA;
1800     Handle(AIS_Point) theAISPointB= *(Handle(AIS_Point)*)& theShapeB;
1801
1802     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1803     Handle(Geom_CartesianPoint ) myCartPointA= *((Handle(Geom_CartesianPoint)*)&  myGeomPointBA);
1804     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1805
1806     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1807     Handle(Geom_CartesianPoint ) myCartPointB= *((Handle(Geom_CartesianPoint)*)&  myGeomPointB);
1808     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1809
1810     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1811       // B=A
1812       di<<"vline error: same points"<<"\n";return 1;
1813     }
1814     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1815     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1816     GetMapOfAIS().Bind(theAISLine,argv[1] );
1817     TheAISContext()->Display(theAISLine );
1818
1819   }
1820
1821   // Parametres 6 Reals
1822   // ==================
1823
1824   else if (argc==8) {
1825     // On verifie que les deux points ne sont pas confondus
1826
1827     Standard_Real coord[6];
1828     for(Standard_Integer i=0;i<=2;i++){
1829       coord[i]=Draw::Atof(argv[2+i]);
1830       coord[i+3]=Draw::Atof(argv[5+i]);
1831     }
1832
1833     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1834     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1835
1836     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1837     GetMapOfAIS().Bind(theAISLine,argv[1] );
1838     TheAISContext()->Display(theAISLine );
1839
1840   }
1841
1842   // Pas de parametres: Selection dans le viewer.
1843   // ============================================
1844
1845   else {
1846     TheAISContext()->OpenLocalContext();
1847     myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1848
1849     // Active le mode Vertex.
1850     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1851     di<<" Select a vertex "<<"\n";
1852
1853     // Boucle d'attente waitpick.
1854     Standard_Integer argcc = 5;
1855     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1856     const char **argvv = (const char **) buff;
1857     while (ViewerMainLoop( argcc, argvv) ) { }
1858     // fin de la boucle
1859
1860     TopoDS_Shape ShapeA;
1861     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1862       ShapeA = TheAISContext()->SelectedShape();
1863     }
1864
1865     // ShapeA est un Vertex
1866     if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
1867
1868       di<<" Select a different vertex."<<"\n";
1869
1870       TopoDS_Shape ShapeB;
1871       do {
1872
1873         // Boucle d'attente waitpick.
1874         Standard_Integer argccc = 5;
1875         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1876         const char **argvvv = (const char **) bufff;
1877         while (ViewerMainLoop( argccc, argvvv) ) { }
1878         // fin de la boucle
1879
1880         for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1881           ShapeB = TheAISContext()->SelectedShape();
1882         }
1883
1884
1885       } while(ShapeB.IsSame(ShapeA) );
1886
1887       // Fermeture du context local
1888       TheAISContext()->CloseLocalContext(myCurrentIndex);
1889
1890       // Construction de la line
1891       gp_Pnt   A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA)  );
1892       gp_Pnt   B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB)  );
1893
1894       Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1895       Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1896
1897       Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1898       GetMapOfAIS().Bind(theAISLine,argv[1] );
1899       TheAISContext()->Display(theAISLine );
1900
1901     }
1902     else  {
1903       di<<"vline error."<<"\n";
1904     }
1905
1906   }
1907
1908   return 0;
1909 }
1910
1911 //==============================================================================
1912 // class   : FilledCircle
1913 // purpose : creates filled circle based on AIS_InteractiveObject 
1914 //           and Geom_Circle.
1915 //           This class is used to check method Matches() of class 
1916 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1917 //           because none of AIS classes provides creation of 
1918 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1919 //           (look method ComputeSelection() )
1920 //============================================================================== 
1921
1922 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1923 {
1924   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
1925   gp_Circ aCirc(anAxes, theRadius);
1926   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
1927   return aCircle;
1928 }
1929
1930 DEFINE_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1931
1932 class FilledCircle : public AIS_InteractiveObject 
1933 {
1934 public:
1935     // CASCADE RTTI
1936     DEFINE_STANDARD_RTTI(FilledCircle); 
1937
1938     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1939     FilledCircle(Handle(Geom_Circle) theCircle);
1940
1941 private:
1942     TopoDS_Face ComputeFace();
1943
1944     // Virtual methods implementation
1945     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1946                   const Handle(Prs3d_Presentation)& thePresentation,
1947                   const Standard_Integer theMode);
1948
1949     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1950                            const Standard_Integer theMode);
1951
1952 protected:
1953     Handle(Geom_Circle) myCircle;
1954     Standard_Boolean myFilledStatus;
1955
1956 }; 
1957
1958 IMPLEMENT_STANDARD_HANDLE(FilledCircle, AIS_InteractiveObject)
1959 IMPLEMENT_STANDARD_RTTIEXT(FilledCircle, AIS_InteractiveObject)
1960
1961 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1962 {
1963   myCircle = CreateCircle(theCenter, theRadius);
1964   myFilledStatus = Standard_True;
1965 }
1966
1967 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1968 {
1969   myCircle = theCircle;
1970   myFilledStatus = Standard_True;
1971 }
1972
1973 TopoDS_Face FilledCircle::ComputeFace() 
1974 {
1975   // Create edge from myCircle 
1976   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1977   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1978
1979   // Create wire from anEdge 
1980   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1981   TopoDS_Wire aWire = aWireMaker.Wire();
1982
1983   // Create face from aWire
1984   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1985   TopoDS_Face aFace = aFaceMaker.Face();
1986
1987   return aFace;
1988 }
1989
1990 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
1991                            const Handle(Prs3d_Presentation) &thePresentation, 
1992                            const Standard_Integer theMode) 
1993 {
1994   thePresentation->Clear();
1995
1996   TopoDS_Face aFace = ComputeFace();
1997
1998   if (aFace.IsNull()) return;
1999   if (theMode != 0) return;
2000
2001   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
2002 }
2003
2004 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2005                                     const Standard_Integer /*theMode*/)
2006 {
2007   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2008   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2009       myCircle, myFilledStatus);
2010   theSelection->Add(aSensitiveCircle);
2011 }
2012
2013 //==============================================================================
2014 // Fonction  vcircle
2015 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2016 //==============================================================================
2017
2018 //==============================================================================
2019 //function : VCircleBuilder
2020 //purpose  : Build an AIS_Circle
2021 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2022 //                              PointName PointName PointName IsFilled
2023 //==============================================================================
2024
2025 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2026                     TCollection_AsciiString theName, 
2027                     Standard_Boolean isFilled) 
2028 {
2029   Handle(AIS_InteractiveObject) aCircle;
2030   if (isFilled) 
2031   {
2032     aCircle = new FilledCircle(theGeomCircle);
2033   }
2034   else
2035   {
2036     aCircle = new AIS_Circle(theGeomCircle);
2037     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2038   }
2039
2040   // Check if there is an object with given name
2041   // and remove it from context
2042   if (GetMapOfAIS().IsBound2(theName)) 
2043   {
2044     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
2045     Handle(AIS_InteractiveObject) anInterObj = 
2046          Handle(AIS_InteractiveObject)::DownCast(anObj);
2047     TheAISContext()->Remove(anInterObj, Standard_False);
2048     GetMapOfAIS().UnBind2(theName);
2049    }
2050
2051    // Bind the circle to its name
2052    GetMapOfAIS().Bind(aCircle, theName);
2053
2054    // Display the circle
2055    TheAISContext()->Display(aCircle);
2056   
2057 }
2058
2059 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2060 {
2061   Standard_Integer myCurrentIndex;
2062   // Verification of the arguments
2063   if (argc>6 || argc<2) 
2064   { 
2065     std::cout << "vcircle error: expect 4 arguments.\n"; 
2066     return 1; // TCL_ERROR 
2067   }
2068   TheAISContext()->CloseAllContexts();
2069
2070   // There are all arguments
2071   if (argc == 6) 
2072   {
2073     // Get arguments
2074     TCollection_AsciiString aName(argv[1]);
2075     Standard_Boolean isFilled = (Standard_Boolean)Draw::Atoi(argv[5]);
2076
2077     Handle(AIS_InteractiveObject) theShapeA;
2078     Handle(AIS_InteractiveObject) theShapeB;
2079
2080     theShapeA =
2081       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2082     theShapeB =
2083       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2084
2085
2086     // Arguments: AIS_Point AIS_Point AIS_Point
2087     // ========================================
2088     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2089       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2090     {
2091       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2092       {
2093         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2094         return 1; // TCL_ERROR 
2095       }
2096       // The third object must be a point
2097       Handle(AIS_InteractiveObject) theShapeC =
2098         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2099       if (theShapeC.IsNull() ||
2100         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2101       {
2102         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2103         return 1; // TCL_ERROR 
2104       }
2105         // tag
2106         // Verify that the three points are different
2107         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2108         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2109         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2110         
2111         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2112         Handle(Geom_CartesianPoint) myCartPointA = 
2113           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2114
2115         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2116         Handle(Geom_CartesianPoint) myCartPointB =
2117           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2118
2119         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2120         Handle(Geom_CartesianPoint) myCartPointC =
2121           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2122
2123         // Test A=B
2124         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2125             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2126             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2127         {
2128           std::cout << "vcircle error: Same points.\n"; 
2129           return 1; // TCL_ERROR 
2130         }
2131         // Test A=C
2132         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2133             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2134             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2135         {
2136           std::cout << "vcircle error: Same points.\n"; 
2137           return 1; // TCL_ERROR 
2138         }
2139         // Test B=C
2140         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2141             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2142             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2143         {
2144           std::cout << "vcircle error: Same points.\n"; 
2145           return 1;// TCL_ERROR 
2146         }
2147         // Construction of the circle
2148         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2149           myCartPointB->Pnt(), myCartPointC->Pnt() );
2150         Handle (Geom_Circle) theGeomCircle;
2151         try 
2152         {
2153           theGeomCircle = Cir.Value();
2154         }
2155         catch (StdFail_NotDone)
2156         {
2157           std::cout << "vcircle error: can't create circle\n";
2158           return -1; // TCL_ERROR
2159         }
2160         
2161         DisplayCircle(theGeomCircle, aName, isFilled);
2162     }
2163
2164     // Arguments: AIS_Plane AIS_Point Real
2165     // ===================================
2166     else if (theShapeA->Type() == AIS_KOI_Datum && 
2167       theShapeA->Signature() == 7 ) 
2168     {
2169       if (theShapeB->Type() != AIS_KOI_Datum || 
2170         theShapeB->Signature() != 1 ) 
2171       {
2172         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2173         return 1; // TCL_ERROR 
2174       }
2175       // Check that the radius is >= 0
2176       if (Draw::Atof(argv[4]) <= 0 ) 
2177       {
2178         std::cout << "vcircle error: the radius must be >=0.\n"; 
2179         return 1; // TCL_ERROR 
2180       }
2181
2182       // Recover the normal to the plane
2183       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2184       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2185
2186       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2187       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2188       Handle(Geom_CartesianPoint) myCartPointB = 
2189         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2190
2191       gp_Pln mygpPlane = myGeomPlane->Pln();
2192       gp_Ax1 thegpAxe = mygpPlane.Axis();
2193       gp_Dir theDir = thegpAxe.Direction();
2194       gp_Pnt theCenter = myCartPointB->Pnt();
2195       Standard_Real TheR = Draw::Atof(argv[4]);
2196       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2197       Handle (Geom_Circle) theGeomCircle;
2198       try 
2199       {
2200         theGeomCircle = Cir.Value();
2201       }
2202       catch (StdFail_NotDone)
2203       {
2204         std::cout << "vcircle error: can't create circle\n";
2205         return -1; // TCL_ERROR
2206       }
2207
2208       DisplayCircle(theGeomCircle, aName, isFilled);
2209
2210     }
2211
2212     // Error
2213     else
2214     {
2215       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2216       return 1; // TCL_ERROR 
2217     }
2218
2219   }
2220   // No arguments: selection in the viewer
2221   // =========================================
2222   else 
2223   {
2224     // Get the name of the circle 
2225     TCollection_AsciiString aName(argv[1]);
2226
2227     TheAISContext()->OpenLocalContext();
2228     myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
2229
2230     // Activate selection mode for vertices and faces
2231     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2232     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2233     std::cout << " Select a vertex or a face\n";
2234
2235     // Wait for picking
2236     Standard_Integer argcc = 5;
2237     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2238     const char **argvv = (const char **) buff;
2239     while (ViewerMainLoop( argcc, argvv) ) { }
2240     // end of the loop
2241
2242     TopoDS_Shape ShapeA;
2243     for(TheAISContext()->InitSelected(); 
2244       TheAISContext()->MoreSelected(); 
2245       TheAISContext()->NextSelected() ) 
2246     {
2247       ShapeA = TheAISContext()->SelectedShape();
2248     }
2249
2250     // ShapeA is a Vertex
2251     if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
2252     {
2253       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2254       std::cout << " Select a different vertex\n";
2255
2256       TopoDS_Shape ShapeB;
2257       do 
2258       {
2259         // Wait for picking
2260         Standard_Integer argccc = 5;
2261         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2262         const char **argvvv = (const char **) bufff;
2263         while (ViewerMainLoop( argccc, argvvv) ) { }
2264         // end of the loop
2265
2266         for(TheAISContext()->InitSelected(); 
2267           TheAISContext()->MoreSelected(); 
2268           TheAISContext()->NextSelected() ) 
2269         {
2270           ShapeB = TheAISContext()->SelectedShape();
2271         }
2272       } while(ShapeB.IsSame(ShapeA) );
2273
2274       // Selection of ShapeC
2275       std::cout << " Select the last vertex\n";
2276       TopoDS_Shape ShapeC;
2277       do 
2278       {
2279         // Wait for picking
2280         Standard_Integer argcccc = 5;
2281         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2282         const char **argvvvv = (const char **) buffff;
2283         while (ViewerMainLoop( argcccc, argvvvv) ) { }
2284         // end of the loop
2285
2286         for(TheAISContext()->InitSelected(); 
2287           TheAISContext()->MoreSelected(); 
2288           TheAISContext()->NextSelected() ) 
2289         {
2290           ShapeC = TheAISContext()->SelectedShape();
2291         }
2292       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
2293       
2294       // Get isFilled
2295       Standard_Boolean isFilled;
2296       std::cout << "Enter filled status (0 or 1)\n";
2297       cin >> isFilled;
2298
2299       // Close the local context
2300       TheAISContext()->CloseLocalContext(myCurrentIndex);
2301
2302       // Construction of the circle
2303       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
2304       gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2305       gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
2306
2307       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2308       Handle (Geom_Circle) theGeomCircle;
2309       try 
2310       {
2311         theGeomCircle = Cir.Value();
2312       }
2313       catch (StdFail_NotDone)
2314       {
2315         std::cout << "vcircle error: can't create circle\n";
2316         return -1; // TCL_ERROR
2317       }
2318
2319       DisplayCircle(theGeomCircle, aName, isFilled);
2320
2321     }
2322     // Shape is a face
2323     else
2324     {
2325       std::cout << " Select a vertex (in your face)\n";
2326       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2327
2328       TopoDS_Shape ShapeB;
2329       // Wait for picking
2330       Standard_Integer argccc = 5;
2331       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2332       const char **argvvv = (const char **) bufff;
2333       while (ViewerMainLoop( argccc, argvvv) ) { }
2334       // end of the loop
2335
2336       for(TheAISContext()->InitSelected(); 
2337         TheAISContext()->MoreSelected(); 
2338         TheAISContext()->NextSelected() ) 
2339       {
2340         ShapeB = TheAISContext()->SelectedShape();
2341       }
2342
2343       // Recover the radius 
2344       Standard_Real theRad;
2345       do 
2346       {
2347         std::cout << " Enter the value of the radius:\n";
2348         cin >> theRad;
2349       } while (theRad <= 0);
2350       
2351       // Get filled status
2352       Standard_Boolean isFilled;
2353       std::cout << "Enter filled status (0 or 1)\n";
2354       cin >> isFilled;
2355
2356       // Close the local context
2357       TheAISContext()->CloseLocalContext(myCurrentIndex);
2358       // Construction of the circle
2359
2360       // Recover the normal to the plane. tag
2361       TopoDS_Face myFace = TopoDS::Face(ShapeA);
2362       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2363       gp_Pln myPlane = mySurface.Plane();
2364       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2365       gp_Pln mygpPlane = theGeomPlane->Pln();
2366       gp_Ax1 thegpAxe = mygpPlane.Axis();
2367       gp_Dir theDir = thegpAxe.Direction();
2368
2369       // Recover the center
2370       gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2371
2372       // Construct the circle
2373       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2374       Handle (Geom_Circle) theGeomCircle;
2375       try 
2376       {
2377         theGeomCircle = Cir.Value();
2378       }
2379       catch (StdFail_NotDone)
2380       {
2381         std::cout << "vcircle error: can't create circle\n";
2382         return -1; // TCL_ERROR
2383       }
2384
2385       DisplayCircle(theGeomCircle, aName, isFilled);
2386       
2387     }
2388
2389   }
2390
2391   return 0;
2392 }
2393
2394 //=======================================================================
2395 //function : VDrawText
2396 //purpose  :
2397 //=======================================================================
2398 static int VDrawText (Draw_Interpretor& theDI,
2399                       Standard_Integer  theArgsNb,
2400                       const char**      theArgVec)
2401 {
2402   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2403   if (theArgsNb < 3)
2404   {
2405     std::cout << "Error: wrong number of arguments! See usage:\n";
2406     theDI.PrintHelp (theArgVec[0]);
2407     return 1;
2408   }
2409   else if (aContext.IsNull())
2410   {
2411     std::cout << "Error: no active view!\n";
2412     return 1;
2413   }
2414
2415   Standard_Integer           anArgIt = 1;
2416   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2417   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2418   Handle(AIS_TextLabel)      aTextPrs;
2419   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2420
2421   if (GetMapOfAIS().IsBound2 (aName))
2422   {
2423     aTextPrs  = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2424   }
2425   else
2426   {
2427     aTextPrs = new AIS_TextLabel();
2428     aTextPrs->SetFont ("Courier");
2429   }
2430
2431   aTextPrs->SetText (aText);
2432
2433   for (; anArgIt < theArgsNb; ++anArgIt)
2434   {
2435     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2436     aParam.LowerCase();
2437
2438     if (anAutoUpdater.parseRedrawMode (aParam))
2439     {
2440       continue;
2441     }
2442     else if (aParam == "-pos"
2443           || aParam == "-position")
2444     {
2445       if (anArgIt + 3 >= theArgsNb)
2446       {
2447         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2448         return 1;
2449       }
2450
2451       gp_Pnt aPos;
2452       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2453       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2454       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2455       aTextPrs->SetPosition (aPos);
2456     }
2457     else if (aParam == "-color")
2458     {
2459       if (anArgIt + 1 >= theArgsNb)
2460       {
2461         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2462         return 1;
2463       }
2464
2465       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2466       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2467       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2468       {
2469         anArgIt += 1;
2470         aTextPrs->SetColor (aNameOfColor);
2471         continue;
2472       }
2473       else if (anArgIt + 3 >= theArgsNb)
2474       {
2475         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2476         return 1;
2477       }
2478
2479       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2480       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2481       if (!aColor.IsRealValue()
2482        || !aGreen.IsRealValue()
2483        || !aBlue.IsRealValue())
2484       {
2485         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2486         return 1;
2487       }
2488
2489       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2490                                    aGreen.RealValue(),
2491                                    aBlue.RealValue());
2492
2493       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2494       anArgIt += 3;
2495     }
2496     else if (aParam == "-halign")
2497     {
2498       if (++anArgIt >= theArgsNb)
2499       {
2500         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2501         return 1;
2502       }
2503
2504       TCollection_AsciiString aType (theArgVec[anArgIt]);
2505       aType.LowerCase();
2506       if (aType == "left")
2507       {
2508         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2509       }
2510       else if (aType == "center")
2511       {
2512         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2513       }
2514       else if (aType == "right")
2515       {
2516         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2517       }
2518       else
2519       {
2520         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2521         return 1;
2522       }
2523     }
2524     else if (aParam == "-valign")
2525     {
2526       if (++anArgIt >= theArgsNb)
2527       {
2528         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2529         return 1;
2530       }
2531
2532       TCollection_AsciiString aType (theArgVec[anArgIt]);
2533       aType.LowerCase();
2534       if (aType == "top")
2535       {
2536         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2537       }
2538       else if (aType == "center")
2539       {
2540         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2541       }
2542       else if (aType == "bottom")
2543       {
2544         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2545       }
2546       else
2547       {
2548         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2549         return 1;
2550       }
2551     }
2552     else if (aParam == "-angle")
2553     {
2554       if (++anArgIt >= theArgsNb)
2555       {
2556         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2557         return 1;
2558       }
2559
2560       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2561     }
2562     else if (aParam == "-zoom")
2563     {
2564       if (++anArgIt >= theArgsNb)
2565       {
2566         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2567         return 1;
2568       }
2569
2570       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2571     }
2572     else if (aParam == "-height")
2573     {
2574       if (++anArgIt >= theArgsNb)
2575       {
2576         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2577         return 1;
2578       }
2579
2580       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2581     }
2582     else if (aParam == "-aspect")
2583     {
2584       if (++anArgIt >= theArgsNb)
2585       {
2586         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2587         return 1;
2588       }
2589
2590       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2591       anOption.LowerCase();
2592       if (anOption.IsEqual ("regular"))
2593       {
2594         aTextPrs->SetFontAspect (Font_FA_Regular);
2595       }
2596       else if (anOption.IsEqual ("bold"))
2597       {
2598         aTextPrs->SetFontAspect (Font_FA_Bold);
2599       }
2600       else if (anOption.IsEqual ("italic"))
2601       {
2602         aTextPrs->SetFontAspect (Font_FA_Italic);
2603       }
2604       else if (anOption.IsEqual ("bolditalic"))
2605       {
2606         aTextPrs->SetFontAspect (Font_FA_BoldItalic);
2607       }
2608     }
2609     else if (aParam == "-font")
2610     {
2611       if (++anArgIt >= theArgsNb)
2612       {
2613         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2614         return 1;
2615       }
2616
2617       aTextPrs->SetFont (theArgVec[anArgIt]);
2618     }
2619     else
2620     {
2621       std::cout << "Error: unknown argument '" << aParam << "'\n";
2622       return 1;
2623     }
2624   }
2625
2626   ViewerTest::Display (aName, aTextPrs, Standard_False);
2627   return 0;
2628 }
2629
2630 #include <math.h>
2631 #include <gp_Pnt.hxx>
2632 #include <Graphic3d_ArrayOfPoints.hxx>
2633 #include <Graphic3d_ArrayOfPrimitives.hxx>
2634 #include <Graphic3d_ArrayOfTriangles.hxx>
2635 #include <Poly_Array1OfTriangle.hxx>
2636 #include <Poly_Triangle.hxx>
2637 #include <Poly_Triangulation.hxx>
2638 #include <TColgp_Array1OfPnt.hxx>
2639 #include <TShort_Array1OfShortReal.hxx>
2640 #include <TShort_HArray1OfShortReal.hxx>
2641
2642 #include <AIS_Triangulation.hxx>
2643 #include <StdPrs_ToolShadedShape.hxx>
2644 #include <Poly_Connect.hxx>
2645 #include <TColgp_Array1OfDir.hxx>
2646 #include <Graphic3d_GraphicDriver.hxx>
2647
2648 #include <TColStd_Array1OfInteger.hxx>
2649 #include <TColStd_HArray1OfInteger.hxx>
2650 #include <Prs3d_ShadingAspect.hxx>
2651 #include <Graphic3d_MaterialAspect.hxx>
2652 #include <Graphic3d_AspectFillArea3d.hxx>
2653
2654 #include <BRepPrimAPI_MakeCylinder.hxx>
2655 #include <TopoDS_Shape.hxx>
2656 #include <TopExp_Explorer.hxx>
2657 #include <TopAbs.hxx>
2658 #include <StdSelect_ShapeTypeFilter.hxx>
2659
2660
2661 //===============================================================================================
2662 //function : CalculationOfSphere
2663 //author   : psn
2664 //purpose  : Create a Sphere
2665 //===============================================================================================
2666
2667 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2668                                                   int res ,
2669                                                   double Radius ){
2670   double mRadius = Radius;
2671   double mCenter[3] = {X,Y,Z};
2672   int mThetaResolution;
2673   int mPhiResolution;
2674   double mStartTheta = 0;//StartTheta;
2675   double mEndTheta = 360;//EndTheta;
2676   double mStartPhi = 0;//StartPhi;
2677   double mEndPhi = 180;//EndPhi;
2678   res = res < 4 ? 4 : res;
2679
2680   mThetaResolution = res;
2681   mPhiResolution = res;
2682
2683   int i, j;
2684   int jStart, jEnd, numOffset;
2685   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2686   double startTheta, endTheta, startPhi, endPhi;
2687   int base, numPoles=0, thetaResolution, phiResolution;
2688
2689   int pts[3];
2690   int piece = -1;
2691   int numPieces = 1;
2692   if ( numPieces > mThetaResolution ) {
2693     numPieces = mThetaResolution;
2694   }
2695
2696   int localThetaResolution =  mThetaResolution;
2697   double localStartTheta =  mStartTheta;
2698   double localEndTheta =  mEndTheta;
2699
2700   while ( localEndTheta < localStartTheta ) {
2701     localEndTheta += 360.0;
2702   }
2703
2704   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2705
2706   // Change the ivars based on pieces.
2707   int start, end;
2708   start = piece * localThetaResolution / numPieces;
2709   end = (piece+1) * localThetaResolution / numPieces;
2710   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2711   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2712   localThetaResolution = end - start;
2713
2714   // Create north pole if needed
2715   int number_point = 0;
2716   int number_pointArray = 0;
2717
2718   if ( mStartPhi <= 0.0 ) {
2719     number_pointArray++;
2720     numPoles++;
2721   }
2722   if ( mEndPhi >= 180.0 ) {
2723     number_pointArray++;
2724     numPoles++;
2725   }
2726
2727   // Check data, determine increments, and convert to radians
2728   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2729   startTheta *= M_PI  / 180.0;
2730   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2731   endTheta *= M_PI  / 180.0;
2732
2733
2734   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2735   startPhi *= M_PI  / 180.0;
2736   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2737   endPhi *= M_PI  / 180.0;
2738
2739   phiResolution =  mPhiResolution - numPoles;
2740   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2741   thetaResolution = localThetaResolution;
2742   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2743     ++localThetaResolution;
2744   }
2745   deltaTheta = (endTheta - startTheta) / thetaResolution;
2746
2747   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2748   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2749
2750   // Create intermediate points
2751   for ( i = 0; i < localThetaResolution; i++ ) {
2752     for ( j = jStart; j < jEnd; j++ ) {
2753         number_pointArray++;
2754     }
2755   }
2756
2757   //Generate mesh connectivity
2758   base = phiResolution * localThetaResolution;
2759
2760   int number_triangle = 0 ;
2761   if ( mStartPhi <= 0.0 ) { // around north pole
2762     number_triangle += localThetaResolution;
2763   }
2764
2765   if ( mEndPhi >= 180.0 ) { // around south pole
2766     number_triangle += localThetaResolution;
2767   }
2768
2769   // bands in-between poles
2770   for ( i=0; i < localThetaResolution; i++){
2771     for ( j=0; j < (phiResolution-1); j++){
2772        number_triangle +=2;
2773     }
2774   }
2775
2776   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2777   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2778   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2779
2780   if (  mStartPhi <= 0.0 ){
2781       x[0] =  mCenter[0];
2782       x[1] =  mCenter[1];
2783       x[2] =  mCenter[2] +  mRadius;
2784       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2785   }
2786
2787   // Create south pole if needed
2788   if (  mEndPhi >= 180.0 ){
2789       x[0] =  mCenter[0];
2790       x[1] =  mCenter[1];
2791       x[2] =  mCenter[2] -  mRadius;
2792       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2793   }
2794
2795   number_point = 3;
2796   for ( i=0; i < localThetaResolution; i++){
2797     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2798     for ( j = jStart; j < jEnd; j++){
2799         phi = startPhi + j*deltaPhi;
2800         radius =  mRadius * sin((double)phi);
2801         n[0] = radius * cos((double)theta);
2802         n[1] = radius * sin((double)theta);
2803         n[2] =  mRadius * cos((double)phi);
2804         x[0] = n[0] +  mCenter[0];
2805         x[1] = n[1] +  mCenter[1];
2806         x[2] = n[2] +  mCenter[2];
2807         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2808         number_point++;
2809       }
2810     }
2811
2812   numPoles = 3;
2813   number_triangle = 1;
2814   if ( mStartPhi <= 0.0 ){// around north pole
2815     for (i=0; i < localThetaResolution; i++){
2816         pts[0] = phiResolution*i + numPoles;
2817         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2818         pts[2] = 1;
2819         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2820         number_triangle++;
2821       }
2822     }
2823
2824   if (  mEndPhi >= 180.0 ){ // around south pole
2825     numOffset = phiResolution - 1 + numPoles;
2826     for (i=0; i < localThetaResolution; i++){
2827         pts[0] = phiResolution*i + numOffset;
2828         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2829         pts[1] = numPoles - 1;
2830         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2831         number_triangle++;
2832       }
2833     }
2834
2835   // bands in-between poles
2836
2837   for (i=0; i < localThetaResolution; i++){
2838     for (j=0; j < (phiResolution-1); j++){
2839         pts[0] = phiResolution*i + j + numPoles;
2840         pts[1] = pts[0] + 1;
2841         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2842         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2843         number_triangle++;
2844         pts[1] = pts[2];
2845         pts[2] = pts[1] - 1;
2846         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2847         number_triangle++;
2848       }
2849     }
2850
2851   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2852
2853   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2854
2855   Standard_Integer index[3];
2856   Standard_Real Tol = Precision::Confusion();
2857
2858   gp_Dir Nor;
2859   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2860       gp_XYZ eqPlan(0, 0, 0);
2861       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2862         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2863         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2864         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2865         gp_XYZ vv = v1^v2;
2866         Standard_Real mod = vv.Modulus();
2867         if(mod < Tol) continue;
2868         eqPlan += vv/mod;
2869       }
2870
2871       Standard_Real modmax = eqPlan.Modulus();
2872
2873       if(modmax > Tol)
2874         Nor = gp_Dir(eqPlan);
2875       else
2876         Nor = gp_Dir(0., 0., 1.);
2877
2878       Standard_Integer j = (i - PointsOfArray.Lower()) * 3;
2879       Normals->SetValue(j + 1, (Standard_ShortReal)Nor.X());
2880       Normals->SetValue(j + 2, (Standard_ShortReal)Nor.Y());
2881       Normals->SetValue(j + 3, (Standard_ShortReal)Nor.Z());
2882   }
2883
2884   delete pc;
2885   polyTriangulation->SetNormals(Normals);
2886
2887   return polyTriangulation;
2888 }
2889
2890 //===============================================================================================
2891 //function : VDrawSphere
2892 //author   : psn
2893 //purpose  : Create an AIS shape.
2894 //===============================================================================================
2895 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2896 {
2897   // check for errors
2898   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2899   if (aContextAIS.IsNull())
2900   {
2901     std::cout << "Call vinit before!\n";
2902     return 1;
2903   }
2904   else if (argc < 3)
2905   {
2906     std::cout << "Use: " << argv[0]
2907               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2908     return 1;
2909   }
2910
2911   // read the arguments
2912   TCollection_AsciiString aShapeName (argv[1]);
2913   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2914   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2915   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2916   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
2917   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
2918   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
2919   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
2920
2921   // remove AIS object with given name from map
2922   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
2923
2924   if (toPrintInfo)
2925     std::cout << "Compute Triangulation...\n";
2926   Handle(AIS_Triangulation) aShape
2927     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2928                                                   aResolution,
2929                                                   aRadius));
2930   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2931   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2932
2933   // stupid initialization of Green color in RGBA space as integer
2934   // probably wrong for big-endian CPUs
2935   Standard_Integer aRed    = 0;
2936   Standard_Integer aGreen  = 255;
2937   Standard_Integer aBlue   = 0;
2938   Standard_Integer anAlpha = 0; // not used
2939   Standard_Integer aColorInt = aRed;
2940   aColorInt += aGreen  << 8;
2941   aColorInt += aBlue   << 16;
2942   aColorInt += anAlpha << 24;
2943
2944   // setup colors array per vertex
2945   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2946   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2947   {
2948     aColorArray->SetValue (aNodeId, aColorInt);
2949   }
2950   aShape->SetColors (aColorArray);
2951
2952   // show statistics
2953   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2954   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2955   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2956   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2957   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
2958   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
2959   aTotalSize >>= 20; //MB
2960   aNormalsSize >>= 20;
2961   aColorsSize >>= 20;
2962   aTrianglesSize >>= 20;
2963   aPolyConnectSize >>= 20;
2964   if (toPrintInfo)
2965   {
2966     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
2967       << "NumberOfTriangles: " << aNumberTriangles << "\n"
2968       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
2969       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
2970       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
2971       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
2972   }
2973
2974   // Setting material properties, very important for desirable visual result!
2975   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
2976   aMat.SetAmbient (0.2);
2977   aMat.SetSpecular (0.5);
2978   Handle(Graphic3d_AspectFillArea3d) anAspect
2979     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
2980                                       Quantity_NOC_RED,
2981                                       Quantity_NOC_YELLOW,
2982                                       Aspect_TOL_SOLID,
2983                                       1.0,
2984                                       aMat,
2985                                       aMat);
2986   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
2987   if (toShowEdges)
2988   {
2989     anAspect->SetEdgeOn();
2990   }
2991   else
2992   {
2993     anAspect->SetEdgeOff();
2994   }
2995   aShAsp->SetAspect (anAspect);
2996   aShape->Attributes()->SetShadingAspect (aShAsp);
2997
2998   VDisplayAISObject (aShapeName, aShape);
2999   return 0;
3000 }
3001
3002 //=============================================================================
3003 //function : VComputeHLR
3004 //purpose  :
3005 //=============================================================================
3006
3007 static int VComputeHLR (Draw_Interpretor& di,
3008                         Standard_Integer argc,
3009                         const char** argv)
3010 {
3011   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3012
3013   if (aContextAIS.IsNull ())
3014   {
3015     di << "Please call vinit before\n";
3016     return 1;
3017   }
3018
3019   if ( argc != 3 &&  argc != 12 )
3020   {
3021     di << "Usage: " << argv[0] << " ShapeName HlrName "
3022        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]" << "\n"
3023        << "                    ShapeName - name of the initial shape\n"
3024        << "                    HlrName - result hlr object from initial shape\n"
3025        << "                    eye, dir are eye position and look direction\n"
3026        << "                    up is the look up direction vector\n"
3027        << "                    Use vtop to see projected hlr shape\n";
3028     return 1;
3029   }
3030
3031   // shape and new object name
3032   TCollection_AsciiString aShapeName (argv[1]);
3033   TCollection_AsciiString aHlrName (argv[2]);
3034
3035   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3036   if (aSh.IsNull()) 
3037   {
3038     BRep_Builder aBrepBuilder;
3039     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3040     if (aSh.IsNull ())
3041     {
3042       di << "No shape with name " << argv[1] << " found\n";
3043       return 1;
3044     }
3045   }
3046
3047   if (GetMapOfAIS ().IsBound2 (aHlrName))
3048   {
3049     di << "Presentable object with name " << argv[2] << " already exists\n";
3050     return 1;
3051   }
3052
3053   // close local context
3054   if (aContextAIS->HasOpenedContext ())
3055     aContextAIS->CloseLocalContext ();
3056
3057   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3058   HLRBRep_PolyHLRToShape aHLRToShape;
3059
3060   gp_Pnt anEye;
3061   gp_Dir aDir;
3062   gp_Ax2 aProjAx;
3063   if (argc == 9)
3064   {
3065     gp_Dir anUp;
3066
3067     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3068     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3069     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3070     aProjAx.SetLocation (anEye);
3071     aProjAx.SetDirection (aDir);
3072     aProjAx.SetYDirection (anUp);
3073   }
3074   else
3075   {
3076     gp_Dir aRight;
3077
3078     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3079     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3080     Standard_Integer aWidth, aHeight;
3081     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3082     Standard_Real aRightX, aRightY, aRightZ;
3083     aView->Window()->Size (aWidth, aHeight);
3084
3085     aView->ConvertWithProj (aWidth, aHeight/2, 
3086                             aRightX, aRightY, aRightZ,
3087                             aDirX, aDirY, aDirZ);
3088
3089     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3090                             aCentX, aCentY, aCentZ,
3091                             aDirX, aDirY, aDirZ);
3092
3093     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3094     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3095     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3096     aProjAx.SetLocation (anEye);
3097     aProjAx.SetDirection (aDir);
3098     aProjAx.SetXDirection (aRight);
3099   }
3100
3101   HLRAlgo_Projector aProjector (aProjAx);
3102   aPolyAlgo->Projector (aProjector);
3103   aPolyAlgo->Load (aSh);
3104   aPolyAlgo->Update ();
3105
3106   aHLRToShape.Update (aPolyAlgo);
3107
3108   // make hlr shape from input shape
3109   TopoDS_Compound aHlrShape;
3110   BRep_Builder aBuilder;
3111   aBuilder.MakeCompound (aHlrShape);
3112
3113   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3114   if (!aCompound.IsNull ())
3115   {
3116     aBuilder.Add (aHlrShape, aCompound);
3117   }
3118   
3119   // extract visible outlines
3120   aCompound = aHLRToShape.OutLineVCompound();
3121   if (!aCompound.IsNull ())
3122   {
3123     aBuilder.Add (aHlrShape, aCompound);
3124   }
3125
3126   // create an AIS shape and display it
3127   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3128   GetMapOfAIS().Bind (anObject, aHlrName);
3129   aContextAIS->Display (anObject);
3130
3131   aContextAIS->UpdateCurrentViewer ();
3132
3133   return 0;
3134 }
3135
3136 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3137 // manipulating and displaying such an array with AIS context
3138 DEFINE_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3139 class MyPArrayObject : public AIS_InteractiveObject
3140 {
3141
3142 public:
3143
3144   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3145                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3146   {
3147     myArrayDescription = theArrayDescription;
3148     myMarkerAspect = theMarkerAspect;
3149   }
3150
3151   DEFINE_STANDARD_RTTI(MyPArrayObject);
3152
3153 private:
3154
3155   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3156                 const Handle(Prs3d_Presentation)& aPresentation,
3157                 const Standard_Integer aMode);
3158
3159   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3160                          const Standard_Integer /*theMode*/);
3161
3162   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3163                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3164                           Standard_Integer &theArgIndex,
3165                           Standard_Integer theArgCount,
3166                           Standard_Integer theMaxArgs);
3167
3168 protected:
3169
3170   Handle(TColStd_HArray1OfAsciiString) myArrayDescription;
3171   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3172
3173 };
3174
3175 IMPLEMENT_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3176 IMPLEMENT_STANDARD_RTTIEXT(MyPArrayObject, AIS_InteractiveObject)
3177
3178 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3179                               const Handle(Prs3d_Presentation)& aPresentation,
3180                               const Standard_Integer /*aMode*/)
3181 {
3182
3183   // Parsing array description
3184   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3185   Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
3186   hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
3187
3188   Standard_Integer anArgIndex = 0;
3189   Standard_Integer anArgsCount = myArrayDescription->Length();
3190   TCollection_AsciiString anArrayType = myArrayDescription->Value (anArgIndex++);
3191
3192   TCollection_AsciiString aCommand;
3193   while (anArgIndex < anArgsCount)
3194   {
3195     aCommand = myArrayDescription->Value (anArgIndex);
3196     aCommand.LowerCase();
3197
3198     // vertex command
3199     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3200     {
3201       // vertex has a normal or normal with color or texel
3202       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3203         hasNormals = Standard_True;
3204
3205       // vertex has a color
3206       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3207         hasVColors = Standard_True;
3208
3209       // vertex has a texel
3210       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3211         hasTexels = Standard_True;
3212
3213       aVertexNum++;
3214     }
3215     // bound command
3216     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3217     {
3218       // bound has color
3219       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3220         hasBColors = Standard_True;
3221
3222       aBoundNum++;
3223     }
3224     // edge command
3225     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3226     {
3227       aEdgeNum++;
3228     }
3229     // unknown command
3230     else
3231       anArgIndex++;
3232   }
3233
3234   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3235   if (anArrayType == "points")
3236   {
3237     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3238   }
3239   else if (anArrayType == "segments")
3240     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3241   else if (anArrayType == "polylines")
3242     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3243                                               hasVColors, hasBColors);
3244   else if (anArrayType == "triangles")
3245     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3246                                               hasVColors, hasTexels);
3247   else if (anArrayType == "trianglefans")
3248     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3249                                                  hasNormals, hasVColors,
3250                                                  hasBColors, hasTexels);
3251   else if (anArrayType == "trianglestrips")
3252     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3253                                                    hasNormals, hasVColors,
3254                                                    hasBColors, hasTexels);
3255   else if (anArrayType == "quads")
3256     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3257                                                 hasNormals, hasVColors,
3258                                                 hasTexels);
3259   else if (anArrayType == "quadstrips")
3260     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3261                                                      hasNormals, hasVColors,
3262                                                      hasBColors, hasTexels);
3263   else if (anArrayType == "polygons")
3264     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3265                                              hasNormals, hasVColors, hasBColors,
3266                                              hasTexels);
3267
3268   anArgIndex = 1;
3269   while (anArgIndex < anArgsCount)
3270   {
3271     aCommand = myArrayDescription->Value (anArgIndex);
3272     aCommand.LowerCase();
3273     if (!aCommand.IsAscii())
3274       break;
3275
3276     // vertex command
3277     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3278     {
3279       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3280                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
3281                           myArrayDescription->Value (anArgIndex - 1).RealValue());
3282       const Standard_Integer aVertIndex = anArray->VertexNumber();
3283
3284       // vertex has a normal or normal with color or texel
3285       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3286         anArray->SetVertexNormal (aVertIndex,
3287                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
3288                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
3289                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
3290       
3291       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3292         anArray->SetVertexColor (aVertIndex,
3293                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
3294                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3295                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3296       
3297       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3298         anArray->SetVertexTexel (aVertIndex,
3299                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3300                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3301     }
3302     // bounds command
3303     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3304     {
3305       Standard_Integer aVertCount = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3306
3307       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3308         anArray->AddBound (aVertCount,
3309                            myArrayDescription->Value (anArgIndex - 3).RealValue(),
3310                            myArrayDescription->Value (anArgIndex - 2).RealValue(),
3311                            myArrayDescription->Value (anArgIndex - 1).RealValue());
3312
3313       else
3314         anArray->AddBound (aVertCount);
3315     }
3316     // edge command
3317     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3318     {
3319       const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3320       anArray->AddEdge (aVertIndex);
3321     }
3322     // unknown command
3323     else
3324       anArgIndex++;
3325   }
3326
3327   aPresentation->Clear();
3328   if (!myMarkerAspect.IsNull())
3329   {
3330     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
3331   }
3332   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
3333 }
3334
3335 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3336                                        const Standard_Integer /*theMode*/)
3337 {
3338   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
3339
3340   Standard_Integer anArgIndex = 1;
3341   while (anArgIndex < myArrayDescription->Length())
3342   {
3343     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, myArrayDescription->Length()))
3344     {
3345       gp_Pnt aPoint (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3346                      myArrayDescription->Value (anArgIndex - 2).RealValue(),
3347                      myArrayDescription->Value (anArgIndex - 1).RealValue());
3348       Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
3349       theSelection->Add (aSensetivePoint);
3350     }
3351     else
3352     {
3353       anArgIndex++;
3354     }
3355   }
3356 }
3357
3358 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3359                                        const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3360                                        Standard_Integer &theArgIndex,
3361                                        Standard_Integer theArgCount,
3362                                        Standard_Integer theMaxArgs)
3363 {
3364   // check if there is more elements than expected
3365   if (theArgIndex >= theMaxArgs)
3366     return false;
3367
3368   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3369   aStrCommand.LowerCase();
3370   if (aStrCommand.Search(theCommand) != 1 ||
3371       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3372     return false;
3373
3374   // go to the first data element
3375   theArgIndex++;
3376
3377   // check data if it can be converted to numeric
3378   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3379   {
3380     aStrCommand = theArgsArray->Value (theArgIndex);
3381     if (!aStrCommand.IsRealValue())
3382       return false;
3383   }
3384
3385   return true;
3386 }
3387
3388 //=============================================================================
3389 //function : VDrawPArray
3390 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3391 //=============================================================================
3392
3393 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3394 {
3395   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3396   if (aContextAIS.IsNull())
3397   {
3398     di << "Call vinit before!\n";
3399     return 1;
3400   }
3401   else if (argc < 3)
3402   {
3403     di << "Use: " << argv[0] << " Name TypeOfArray"
3404        << " [vertex] ... [bounds] ... [edges]\n"
3405        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
3406        << "                trianglefans | trianglestrips | quads |\n"
3407        << "                quadstrips | polygons }\n"
3408        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
3409        << " [texel={ 't' tx ty }] } \n"
3410        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
3411        << "  edges={ 'e' vertex_id }\n";
3412     return 1;
3413   }
3414
3415   // read the arguments
3416   Standard_Integer aArgIndex = 1;
3417   TCollection_AsciiString aName (argv[aArgIndex++]);
3418   TCollection_AsciiString anArrayType (argv[aArgIndex++]);
3419
3420   Standard_Boolean hasVertex = Standard_False;
3421
3422   Handle(TColStd_HArray1OfAsciiString) anArgsArray = new TColStd_HArray1OfAsciiString (0, argc - 2);
3423   anArgsArray->SetValue (0, anArrayType);
3424
3425   if (anArrayType != "points"         &&
3426       anArrayType != "segments"       &&
3427       anArrayType != "polylines"      &&
3428       anArrayType != "triangles"      &&
3429       anArrayType != "trianglefans"   &&
3430       anArrayType != "trianglestrips" &&
3431       anArrayType != "quads"          &&
3432       anArrayType != "quadstrips"     &&
3433       anArrayType != "polygons")
3434   {
3435     di << "Unexpected type of primitives array\n";
3436     return 1;
3437   }
3438
3439   TCollection_AsciiString aCommand;
3440   for (Standard_Integer anArgIndex = 3; anArgIndex < argc; anArgIndex++)
3441   {
3442     aCommand = argv[anArgIndex];
3443     aCommand.LowerCase();
3444     if (!aCommand.IsAscii())
3445     {
3446       di << "Unexpected argument: #" << aArgIndex - 1 << " , "
3447          << "should be an array element: 'v', 'b', 'e' \n";
3448       break;
3449     }
3450
3451     if (aCommand == "v")
3452     {
3453       hasVertex = Standard_True;
3454     }
3455
3456     anArgsArray->SetValue (anArgIndex - 2, aCommand);
3457   }
3458
3459   if (!hasVertex)
3460   {
3461     di << "You should pass any verticies in the list of array elements\n";
3462     return 1;
3463   }
3464
3465   Handle(Graphic3d_AspectMarker3d)    anAspPoints;
3466   if (anArrayType == "points")
3467   {
3468     anAspPoints = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
3469   }
3470
3471   // create primitives array object
3472   Handle(MyPArrayObject) aPObject = new MyPArrayObject (anArgsArray, anAspPoints);
3473
3474   // register the object in map
3475   VDisplayAISObject (aName, aPObject);
3476
3477   return 0;
3478 }
3479
3480 //=======================================================================
3481 //function : VSetLocation
3482 //purpose  : Change location of AIS interactive object
3483 //=======================================================================
3484
3485 static Standard_Integer VSetLocation (Draw_Interpretor& /*di*/,
3486                                       Standard_Integer  theArgNb,
3487                                       const char**      theArgVec)
3488 {
3489   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3490   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
3491   if (aContext.IsNull())
3492   {
3493     std::cout << "Error: no active view!\n";
3494     return 1;
3495   }
3496
3497   TCollection_AsciiString aName;
3498   gp_Vec aLocVec;
3499   Standard_Boolean isSetLoc = Standard_False;
3500
3501   Standard_Integer anArgIter = 1;
3502   for (; anArgIter < theArgNb; ++anArgIter)
3503   {
3504     Standard_CString anArg = theArgVec[anArgIter];
3505     if (anUpdateTool.parseRedrawMode (theArgVec[anArgIter]))
3506     {
3507       continue;
3508     }
3509     else if (aName.IsEmpty())
3510     {
3511       aName = anArg;
3512     }
3513     else if (!isSetLoc)
3514     {
3515       isSetLoc = Standard_True;
3516       if (anArgIter + 1 >= theArgNb)
3517       {
3518         std::cout << "Error: syntax error at '" << anArg << "'\n";
3519         return 1;
3520       }
3521       aLocVec.SetX (Draw::Atof (theArgVec[anArgIter++]));
3522       aLocVec.SetY (Draw::Atof (theArgVec[anArgIter]));
3523       if (anArgIter + 1 < theArgNb)
3524       {
3525         aLocVec.SetZ (Draw::Atof (theArgVec[++anArgIter]));
3526       }
3527     }
3528     else
3529     {
3530       std::cout << "Error: unknown argument '" << anArg << "'\n";
3531       return 1;
3532     }
3533   }
3534
3535   // find object
3536   const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3537   Handle(AIS_InteractiveObject) anIObj;
3538   if (aMap.IsBound2 (aName))
3539   {
3540     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
3541   }
3542   if (anIObj.IsNull())
3543   {
3544     std::cout << "Error: object '" << aName << "' is not displayed!\n";
3545     return 1;
3546   }
3547
3548   gp_Trsf aTrsf;
3549   aTrsf.SetTranslation (aLocVec);
3550   TopLoc_Location aLocation (aTrsf);
3551   aContext->SetLocation (anIObj, aLocation);
3552   return 0;
3553 }
3554
3555 //=======================================================================
3556 //function : TransformPresentation
3557 //purpose  : Change transformation of AIS interactive object
3558 //=======================================================================
3559 static Standard_Integer LocalTransformPresentation (Draw_Interpretor& /*theDi*/,
3560                                                     Standard_Integer theArgNb,
3561                                                     const char** theArgVec)
3562 {
3563   if (theArgNb <= 1)
3564   {
3565     std::cout << "Error: too few arguments.\n";
3566     return 1;
3567   }
3568
3569   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3570   ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
3571   if (aContext.IsNull())
3572   {
3573     std::cout << "Error: no active view!\n";
3574     return 1;
3575   }
3576
3577   gp_Trsf aTrsf;
3578   Standard_Integer aLast = theArgNb;
3579   const char* aName = theArgVec[0];
3580
3581   Standard_Boolean isReset = Standard_False;
3582   Standard_Boolean isMove = Standard_False;
3583
3584   // Prefix 'vloc'
3585   aName += 4;
3586
3587   if (!strcmp (aName, "reset"))
3588   {
3589     isReset = Standard_True;
3590   }
3591   else if (!strcmp (aName, "move"))
3592   {
3593     if (theArgNb < 3)
3594     {
3595       std::cout << "Error: too few arguments.\n";
3596       return 1;
3597     }
3598
3599     const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3600
3601     Handle(AIS_InteractiveObject) anIObj;
3602     if (aMap.IsBound2 (theArgVec[theArgNb - 1]))
3603     {
3604       anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[theArgNb - 1]));
3605     }
3606
3607     if (anIObj.IsNull())
3608     {
3609       std::cout << "Error: object '" << theArgVec[theArgNb - 1] << "' is not displayed!\n";
3610       return 1;
3611     }
3612
3613     isMove = Standard_True;
3614
3615     aTrsf = anIObj->Transformation();
3616     aLast = theArgNb - 1;
3617   }
3618   else if (!strcmp (aName, "translate"))
3619   {
3620     if (theArgNb < 5)
3621     {
3622       std::cout << "Error: too few arguments.\n";
3623       return 1;
3624     }
3625     aTrsf.SetTranslation (gp_Vec (Draw::Atof (theArgVec[theArgNb - 3]),
3626                                   Draw::Atof (theArgVec[theArgNb - 2]),
3627                                   Draw::Atof (theArgVec[theArgNb - 1])));
3628     aLast = theArgNb - 3;
3629   }
3630   else if (!strcmp (aName, "rotate"))
3631   {
3632     if (theArgNb < 9)
3633     {
3634       std::cout << "Error: too few arguments.\n";
3635       return 1;
3636     }
3637
3638     aTrsf.SetRotation (
3639       gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[theArgNb - 7]),
3640                       Draw::Atof (theArgVec[theArgNb - 6]),
3641                       Draw::Atof (theArgVec[theArgNb - 5])),
3642               gp_Vec (Draw::Atof (theArgVec[theArgNb - 4]),
3643                       Draw::Atof (theArgVec[theArgNb - 3]),
3644                       Draw::Atof (theArgVec[theArgNb - 2]))),
3645       Draw::Atof (theArgVec[theArgNb - 1]) * (M_PI / 180.0));
3646
3647     aLast = theArgNb - 7;
3648   }
3649   else if (!strcmp (aName, "mirror"))
3650   {
3651     if (theArgNb < 8)
3652     {
3653       std::cout << "Error: too few arguments.\n";
3654       return 1;
3655     }
3656
3657     aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
3658                                      Draw::Atof(theArgVec[theArgNb - 5]),
3659                                      Draw::Atof(theArgVec[theArgNb - 4])),
3660                              gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
3661                                      Draw::Atof(theArgVec[theArgNb - 2]),
3662                                      Draw::Atof(theArgVec[theArgNb - 1]))));
3663     aLast = theArgNb - 6;
3664   }
3665   else if (!strcmp (aName, "scale"))
3666   {
3667     if (theArgNb < 6)
3668     {
3669       std::cout << "Error: too few arguments.\n";
3670       return 1;
3671     }
3672
3673     aTrsf.SetScale (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 4]),
3674                             Draw::Atof(theArgVec[theArgNb - 3]),
3675                             Draw::Atof(theArgVec[theArgNb - 2])),
3676                     Draw::Atof(theArgVec[theArgNb - 1]));
3677     aLast = theArgNb - 4;
3678   }
3679
3680   for (Standard_Integer anIdx = 1; anIdx < aLast; anIdx++)
3681   {
3682     // find object
3683     const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3684     Handle(AIS_InteractiveObject) anIObj;
3685     if (aMap.IsBound2 (theArgVec[anIdx]))
3686     {
3687       anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[anIdx]));
3688     }
3689     if (anIObj.IsNull())
3690     {
3691       std::cout << "Error: object '" << theArgVec[anIdx] << "' is not displayed!\n";
3692       return 1;
3693     }
3694     
3695     if (isReset)
3696     {
3697       // aTrsf already identity
3698     }
3699     else if (isMove)
3700     {
3701       aTrsf = anIObj->LocalTransformation() * anIObj->Transformation().Inverted() * aTrsf;
3702     }
3703     else
3704     {
3705       aTrsf = anIObj->LocalTransformation() * aTrsf;
3706     }
3707
3708     TopLoc_Location aLocation (aTrsf);
3709     aContext->SetLocation (anIObj, aLocation);
3710   }
3711
3712   return 0;
3713 }
3714
3715 //===============================================================================================
3716 //function : VConnect
3717 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3718 //Draw arg : vconnect name Xo Yo Zo object1 object2 ... [color=NAME]
3719 //===============================================================================================
3720
3721 static Standard_Integer VConnect (Draw_Interpretor& /*di*/, 
3722                                   Standard_Integer argc, 
3723                                   const char ** argv) 
3724 {
3725   // Check the viewer
3726   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3727   if (aContext.IsNull())
3728   {
3729     std::cout << "vconnect error : call vinit before\n";
3730     return 1; // TCL_ERROR
3731   }
3732   // Check argumnets 
3733   if (argc < 6)
3734   {
3735     std::cout << "vconnect error: expect at least 5 arguments\n";
3736     return 1; // TCL_ERROR
3737   }
3738
3739   // Get values
3740   Standard_Integer anArgIter = 1;
3741   TCollection_AsciiString aName (argv[anArgIter++]);
3742   Handle(AIS_MultipleConnectedInteractive) anOriginObject;
3743   TCollection_AsciiString aColorString (argv[argc-1]);
3744   Standard_CString aColorName = "";
3745   Standard_Boolean hasColor = Standard_False;
3746   if (aColorString.Search ("color=") != -1)
3747   {
3748     hasColor = Standard_True;
3749     aColorString.Remove (1, 6);
3750     aColorName = aColorString.ToCString();
3751   }
3752   Handle(AIS_InteractiveObject) anObject;
3753
3754   // AIS_MultipleConnectedInteractive
3755   const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
3756   for (Standard_Integer i = 5; i < aNbShapes; ++i)
3757   {
3758     TCollection_AsciiString anOriginObjectName (argv[i]);
3759     if (aName.IsEqual (anOriginObjectName))
3760     {
3761       std::cout << "vconnect error: equal names for connected objects\n";
3762       continue;
3763     }
3764     if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3765     {
3766       Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3767       anObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3768       if (anObject.IsNull())
3769       {
3770         std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3771         continue;
3772       }
3773     }
3774     else
3775     {
3776       Standard_CString aName = anOriginObjectName.ToCString();
3777       TopoDS_Shape aTDShape = DBRep::Get (aName);
3778       if (aTDShape.IsNull())
3779       {
3780         std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3781         continue;
3782       }
3783       anObject = new AIS_Shape (aTDShape);
3784       aContext->Load (anObject);
3785       anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
3786     }
3787
3788     if (anOriginObject.IsNull())
3789     {
3790       anOriginObject = new AIS_MultipleConnectedInteractive();
3791     }
3792
3793     anOriginObject->Connect (anObject);
3794   }
3795   if (anOriginObject.IsNull())
3796   {
3797     std::cout << "vconect error : can't connect input objects\n";
3798     return 1; // TCL_ERROR
3799   }
3800
3801   // Get location data
3802   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3803   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3804   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3805
3806   // Create transformation
3807   gp_Vec aTranslation (aXo, aYo, aZo);
3808
3809   gp_Trsf aTrsf; 
3810   aTrsf.SetTranslationPart (aTranslation);
3811   TopLoc_Location aLocation (aTrsf);
3812
3813   anOriginObject->SetLocalTransformation (aTrsf);
3814
3815   // Check if there is another object with given name
3816   // and remove it from context
3817   if(GetMapOfAIS().IsBound2(aName))
3818   {
3819     Handle(AIS_InteractiveObject) anObj = 
3820       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3821     TheAISContext()->Remove(anObj, Standard_False);
3822     GetMapOfAIS().UnBind2(aName);
3823   }
3824
3825   // Bind connected object to its name
3826   GetMapOfAIS().Bind (anOriginObject, aName);
3827
3828   // Display connected object
3829   TheAISContext()->Display (anOriginObject);
3830
3831   return 0;
3832 }
3833
3834 //===============================================================================================
3835 //function : VConnectTo
3836 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3837 //Draw arg : vconnectto name Xo Yo Zo object
3838 //===============================================================================================
3839
3840 static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, 
3841                                     Standard_Integer argc, 
3842                                     const char ** argv) 
3843 {
3844   // Check the viewer
3845   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3846   if (aContext.IsNull())
3847   {
3848     std::cout << "vconnect error : call vinit before\n";
3849     return 1; // TCL_ERROR
3850   }
3851   // Check argumnets 
3852   if (argc != 6 && argc != 7)
3853   {
3854     std::cout << "vconnect error: expect at least 5 arguments\n";
3855     return 1; // TCL_ERROR
3856   }
3857
3858   // Get values
3859   Standard_Integer anArgIter = 1;
3860   TCollection_AsciiString aName (argv[anArgIter++]);
3861   Handle(AIS_InteractiveObject) anOriginObject;
3862
3863   TCollection_AsciiString anOriginObjectName(argv[5]);
3864   if (aName.IsEqual (anOriginObjectName))
3865   {
3866     std::cout << "vconnect error: equal names for connected objects\n"; 
3867     return 1; // TCL_ERROR
3868   }
3869   if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3870   {
3871     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3872     anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3873     if (anOriginObject.IsNull())
3874     {
3875       std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3876       return 1; // TCL_ERROR
3877     }
3878   }
3879   else
3880   {
3881     Standard_CString aName = anOriginObjectName.ToCString();
3882     TopoDS_Shape aTDShape = DBRep::Get (aName);
3883     if (aTDShape.IsNull())
3884     {
3885       std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3886       return 1; // TCL_ERROR
3887     }
3888     anOriginObject = new AIS_Shape (aTDShape);
3889     GetMapOfAIS().Bind (anOriginObject, anOriginObjectName);
3890   }
3891  
3892   // Get location data
3893   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3894   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3895   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3896
3897   // Create transformation
3898   gp_Vec aTranslation (aXo, aYo, aZo);
3899
3900   gp_Trsf aTrsf; 
3901   aTrsf.SetTranslationPart (aTranslation);
3902  
3903   Handle(AIS_ConnectedInteractive) aConnected;
3904
3905   aConnected = new AIS_ConnectedInteractive();
3906
3907   aConnected->Connect (anOriginObject, aTrsf);
3908
3909   // Check if there is another object with given name
3910   // and remove it from context
3911   if(GetMapOfAIS().IsBound2(aName))
3912   {
3913     Handle(AIS_InteractiveObject) anObj = 
3914       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3915     TheAISContext()->Remove(anObj, Standard_False);
3916     GetMapOfAIS().UnBind2(aName);
3917   }
3918
3919   // Bind connected object to its name
3920   GetMapOfAIS().Bind (aConnected, aName);
3921
3922   if (argc == 7)
3923   {
3924     TCollection_AsciiString anArg = argv[6];
3925     anArg.LowerCase();
3926     if (anArg == "-nodisplay")
3927       return 0;
3928   }
3929
3930   // Display connected object
3931   TheAISContext()->Display (aConnected);
3932
3933   return 0;
3934 }
3935
3936 //=======================================================================
3937 //function : VDisconnect
3938 //purpose  :
3939 //=======================================================================
3940 static Standard_Integer VDisconnect (Draw_Interpretor& di,
3941                                      Standard_Integer argc,
3942                                      const char ** argv)
3943 {
3944   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3945   if (aContext.IsNull())
3946   {
3947     std::cout << argv[0] << "ERROR : use 'vinit' command before " << "\n";
3948     return 1;
3949   }
3950   
3951   if (argc != 3)
3952   {
3953     std::cout << "ERROR : Usage : " << argv[0] << " name object" << "\n";
3954     return 1;
3955   }
3956
3957   TCollection_AsciiString aName (argv[1]);
3958   TCollection_AsciiString anObject (argv[2]);
3959   Standard_Integer anObjectNumber = Draw::Atoi (argv[2]);
3960
3961   // find objects
3962   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3963   Handle(AIS_MultipleConnectedInteractive) anAssembly;
3964   if (!aMap.IsBound2 (aName) )
3965   {
3966     std::cout << "Use 'vdisplay' before" << "\n";
3967     return 1;
3968   }
3969
3970   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
3971   if (anAssembly.IsNull())