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