0024023: Revamp the OCCT Handle -- general
[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 class FilledCircle : public AIS_InteractiveObject 
1931 {
1932 public:
1933     // CASCADE RTTI
1934     DEFINE_STANDARD_RTTI(FilledCircle, AIS_InteractiveObject); 
1935
1936     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1937     FilledCircle(Handle(Geom_Circle) theCircle);
1938
1939 private:
1940     TopoDS_Face ComputeFace();
1941
1942     // Virtual methods implementation
1943     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1944                   const Handle(Prs3d_Presentation)& thePresentation,
1945                   const Standard_Integer theMode);
1946
1947     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1948                            const Standard_Integer theMode);
1949
1950 protected:
1951     Handle(Geom_Circle) myCircle;
1952     Standard_Boolean myFilledStatus;
1953
1954 }; 
1955
1956
1957 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1958 {
1959   myCircle = CreateCircle(theCenter, theRadius);
1960   myFilledStatus = Standard_True;
1961 }
1962
1963 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1964 {
1965   myCircle = theCircle;
1966   myFilledStatus = Standard_True;
1967 }
1968
1969 TopoDS_Face FilledCircle::ComputeFace() 
1970 {
1971   // Create edge from myCircle 
1972   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1973   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1974
1975   // Create wire from anEdge 
1976   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1977   TopoDS_Wire aWire = aWireMaker.Wire();
1978
1979   // Create face from aWire
1980   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1981   TopoDS_Face aFace = aFaceMaker.Face();
1982
1983   return aFace;
1984 }
1985
1986 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
1987                            const Handle(Prs3d_Presentation) &thePresentation, 
1988                            const Standard_Integer theMode) 
1989 {
1990   thePresentation->Clear();
1991
1992   TopoDS_Face aFace = ComputeFace();
1993
1994   if (aFace.IsNull()) return;
1995   if (theMode != 0) return;
1996
1997   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
1998 }
1999
2000 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2001                                     const Standard_Integer /*theMode*/)
2002 {
2003   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2004   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2005       myCircle, myFilledStatus);
2006   theSelection->Add(aSensitiveCircle);
2007 }
2008
2009 //==============================================================================
2010 // Fonction  vcircle
2011 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2012 //==============================================================================
2013
2014 //==============================================================================
2015 //function : VCircleBuilder
2016 //purpose  : Build an AIS_Circle
2017 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2018 //                              PointName PointName PointName IsFilled
2019 //==============================================================================
2020
2021 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2022                     TCollection_AsciiString theName, 
2023                     Standard_Boolean isFilled) 
2024 {
2025   Handle(AIS_InteractiveObject) aCircle;
2026   if (isFilled) 
2027   {
2028     aCircle = new FilledCircle(theGeomCircle);
2029   }
2030   else
2031   {
2032     aCircle = new AIS_Circle(theGeomCircle);
2033     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2034   }
2035
2036   // Check if there is an object with given name
2037   // and remove it from context
2038   if (GetMapOfAIS().IsBound2(theName)) 
2039   {
2040     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
2041     Handle(AIS_InteractiveObject) anInterObj = 
2042          Handle(AIS_InteractiveObject)::DownCast(anObj);
2043     TheAISContext()->Remove(anInterObj, Standard_False);
2044     GetMapOfAIS().UnBind2(theName);
2045    }
2046
2047    // Bind the circle to its name
2048    GetMapOfAIS().Bind(aCircle, theName);
2049
2050    // Display the circle
2051    TheAISContext()->Display(aCircle);
2052   
2053 }
2054
2055 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2056 {
2057   Standard_Integer myCurrentIndex;
2058   // Verification of the arguments
2059   if (argc>6 || argc<2) 
2060   { 
2061     std::cout << "vcircle error: expect 4 arguments.\n"; 
2062     return 1; // TCL_ERROR 
2063   }
2064   TheAISContext()->CloseAllContexts();
2065
2066   // There are all arguments
2067   if (argc == 6) 
2068   {
2069     // Get arguments
2070     TCollection_AsciiString aName(argv[1]);
2071     Standard_Boolean isFilled = (Standard_Boolean)Draw::Atoi(argv[5]);
2072
2073     Handle(AIS_InteractiveObject) theShapeA;
2074     Handle(AIS_InteractiveObject) theShapeB;
2075
2076     theShapeA =
2077       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2078     theShapeB =
2079       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2080
2081
2082     // Arguments: AIS_Point AIS_Point AIS_Point
2083     // ========================================
2084     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2085       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2086     {
2087       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2088       {
2089         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2090         return 1; // TCL_ERROR 
2091       }
2092       // The third object must be a point
2093       Handle(AIS_InteractiveObject) theShapeC =
2094         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2095       if (theShapeC.IsNull() ||
2096         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2097       {
2098         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2099         return 1; // TCL_ERROR 
2100       }
2101         // tag
2102         // Verify that the three points are different
2103         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2104         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2105         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2106         
2107         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2108         Handle(Geom_CartesianPoint) myCartPointA = 
2109           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2110
2111         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2112         Handle(Geom_CartesianPoint) myCartPointB =
2113           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2114
2115         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2116         Handle(Geom_CartesianPoint) myCartPointC =
2117           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2118
2119         // Test A=B
2120         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2121             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2122             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2123         {
2124           std::cout << "vcircle error: Same points.\n"; 
2125           return 1; // TCL_ERROR 
2126         }
2127         // Test A=C
2128         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2129             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2130             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2131         {
2132           std::cout << "vcircle error: Same points.\n"; 
2133           return 1; // TCL_ERROR 
2134         }
2135         // Test B=C
2136         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2137             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2138             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2139         {
2140           std::cout << "vcircle error: Same points.\n"; 
2141           return 1;// TCL_ERROR 
2142         }
2143         // Construction of the circle
2144         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2145           myCartPointB->Pnt(), myCartPointC->Pnt() );
2146         Handle (Geom_Circle) theGeomCircle;
2147         try 
2148         {
2149           theGeomCircle = Cir.Value();
2150         }
2151         catch (StdFail_NotDone)
2152         {
2153           std::cout << "vcircle error: can't create circle\n";
2154           return -1; // TCL_ERROR
2155         }
2156         
2157         DisplayCircle(theGeomCircle, aName, isFilled);
2158     }
2159
2160     // Arguments: AIS_Plane AIS_Point Real
2161     // ===================================
2162     else if (theShapeA->Type() == AIS_KOI_Datum && 
2163       theShapeA->Signature() == 7 ) 
2164     {
2165       if (theShapeB->Type() != AIS_KOI_Datum || 
2166         theShapeB->Signature() != 1 ) 
2167       {
2168         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2169         return 1; // TCL_ERROR 
2170       }
2171       // Check that the radius is >= 0
2172       if (Draw::Atof(argv[4]) <= 0 ) 
2173       {
2174         std::cout << "vcircle error: the radius must be >=0.\n"; 
2175         return 1; // TCL_ERROR 
2176       }
2177
2178       // Recover the normal to the plane
2179       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2180       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2181
2182       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2183       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2184       Handle(Geom_CartesianPoint) myCartPointB = 
2185         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2186
2187       gp_Pln mygpPlane = myGeomPlane->Pln();
2188       gp_Ax1 thegpAxe = mygpPlane.Axis();
2189       gp_Dir theDir = thegpAxe.Direction();
2190       gp_Pnt theCenter = myCartPointB->Pnt();
2191       Standard_Real TheR = Draw::Atof(argv[4]);
2192       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2193       Handle (Geom_Circle) theGeomCircle;
2194       try 
2195       {
2196         theGeomCircle = Cir.Value();
2197       }
2198       catch (StdFail_NotDone)
2199       {
2200         std::cout << "vcircle error: can't create circle\n";
2201         return -1; // TCL_ERROR
2202       }
2203
2204       DisplayCircle(theGeomCircle, aName, isFilled);
2205
2206     }
2207
2208     // Error
2209     else
2210     {
2211       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2212       return 1; // TCL_ERROR 
2213     }
2214
2215   }
2216   // No arguments: selection in the viewer
2217   // =========================================
2218   else 
2219   {
2220     // Get the name of the circle 
2221     TCollection_AsciiString aName(argv[1]);
2222
2223     TheAISContext()->OpenLocalContext();
2224     myCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
2225
2226     // Activate selection mode for vertices and faces
2227     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2228     TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2229     std::cout << " Select a vertex or a face\n";
2230
2231     // Wait for picking
2232     Standard_Integer argcc = 5;
2233     const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2234     const char **argvv = (const char **) buff;
2235     while (ViewerMainLoop( argcc, argvv) ) { }
2236     // end of the loop
2237
2238     TopoDS_Shape ShapeA;
2239     for(TheAISContext()->InitSelected(); 
2240       TheAISContext()->MoreSelected(); 
2241       TheAISContext()->NextSelected() ) 
2242     {
2243       ShapeA = TheAISContext()->SelectedShape();
2244     }
2245
2246     // ShapeA is a Vertex
2247     if (ShapeA.ShapeType() == TopAbs_VERTEX ) 
2248     {
2249       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2250       std::cout << " Select a different vertex\n";
2251
2252       TopoDS_Shape ShapeB;
2253       do 
2254       {
2255         // Wait for picking
2256         Standard_Integer argccc = 5;
2257         const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2258         const char **argvvv = (const char **) bufff;
2259         while (ViewerMainLoop( argccc, argvvv) ) { }
2260         // end of the loop
2261
2262         for(TheAISContext()->InitSelected(); 
2263           TheAISContext()->MoreSelected(); 
2264           TheAISContext()->NextSelected() ) 
2265         {
2266           ShapeB = TheAISContext()->SelectedShape();
2267         }
2268       } while(ShapeB.IsSame(ShapeA) );
2269
2270       // Selection of ShapeC
2271       std::cout << " Select the last vertex\n";
2272       TopoDS_Shape ShapeC;
2273       do 
2274       {
2275         // Wait for picking
2276         Standard_Integer argcccc = 5;
2277         const char *buffff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2278         const char **argvvvv = (const char **) buffff;
2279         while (ViewerMainLoop( argcccc, argvvvv) ) { }
2280         // end of the loop
2281
2282         for(TheAISContext()->InitSelected(); 
2283           TheAISContext()->MoreSelected(); 
2284           TheAISContext()->NextSelected() ) 
2285         {
2286           ShapeC = TheAISContext()->SelectedShape();
2287         }
2288       } while(ShapeC.IsSame(ShapeA) || ShapeC.IsSame(ShapeB) );
2289       
2290       // Get isFilled
2291       Standard_Boolean isFilled;
2292       std::cout << "Enter filled status (0 or 1)\n";
2293       cin >> isFilled;
2294
2295       // Close the local context
2296       TheAISContext()->CloseLocalContext(myCurrentIndex);
2297
2298       // Construction of the circle
2299       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(ShapeA));
2300       gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2301       gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(ShapeC));
2302
2303       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2304       Handle (Geom_Circle) theGeomCircle;
2305       try 
2306       {
2307         theGeomCircle = Cir.Value();
2308       }
2309       catch (StdFail_NotDone)
2310       {
2311         std::cout << "vcircle error: can't create circle\n";
2312         return -1; // TCL_ERROR
2313       }
2314
2315       DisplayCircle(theGeomCircle, aName, isFilled);
2316
2317     }
2318     // Shape is a face
2319     else
2320     {
2321       std::cout << " Select a vertex (in your face)\n";
2322       TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2323
2324       TopoDS_Shape ShapeB;
2325       // Wait for picking
2326       Standard_Integer argccc = 5;
2327       const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2328       const char **argvvv = (const char **) bufff;
2329       while (ViewerMainLoop( argccc, argvvv) ) { }
2330       // end of the loop
2331
2332       for(TheAISContext()->InitSelected(); 
2333         TheAISContext()->MoreSelected(); 
2334         TheAISContext()->NextSelected() ) 
2335       {
2336         ShapeB = TheAISContext()->SelectedShape();
2337       }
2338
2339       // Recover the radius 
2340       Standard_Real theRad;
2341       do 
2342       {
2343         std::cout << " Enter the value of the radius:\n";
2344         cin >> theRad;
2345       } while (theRad <= 0);
2346       
2347       // Get filled status
2348       Standard_Boolean isFilled;
2349       std::cout << "Enter filled status (0 or 1)\n";
2350       cin >> isFilled;
2351
2352       // Close the local context
2353       TheAISContext()->CloseLocalContext(myCurrentIndex);
2354       // Construction of the circle
2355
2356       // Recover the normal to the plane. tag
2357       TopoDS_Face myFace = TopoDS::Face(ShapeA);
2358       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2359       gp_Pln myPlane = mySurface.Plane();
2360       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2361       gp_Pln mygpPlane = theGeomPlane->Pln();
2362       gp_Ax1 thegpAxe = mygpPlane.Axis();
2363       gp_Dir theDir = thegpAxe.Direction();
2364
2365       // Recover the center
2366       gp_Pnt theCenter = BRep_Tool::Pnt(TopoDS::Vertex(ShapeB));
2367
2368       // Construct the circle
2369       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2370       Handle (Geom_Circle) theGeomCircle;
2371       try 
2372       {
2373         theGeomCircle = Cir.Value();
2374       }
2375       catch (StdFail_NotDone)
2376       {
2377         std::cout << "vcircle error: can't create circle\n";
2378         return -1; // TCL_ERROR
2379       }
2380
2381       DisplayCircle(theGeomCircle, aName, isFilled);
2382       
2383     }
2384
2385   }
2386
2387   return 0;
2388 }
2389
2390 //=======================================================================
2391 //function : VDrawText
2392 //purpose  :
2393 //=======================================================================
2394 static int VDrawText (Draw_Interpretor& theDI,
2395                       Standard_Integer  theArgsNb,
2396                       const char**      theArgVec)
2397 {
2398   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2399   if (theArgsNb < 3)
2400   {
2401     std::cout << "Error: wrong number of arguments! See usage:\n";
2402     theDI.PrintHelp (theArgVec[0]);
2403     return 1;
2404   }
2405   else if (aContext.IsNull())
2406   {
2407     std::cout << "Error: no active view!\n";
2408     return 1;
2409   }
2410
2411   Standard_Integer           anArgIt = 1;
2412   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2413   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2414   Handle(AIS_TextLabel)      aTextPrs;
2415   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2416
2417   if (GetMapOfAIS().IsBound2 (aName))
2418   {
2419     aTextPrs  = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2420   }
2421   else
2422   {
2423     aTextPrs = new AIS_TextLabel();
2424     aTextPrs->SetFont ("Courier");
2425   }
2426
2427   aTextPrs->SetText (aText);
2428
2429   for (; anArgIt < theArgsNb; ++anArgIt)
2430   {
2431     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2432     aParam.LowerCase();
2433
2434     if (anAutoUpdater.parseRedrawMode (aParam))
2435     {
2436       continue;
2437     }
2438     else if (aParam == "-pos"
2439           || aParam == "-position")
2440     {
2441       if (anArgIt + 3 >= theArgsNb)
2442       {
2443         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2444         return 1;
2445       }
2446
2447       gp_Pnt aPos;
2448       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2449       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2450       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2451       aTextPrs->SetPosition (aPos);
2452     }
2453     else if (aParam == "-color")
2454     {
2455       if (anArgIt + 1 >= theArgsNb)
2456       {
2457         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2458         return 1;
2459       }
2460
2461       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2462       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2463       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2464       {
2465         anArgIt += 1;
2466         aTextPrs->SetColor (aNameOfColor);
2467         continue;
2468       }
2469       else if (anArgIt + 3 >= theArgsNb)
2470       {
2471         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2472         return 1;
2473       }
2474
2475       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2476       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2477       if (!aColor.IsRealValue()
2478        || !aGreen.IsRealValue()
2479        || !aBlue.IsRealValue())
2480       {
2481         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2482         return 1;
2483       }
2484
2485       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2486                                    aGreen.RealValue(),
2487                                    aBlue.RealValue());
2488
2489       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2490       anArgIt += 3;
2491     }
2492     else if (aParam == "-halign")
2493     {
2494       if (++anArgIt >= theArgsNb)
2495       {
2496         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2497         return 1;
2498       }
2499
2500       TCollection_AsciiString aType (theArgVec[anArgIt]);
2501       aType.LowerCase();
2502       if (aType == "left")
2503       {
2504         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2505       }
2506       else if (aType == "center")
2507       {
2508         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2509       }
2510       else if (aType == "right")
2511       {
2512         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2513       }
2514       else
2515       {
2516         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2517         return 1;
2518       }
2519     }
2520     else if (aParam == "-valign")
2521     {
2522       if (++anArgIt >= theArgsNb)
2523       {
2524         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2525         return 1;
2526       }
2527
2528       TCollection_AsciiString aType (theArgVec[anArgIt]);
2529       aType.LowerCase();
2530       if (aType == "top")
2531       {
2532         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2533       }
2534       else if (aType == "center")
2535       {
2536         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2537       }
2538       else if (aType == "bottom")
2539       {
2540         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2541       }
2542       else
2543       {
2544         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2545         return 1;
2546       }
2547     }
2548     else if (aParam == "-angle")
2549     {
2550       if (++anArgIt >= theArgsNb)
2551       {
2552         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2553         return 1;
2554       }
2555
2556       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2557     }
2558     else if (aParam == "-zoom")
2559     {
2560       if (++anArgIt >= theArgsNb)
2561       {
2562         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2563         return 1;
2564       }
2565
2566       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2567     }
2568     else if (aParam == "-height")
2569     {
2570       if (++anArgIt >= theArgsNb)
2571       {
2572         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2573         return 1;
2574       }
2575
2576       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2577     }
2578     else if (aParam == "-aspect")
2579     {
2580       if (++anArgIt >= theArgsNb)
2581       {
2582         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2583         return 1;
2584       }
2585
2586       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2587       anOption.LowerCase();
2588       if (anOption.IsEqual ("regular"))
2589       {
2590         aTextPrs->SetFontAspect (Font_FA_Regular);
2591       }
2592       else if (anOption.IsEqual ("bold"))
2593       {
2594         aTextPrs->SetFontAspect (Font_FA_Bold);
2595       }
2596       else if (anOption.IsEqual ("italic"))
2597       {
2598         aTextPrs->SetFontAspect (Font_FA_Italic);
2599       }
2600       else if (anOption.IsEqual ("bolditalic"))
2601       {
2602         aTextPrs->SetFontAspect (Font_FA_BoldItalic);
2603       }
2604     }
2605     else if (aParam == "-font")
2606     {
2607       if (++anArgIt >= theArgsNb)
2608       {
2609         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2610         return 1;
2611       }
2612
2613       aTextPrs->SetFont (theArgVec[anArgIt]);
2614     }
2615     else
2616     {
2617       std::cout << "Error: unknown argument '" << aParam << "'\n";
2618       return 1;
2619     }
2620   }
2621
2622   ViewerTest::Display (aName, aTextPrs, Standard_False);
2623   return 0;
2624 }
2625
2626 #include <math.h>
2627 #include <gp_Pnt.hxx>
2628 #include <Graphic3d_ArrayOfPoints.hxx>
2629 #include <Graphic3d_ArrayOfPrimitives.hxx>
2630 #include <Graphic3d_ArrayOfTriangles.hxx>
2631 #include <Poly_Array1OfTriangle.hxx>
2632 #include <Poly_Triangle.hxx>
2633 #include <Poly_Triangulation.hxx>
2634 #include <TColgp_Array1OfPnt.hxx>
2635 #include <TShort_Array1OfShortReal.hxx>
2636 #include <TShort_HArray1OfShortReal.hxx>
2637
2638 #include <AIS_Triangulation.hxx>
2639 #include <StdPrs_ToolShadedShape.hxx>
2640 #include <Poly_Connect.hxx>
2641 #include <TColgp_Array1OfDir.hxx>
2642 #include <Graphic3d_GraphicDriver.hxx>
2643
2644 #include <TColStd_Array1OfInteger.hxx>
2645 #include <TColStd_HArray1OfInteger.hxx>
2646 #include <Prs3d_ShadingAspect.hxx>
2647 #include <Graphic3d_MaterialAspect.hxx>
2648 #include <Graphic3d_AspectFillArea3d.hxx>
2649
2650 #include <BRepPrimAPI_MakeCylinder.hxx>
2651 #include <TopoDS_Shape.hxx>
2652 #include <TopExp_Explorer.hxx>
2653 #include <TopAbs.hxx>
2654 #include <StdSelect_ShapeTypeFilter.hxx>
2655 #include <AIS_InteractiveObject.hxx>
2656
2657
2658 //===============================================================================================
2659 //function : CalculationOfSphere
2660 //author   : psn
2661 //purpose  : Create a Sphere
2662 //===============================================================================================
2663
2664 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2665                                                   int res ,
2666                                                   double Radius ){
2667   double mRadius = Radius;
2668   double mCenter[3] = {X,Y,Z};
2669   int mThetaResolution;
2670   int mPhiResolution;
2671   double mStartTheta = 0;//StartTheta;
2672   double mEndTheta = 360;//EndTheta;
2673   double mStartPhi = 0;//StartPhi;
2674   double mEndPhi = 180;//EndPhi;
2675   res = res < 4 ? 4 : res;
2676
2677   mThetaResolution = res;
2678   mPhiResolution = res;
2679
2680   int i, j;
2681   int jStart, jEnd, numOffset;
2682   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2683   double startTheta, endTheta, startPhi, endPhi;
2684   int base, numPoles=0, thetaResolution, phiResolution;
2685
2686   int pts[3];
2687   int piece = -1;
2688   int numPieces = 1;
2689   if ( numPieces > mThetaResolution ) {
2690     numPieces = mThetaResolution;
2691   }
2692
2693   int localThetaResolution =  mThetaResolution;
2694   double localStartTheta =  mStartTheta;
2695   double localEndTheta =  mEndTheta;
2696
2697   while ( localEndTheta < localStartTheta ) {
2698     localEndTheta += 360.0;
2699   }
2700
2701   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2702
2703   // Change the ivars based on pieces.
2704   int start, end;
2705   start = piece * localThetaResolution / numPieces;
2706   end = (piece+1) * localThetaResolution / numPieces;
2707   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2708   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2709   localThetaResolution = end - start;
2710
2711   // Create north pole if needed
2712   int number_point = 0;
2713   int number_pointArray = 0;
2714
2715   if ( mStartPhi <= 0.0 ) {
2716     number_pointArray++;
2717     numPoles++;
2718   }
2719   if ( mEndPhi >= 180.0 ) {
2720     number_pointArray++;
2721     numPoles++;
2722   }
2723
2724   // Check data, determine increments, and convert to radians
2725   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2726   startTheta *= M_PI  / 180.0;
2727   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2728   endTheta *= M_PI  / 180.0;
2729
2730
2731   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2732   startPhi *= M_PI  / 180.0;
2733   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2734   endPhi *= M_PI  / 180.0;
2735
2736   phiResolution =  mPhiResolution - numPoles;
2737   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2738   thetaResolution = localThetaResolution;
2739   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2740     ++localThetaResolution;
2741   }
2742   deltaTheta = (endTheta - startTheta) / thetaResolution;
2743
2744   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2745   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2746
2747   // Create intermediate points
2748   for ( i = 0; i < localThetaResolution; i++ ) {
2749     for ( j = jStart; j < jEnd; j++ ) {
2750         number_pointArray++;
2751     }
2752   }
2753
2754   //Generate mesh connectivity
2755   base = phiResolution * localThetaResolution;
2756
2757   int number_triangle = 0 ;
2758   if ( mStartPhi <= 0.0 ) { // around north pole
2759     number_triangle += localThetaResolution;
2760   }
2761
2762   if ( mEndPhi >= 180.0 ) { // around south pole
2763     number_triangle += localThetaResolution;
2764   }
2765
2766   // bands in-between poles
2767   for ( i=0; i < localThetaResolution; i++){
2768     for ( j=0; j < (phiResolution-1); j++){
2769        number_triangle +=2;
2770     }
2771   }
2772
2773   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2774   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2775   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2776
2777   if (  mStartPhi <= 0.0 ){
2778       x[0] =  mCenter[0];
2779       x[1] =  mCenter[1];
2780       x[2] =  mCenter[2] +  mRadius;
2781       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2782   }
2783
2784   // Create south pole if needed
2785   if (  mEndPhi >= 180.0 ){
2786       x[0] =  mCenter[0];
2787       x[1] =  mCenter[1];
2788       x[2] =  mCenter[2] -  mRadius;
2789       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2790   }
2791
2792   number_point = 3;
2793   for ( i=0; i < localThetaResolution; i++){
2794     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2795     for ( j = jStart; j < jEnd; j++){
2796         phi = startPhi + j*deltaPhi;
2797         radius =  mRadius * sin((double)phi);
2798         n[0] = radius * cos((double)theta);
2799         n[1] = radius * sin((double)theta);
2800         n[2] =  mRadius * cos((double)phi);
2801         x[0] = n[0] +  mCenter[0];
2802         x[1] = n[1] +  mCenter[1];
2803         x[2] = n[2] +  mCenter[2];
2804         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2805         number_point++;
2806       }
2807     }
2808
2809   numPoles = 3;
2810   number_triangle = 1;
2811   if ( mStartPhi <= 0.0 ){// around north pole
2812     for (i=0; i < localThetaResolution; i++){
2813         pts[0] = phiResolution*i + numPoles;
2814         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2815         pts[2] = 1;
2816         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2817         number_triangle++;
2818       }
2819     }
2820
2821   if (  mEndPhi >= 180.0 ){ // around south pole
2822     numOffset = phiResolution - 1 + numPoles;
2823     for (i=0; i < localThetaResolution; i++){
2824         pts[0] = phiResolution*i + numOffset;
2825         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2826         pts[1] = numPoles - 1;
2827         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2828         number_triangle++;
2829       }
2830     }
2831
2832   // bands in-between poles
2833
2834   for (i=0; i < localThetaResolution; i++){
2835     for (j=0; j < (phiResolution-1); j++){
2836         pts[0] = phiResolution*i + j + numPoles;
2837         pts[1] = pts[0] + 1;
2838         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2839         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2840         number_triangle++;
2841         pts[1] = pts[2];
2842         pts[2] = pts[1] - 1;
2843         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2844         number_triangle++;
2845       }
2846     }
2847
2848   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2849
2850   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2851
2852   Standard_Integer index[3];
2853   Standard_Real Tol = Precision::Confusion();
2854
2855   gp_Dir Nor;
2856   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2857       gp_XYZ eqPlan(0, 0, 0);
2858       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2859         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2860         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2861         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2862         gp_XYZ vv = v1^v2;
2863         Standard_Real mod = vv.Modulus();
2864         if(mod < Tol) continue;
2865         eqPlan += vv/mod;
2866       }
2867
2868       Standard_Real modmax = eqPlan.Modulus();
2869
2870       if(modmax > Tol)
2871         Nor = gp_Dir(eqPlan);
2872       else
2873         Nor = gp_Dir(0., 0., 1.);
2874
2875       Standard_Integer j = (i - PointsOfArray.Lower()) * 3;
2876       Normals->SetValue(j + 1, (Standard_ShortReal)Nor.X());
2877       Normals->SetValue(j + 2, (Standard_ShortReal)Nor.Y());
2878       Normals->SetValue(j + 3, (Standard_ShortReal)Nor.Z());
2879   }
2880
2881   delete pc;
2882   polyTriangulation->SetNormals(Normals);
2883
2884   return polyTriangulation;
2885 }
2886
2887 //===============================================================================================
2888 //function : VDrawSphere
2889 //author   : psn
2890 //purpose  : Create an AIS shape.
2891 //===============================================================================================
2892 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2893 {
2894   // check for errors
2895   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2896   if (aContextAIS.IsNull())
2897   {
2898     std::cout << "Call vinit before!\n";
2899     return 1;
2900   }
2901   else if (argc < 3)
2902   {
2903     std::cout << "Use: " << argv[0]
2904               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2905     return 1;
2906   }
2907
2908   // read the arguments
2909   TCollection_AsciiString aShapeName (argv[1]);
2910   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2911   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2912   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2913   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
2914   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
2915   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
2916   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
2917
2918   // remove AIS object with given name from map
2919   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
2920
2921   if (toPrintInfo)
2922     std::cout << "Compute Triangulation...\n";
2923   Handle(AIS_Triangulation) aShape
2924     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2925                                                   aResolution,
2926                                                   aRadius));
2927   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2928   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2929
2930   // stupid initialization of Green color in RGBA space as integer
2931   // probably wrong for big-endian CPUs
2932   Standard_Integer aRed    = 0;
2933   Standard_Integer aGreen  = 255;
2934   Standard_Integer aBlue   = 0;
2935   Standard_Integer anAlpha = 0; // not used
2936   Standard_Integer aColorInt = aRed;
2937   aColorInt += aGreen  << 8;
2938   aColorInt += aBlue   << 16;
2939   aColorInt += anAlpha << 24;
2940
2941   // setup colors array per vertex
2942   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2943   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2944   {
2945     aColorArray->SetValue (aNodeId, aColorInt);
2946   }
2947   aShape->SetColors (aColorArray);
2948
2949   // show statistics
2950   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2951   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2952   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2953   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2954   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
2955   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
2956   aTotalSize >>= 20; //MB
2957   aNormalsSize >>= 20;
2958   aColorsSize >>= 20;
2959   aTrianglesSize >>= 20;
2960   aPolyConnectSize >>= 20;
2961   if (toPrintInfo)
2962   {
2963     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
2964       << "NumberOfTriangles: " << aNumberTriangles << "\n"
2965       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
2966       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
2967       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
2968       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
2969   }
2970
2971   // Setting material properties, very important for desirable visual result!
2972   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
2973   aMat.SetAmbient (0.2);
2974   aMat.SetSpecular (0.5);
2975   Handle(Graphic3d_AspectFillArea3d) anAspect
2976     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
2977                                       Quantity_NOC_RED,
2978                                       Quantity_NOC_YELLOW,
2979                                       Aspect_TOL_SOLID,
2980                                       1.0,
2981                                       aMat,
2982                                       aMat);
2983   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
2984   if (toShowEdges)
2985   {
2986     anAspect->SetEdgeOn();
2987   }
2988   else
2989   {
2990     anAspect->SetEdgeOff();
2991   }
2992   aShAsp->SetAspect (anAspect);
2993   aShape->Attributes()->SetShadingAspect (aShAsp);
2994
2995   VDisplayAISObject (aShapeName, aShape);
2996   return 0;
2997 }
2998
2999 //=============================================================================
3000 //function : VComputeHLR
3001 //purpose  :
3002 //=============================================================================
3003
3004 static int VComputeHLR (Draw_Interpretor& di,
3005                         Standard_Integer argc,
3006                         const char** argv)
3007 {
3008   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3009
3010   if (aContextAIS.IsNull ())
3011   {
3012     di << "Please call vinit before\n";
3013     return 1;
3014   }
3015
3016   if ( argc != 3 &&  argc != 12 )
3017   {
3018     di << "Usage: " << argv[0] << " ShapeName HlrName "
3019        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]" << "\n"
3020        << "                    ShapeName - name of the initial shape\n"
3021        << "                    HlrName - result hlr object from initial shape\n"
3022        << "                    eye, dir are eye position and look direction\n"
3023        << "                    up is the look up direction vector\n"
3024        << "                    Use vtop to see projected hlr shape\n";
3025     return 1;
3026   }
3027
3028   // shape and new object name
3029   TCollection_AsciiString aShapeName (argv[1]);
3030   TCollection_AsciiString aHlrName (argv[2]);
3031
3032   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3033   if (aSh.IsNull()) 
3034   {
3035     BRep_Builder aBrepBuilder;
3036     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3037     if (aSh.IsNull ())
3038     {
3039       di << "No shape with name " << argv[1] << " found\n";
3040       return 1;
3041     }
3042   }
3043
3044   if (GetMapOfAIS ().IsBound2 (aHlrName))
3045   {
3046     di << "Presentable object with name " << argv[2] << " already exists\n";
3047     return 1;
3048   }
3049
3050   // close local context
3051   if (aContextAIS->HasOpenedContext ())
3052     aContextAIS->CloseLocalContext ();
3053
3054   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3055   HLRBRep_PolyHLRToShape aHLRToShape;
3056
3057   gp_Pnt anEye;
3058   gp_Dir aDir;
3059   gp_Ax2 aProjAx;
3060   if (argc == 9)
3061   {
3062     gp_Dir anUp;
3063
3064     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3065     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3066     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3067     aProjAx.SetLocation (anEye);
3068     aProjAx.SetDirection (aDir);
3069     aProjAx.SetYDirection (anUp);
3070   }
3071   else
3072   {
3073     gp_Dir aRight;
3074
3075     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3076     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3077     Standard_Integer aWidth, aHeight;
3078     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3079     Standard_Real aRightX, aRightY, aRightZ;
3080     aView->Window()->Size (aWidth, aHeight);
3081
3082     aView->ConvertWithProj (aWidth, aHeight/2, 
3083                             aRightX, aRightY, aRightZ,
3084                             aDirX, aDirY, aDirZ);
3085
3086     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3087                             aCentX, aCentY, aCentZ,
3088                             aDirX, aDirY, aDirZ);
3089
3090     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3091     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3092     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3093     aProjAx.SetLocation (anEye);
3094     aProjAx.SetDirection (aDir);
3095     aProjAx.SetXDirection (aRight);
3096   }
3097
3098   HLRAlgo_Projector aProjector (aProjAx);
3099   aPolyAlgo->Projector (aProjector);
3100   aPolyAlgo->Load (aSh);
3101   aPolyAlgo->Update ();
3102
3103   aHLRToShape.Update (aPolyAlgo);
3104
3105   // make hlr shape from input shape
3106   TopoDS_Compound aHlrShape;
3107   BRep_Builder aBuilder;
3108   aBuilder.MakeCompound (aHlrShape);
3109
3110   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3111   if (!aCompound.IsNull ())
3112   {
3113     aBuilder.Add (aHlrShape, aCompound);
3114   }
3115   
3116   // extract visible outlines
3117   aCompound = aHLRToShape.OutLineVCompound();
3118   if (!aCompound.IsNull ())
3119   {
3120     aBuilder.Add (aHlrShape, aCompound);
3121   }
3122
3123   // create an AIS shape and display it
3124   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3125   GetMapOfAIS().Bind (anObject, aHlrName);
3126   aContextAIS->Display (anObject);
3127
3128   aContextAIS->UpdateCurrentViewer ();
3129
3130   return 0;
3131 }
3132
3133 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3134 // manipulating and displaying such an array with AIS context
3135
3136 class MyPArrayObject : public AIS_InteractiveObject
3137 {
3138
3139 public:
3140
3141   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3142                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3143   {
3144     myArrayDescription = theArrayDescription;
3145     myMarkerAspect = theMarkerAspect;
3146   }
3147
3148   DEFINE_STANDARD_RTTI(MyPArrayObject, AIS_InteractiveObject);
3149
3150 private:
3151
3152   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3153                 const Handle(Prs3d_Presentation)& aPresentation,
3154                 const Standard_Integer aMode);
3155
3156   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3157                          const Standard_Integer /*theMode*/);
3158
3159   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3160                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3161                           Standard_Integer &theArgIndex,
3162                           Standard_Integer theArgCount,
3163                           Standard_Integer theMaxArgs);
3164
3165 protected:
3166
3167   Handle(TColStd_HArray1OfAsciiString) myArrayDescription;
3168   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3169
3170 };
3171
3172
3173 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3174                               const Handle(Prs3d_Presentation)& aPresentation,
3175                               const Standard_Integer /*aMode*/)
3176 {
3177
3178   // Parsing array description
3179   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3180   Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
3181   hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
3182
3183   Standard_Integer anArgIndex = 0;
3184   Standard_Integer anArgsCount = myArrayDescription->Length();
3185   TCollection_AsciiString anArrayType = myArrayDescription->Value (anArgIndex++);
3186
3187   TCollection_AsciiString aCommand;
3188   while (anArgIndex < anArgsCount)
3189   {
3190     aCommand = myArrayDescription->Value (anArgIndex);
3191     aCommand.LowerCase();
3192
3193     // vertex command
3194     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3195     {
3196       // vertex has a normal or normal with color or texel
3197       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3198         hasNormals = Standard_True;
3199
3200       // vertex has a color
3201       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3202         hasVColors = Standard_True;
3203
3204       // vertex has a texel
3205       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3206         hasTexels = Standard_True;
3207
3208       aVertexNum++;
3209     }
3210     // bound command
3211     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3212     {
3213       // bound has color
3214       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3215         hasBColors = Standard_True;
3216
3217       aBoundNum++;
3218     }
3219     // edge command
3220     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3221     {
3222       aEdgeNum++;
3223     }
3224     // unknown command
3225     else
3226       anArgIndex++;
3227   }
3228
3229   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3230   if (anArrayType == "points")
3231   {
3232     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3233   }
3234   else if (anArrayType == "segments")
3235     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3236   else if (anArrayType == "polylines")
3237     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3238                                               hasVColors, hasBColors);
3239   else if (anArrayType == "triangles")
3240     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3241                                               hasVColors, hasTexels);
3242   else if (anArrayType == "trianglefans")
3243     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3244                                                  hasNormals, hasVColors,
3245                                                  hasBColors, hasTexels);
3246   else if (anArrayType == "trianglestrips")
3247     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3248                                                    hasNormals, hasVColors,
3249                                                    hasBColors, hasTexels);
3250   else if (anArrayType == "quads")
3251     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3252                                                 hasNormals, hasVColors,
3253                                                 hasTexels);
3254   else if (anArrayType == "quadstrips")
3255     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3256                                                      hasNormals, hasVColors,
3257                                                      hasBColors, hasTexels);
3258   else if (anArrayType == "polygons")
3259     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3260                                              hasNormals, hasVColors, hasBColors,
3261                                              hasTexels);
3262
3263   anArgIndex = 1;
3264   while (anArgIndex < anArgsCount)
3265   {
3266     aCommand = myArrayDescription->Value (anArgIndex);
3267     aCommand.LowerCase();
3268     if (!aCommand.IsAscii())
3269       break;
3270
3271     // vertex command
3272     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3273     {
3274       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3275                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
3276                           myArrayDescription->Value (anArgIndex - 1).RealValue());
3277       const Standard_Integer aVertIndex = anArray->VertexNumber();
3278
3279       // vertex has a normal or normal with color or texel
3280       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3281         anArray->SetVertexNormal (aVertIndex,
3282                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
3283                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
3284                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
3285       
3286       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3287         anArray->SetVertexColor (aVertIndex,
3288                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
3289                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3290                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3291       
3292       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3293         anArray->SetVertexTexel (aVertIndex,
3294                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3295                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3296     }
3297     // bounds command
3298     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3299     {
3300       Standard_Integer aVertCount = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3301
3302       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3303         anArray->AddBound (aVertCount,
3304                            myArrayDescription->Value (anArgIndex - 3).RealValue(),
3305                            myArrayDescription->Value (anArgIndex - 2).RealValue(),
3306                            myArrayDescription->Value (anArgIndex - 1).RealValue());
3307
3308       else
3309         anArray->AddBound (aVertCount);
3310     }
3311     // edge command
3312     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3313     {
3314       const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3315       anArray->AddEdge (aVertIndex);
3316     }
3317     // unknown command
3318     else
3319       anArgIndex++;
3320   }
3321
3322   aPresentation->Clear();
3323   if (!myMarkerAspect.IsNull())
3324   {
3325     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
3326   }
3327   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
3328 }
3329
3330 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3331                                        const Standard_Integer /*theMode*/)
3332 {
3333   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
3334
3335   Standard_Integer anArgIndex = 1;
3336   while (anArgIndex < myArrayDescription->Length())
3337   {
3338     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, myArrayDescription->Length()))
3339     {
3340       gp_Pnt aPoint (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3341                      myArrayDescription->Value (anArgIndex - 2).RealValue(),
3342                      myArrayDescription->Value (anArgIndex - 1).RealValue());
3343       Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
3344       theSelection->Add (aSensetivePoint);
3345     }
3346     else
3347     {
3348       anArgIndex++;
3349     }
3350   }
3351 }
3352
3353 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3354                                        const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3355                                        Standard_Integer &theArgIndex,
3356                                        Standard_Integer theArgCount,
3357                                        Standard_Integer theMaxArgs)
3358 {
3359   // check if there is more elements than expected
3360   if (theArgIndex >= theMaxArgs)
3361     return false;
3362
3363   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3364   aStrCommand.LowerCase();
3365   if (aStrCommand.Search(theCommand) != 1 ||
3366       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3367     return false;
3368
3369   // go to the first data element
3370   theArgIndex++;
3371
3372   // check data if it can be converted to numeric
3373   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3374   {
3375     aStrCommand = theArgsArray->Value (theArgIndex);
3376     if (!aStrCommand.IsRealValue())
3377       return false;
3378   }
3379
3380   return true;
3381 }
3382
3383 //=====================================================================