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