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