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