0022796: Possibility to display multi-line text in 3D
[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 || *(str+1)=='\x0A' || *(str+1)=='\x0B' || *(str+1)=='\x0C' || *(str+1)=='\x0D'
2448                  || *(str+1)=='\x07' || *(str+1)=='\x08' || *(str+1)=='\x09' )
2449     {
2450       unsigned short c1 = *str++;
2451       unsigned short c2 = *str++;
2452       if (!c2) break;
2453       name += (Standard_ExtCharacter)((c1 << 8) | c2);
2454     }
2455   }
2456   else
2457   {
2458     name += argv[1];
2459   }
2460
2461   if (name.Length())
2462   {
2463     Handle(MyTextClass) myT = new MyTextClass(name,pnt,aColor,hor_align,ver_align,angle,zoom,height,aspect,font.ToCString());
2464     aContext->Display(myT,Standard_True);
2465   }
2466
2467   return 0;
2468 }
2469
2470 #include <math.h>
2471 #include <gp_Pnt.hxx>
2472 #include <Graphic3d_ArrayOfPoints.hxx>
2473 #include <Graphic3d_ArrayOfPrimitives.hxx>
2474 #include <Graphic3d_Array1OfVertex.hxx>
2475 #include <Graphic3d_ArrayOfTriangles.hxx>
2476 #include <Poly_Array1OfTriangle.hxx>
2477 #include <Poly_Triangle.hxx>
2478 #include <Poly_Triangulation.hxx>
2479 #include <TColgp_Array1OfPnt.hxx>
2480 #include <TShort_Array1OfShortReal.hxx>
2481 #include <TShort_HArray1OfShortReal.hxx>
2482
2483 #include <AIS_Triangulation.hxx>
2484 #include <Aspect_GraphicDevice.hxx>
2485 #include <StdPrs_ToolShadedShape.hxx>
2486 #include <Poly_Connect.hxx>
2487 #include <TColgp_Array1OfDir.hxx>
2488 #include <Graphic3d_GraphicDriver.hxx>
2489
2490 #include <TColStd_Array1OfInteger.hxx>
2491 #include <TColStd_HArray1OfInteger.hxx>
2492 #include <Prs3d_ShadingAspect.hxx>
2493 #include <Graphic3d_MaterialAspect.hxx>
2494 #include <Graphic3d_AspectFillArea3d.hxx>
2495
2496 #include <BRepPrimAPI_MakeCylinder.hxx>
2497 #include <TopoDS_Shape.hxx>
2498 #include <TopExp_Explorer.hxx>
2499 #include <TopAbs.hxx>
2500 #include <StdSelect_ShapeTypeFilter.hxx>
2501
2502
2503 //===============================================================================================
2504 //function : CalculationOfSphere
2505 //author   : psn
2506 //purpose  : Create a Sphere
2507 //===============================================================================================
2508
2509 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2510                                                   int res ,
2511                                                   double Radius ){
2512   double mRadius = Radius;
2513   double mCenter[3] = {X,Y,Z};
2514   int mThetaResolution;
2515   int mPhiResolution;
2516   double mStartTheta = 0;//StartTheta;
2517   double mEndTheta = 360;//EndTheta;
2518   double mStartPhi = 0;//StartPhi;
2519   double mEndPhi = 180;//EndPhi;
2520   res = res < 4 ? 4 : res;
2521
2522   mThetaResolution = res;
2523   mPhiResolution = res;
2524
2525   int i, j;
2526   int jStart, jEnd, numOffset;
2527   int numPts, numPolys;
2528   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2529   double startTheta, endTheta, startPhi, endPhi;
2530   int base, numPoles=0, thetaResolution, phiResolution;
2531
2532   int pts[3];
2533   int piece = -1;
2534   int numPieces = 1;
2535   if ( numPieces > mThetaResolution ) {
2536     numPieces = mThetaResolution;
2537   }
2538
2539   int localThetaResolution =  mThetaResolution;
2540   double localStartTheta =  mStartTheta;
2541   double localEndTheta =  mEndTheta;
2542
2543   while ( localEndTheta < localStartTheta ) {
2544     localEndTheta += 360.0;
2545   }
2546
2547   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2548
2549   // Change the ivars based on pieces.
2550   int start, end;
2551   start = piece * localThetaResolution / numPieces;
2552   end = (piece+1) * localThetaResolution / numPieces;
2553   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2554   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2555   localThetaResolution = end - start;
2556
2557   numPts =  mPhiResolution * localThetaResolution + 2;
2558   numPolys =  mPhiResolution * 2 * localThetaResolution;
2559
2560   // Create north pole if needed
2561   int number_point = 0;
2562   int number_pointArray = 0;
2563
2564   if ( mStartPhi <= 0.0 ) {
2565     number_pointArray++;
2566     numPoles++;
2567   }
2568   if ( mEndPhi >= 180.0 ) {
2569     number_pointArray++;
2570     numPoles++;
2571   }
2572
2573   // Check data, determine increments, and convert to radians
2574   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2575   startTheta *= M_PI  / 180.0;
2576   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2577   endTheta *= M_PI  / 180.0;
2578
2579
2580   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2581   startPhi *= M_PI  / 180.0;
2582   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2583   endPhi *= M_PI  / 180.0;
2584
2585   phiResolution =  mPhiResolution - numPoles;
2586   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2587   thetaResolution = localThetaResolution;
2588   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2589     ++localThetaResolution;
2590   }
2591   deltaTheta = (endTheta - startTheta) / thetaResolution;
2592
2593   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2594   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2595
2596   // Create intermediate points
2597   for ( i = 0; i < localThetaResolution; i++ ) {
2598     for ( j = jStart; j < jEnd; j++ ) {
2599         number_pointArray++;
2600     }
2601   }
2602
2603   //Generate mesh connectivity
2604   base = phiResolution * localThetaResolution;
2605
2606   int number_triangle = 0 ;
2607   if ( mStartPhi <= 0.0 ) { // around north pole
2608     number_triangle += localThetaResolution;
2609   }
2610
2611   if ( mEndPhi >= 180.0 ) { // around south pole
2612     number_triangle += localThetaResolution;
2613   }
2614
2615   // bands in-between poles
2616   for ( i=0; i < localThetaResolution; i++){
2617     for ( j=0; j < (phiResolution-1); j++){
2618        number_triangle +=2;
2619     }
2620   }
2621
2622   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2623   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2624   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2625
2626   if (  mStartPhi <= 0.0 ){
2627       x[0] =  mCenter[0];
2628       x[1] =  mCenter[1];
2629       x[2] =  mCenter[2] +  mRadius;
2630       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2631   }
2632
2633   // Create south pole if needed
2634   if (  mEndPhi >= 180.0 ){
2635       x[0] =  mCenter[0];
2636       x[1] =  mCenter[1];
2637       x[2] =  mCenter[2] -  mRadius;
2638       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2639   }
2640
2641   number_point = 3;
2642   for ( i=0; i < localThetaResolution; i++){
2643     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2644     for ( j = jStart; j < jEnd; j++){
2645         phi = startPhi + j*deltaPhi;
2646         radius =  mRadius * sin((double)phi);
2647         n[0] = radius * cos((double)theta);
2648         n[1] = radius * sin((double)theta);
2649         n[2] =  mRadius * cos((double)phi);
2650         x[0] = n[0] +  mCenter[0];
2651         x[1] = n[1] +  mCenter[1];
2652         x[2] = n[2] +  mCenter[2];
2653         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2654         number_point++;
2655       }
2656     }
2657
2658   numPoles = 3;
2659   number_triangle = 1;
2660   if ( mStartPhi <= 0.0 ){// around north pole
2661     for (i=0; i < localThetaResolution; i++){
2662         pts[0] = phiResolution*i + numPoles;
2663         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2664         pts[2] = 1;
2665         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2666         number_triangle++;
2667       }
2668     }
2669
2670   if (  mEndPhi >= 180.0 ){ // around south pole
2671     numOffset = phiResolution - 1 + numPoles;
2672     for (i=0; i < localThetaResolution; i++){
2673         pts[0] = phiResolution*i + numOffset;
2674         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2675         pts[1] = numPoles - 1;
2676         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2677         number_triangle++;
2678       }
2679     }
2680
2681   // bands in-between poles
2682
2683   for (i=0; i < localThetaResolution; i++){
2684     for (j=0; j < (phiResolution-1); j++){
2685         pts[0] = phiResolution*i + j + numPoles;
2686         pts[1] = pts[0] + 1;
2687         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2688         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2689         number_triangle++;
2690         pts[1] = pts[2];
2691         pts[2] = pts[1] - 1;
2692         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2693         number_triangle++;
2694       }
2695     }
2696
2697   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2698
2699   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2700
2701   Standard_Integer index[3];
2702   Standard_Real Tol = Precision::Confusion();
2703
2704   gp_Dir Nor;
2705   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2706       gp_XYZ eqPlan(0, 0, 0);
2707       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2708         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2709         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2710         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2711         gp_XYZ vv = v1^v2;
2712         Standard_Real mod = vv.Modulus();
2713         if(mod < Tol) continue;
2714         eqPlan += vv/mod;
2715       }
2716
2717       Standard_Real modmax = eqPlan.Modulus();
2718
2719       if(modmax > Tol)
2720         Nor = gp_Dir(eqPlan);
2721       else
2722         Nor = gp_Dir(0., 0., 1.);
2723
2724       Standard_Integer j = (i - PointsOfArray.Lower()) * 3;
2725       Normals->SetValue(j + 1, (Standard_ShortReal)Nor.X());
2726       Normals->SetValue(j + 2, (Standard_ShortReal)Nor.Y());
2727       Normals->SetValue(j + 3, (Standard_ShortReal)Nor.Z());
2728   }
2729
2730   delete pc;
2731   polyTriangulation->SetNormals(Normals);
2732
2733   return polyTriangulation;
2734 }
2735
2736 //===============================================================================================
2737 //function : VDrawSphere
2738 //author   : psn
2739 //purpose  : Create an AIS shape.
2740 //===============================================================================================
2741 static int VDrawSphere (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2742 {
2743   // check for errors
2744   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2745   if (aContextAIS.IsNull())
2746   {
2747     std::cout << "Call vinit before!\n";
2748     return 1;
2749   }
2750   else if (argc < 3)
2751   {
2752     std::cout << "Use: " << argv[0]
2753               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToEnableVBO=1] [NumberOfViewerUpdate=1] [ToShowEdges=0]\n";
2754     return 1;
2755   }
2756
2757   // read the arguments
2758   TCollection_AsciiString aShapeName (argv[1]);
2759   Standard_Integer aResolution = atoi (argv[2]);
2760   Standard_Real aCenterX = (argc > 5) ? atof (argv[3]) : 0.0;
2761   Standard_Real aCenterY = (argc > 5) ? atof (argv[4]) : 0.0;
2762   Standard_Real aCenterZ = (argc > 5) ? atof (argv[5]) : 0.0;
2763   Standard_Real aRadius =  (argc > 6) ? atof (argv[6]) : 100.0;
2764   Standard_Boolean isVBOEnabled = (argc > 7) ? atoi (argv[7]) : Standard_True;
2765   Standard_Integer aRedrawsNb =   (argc > 8) ? atoi (argv[8]) : 1;
2766   Standard_Boolean toShowEdges =  (argc > 9) ? atoi (argv[9]) : Standard_False;
2767
2768   if (aRedrawsNb <= 0)
2769   {
2770     aRedrawsNb = 1;
2771   }
2772
2773   // remove AIS object with given name from map
2774   if (GetMapOfAIS().IsBound2 (aShapeName))
2775   {
2776     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aShapeName);
2777     Handle(AIS_InteractiveObject) anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
2778     if (anInterObj.IsNull())
2779     {
2780       std::cout << "Shape name was used for non AIS viewer\n!";
2781       return 1;
2782     }
2783     aContextAIS->Remove (anInterObj, Standard_False);
2784     GetMapOfAIS().UnBind2 (aShapeName);
2785   }
2786
2787   // enable/disable VBO
2788   Handle(Graphic3d_GraphicDriver) aDriver =
2789          Handle(Graphic3d_GraphicDriver)::DownCast (aContextAIS->CurrentViewer()->Device()->GraphicDriver());
2790   if (!aDriver.IsNull())
2791   {
2792     aDriver->EnableVBO (isVBOEnabled);
2793   }
2794
2795   std::cout << "Compute Triangulation...\n";
2796   Handle(AIS_Triangulation) aShape
2797     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2798                                                   aResolution,
2799                                                   aRadius));
2800   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2801   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2802
2803   // register the object in map
2804   GetMapOfAIS().Bind (aShape, aShapeName);
2805
2806   // stupid initialization of Green color in RGBA space as integer
2807   // probably wrong for big-endian CPUs
2808   Standard_Integer aRed    = 0;
2809   Standard_Integer aGreen  = 255;
2810   Standard_Integer aBlue   = 0;
2811   Standard_Integer anAlpha = 0; // not used
2812   Standard_Integer aColorInt = aRed;
2813   aColorInt += aGreen  << 8;
2814   aColorInt += aBlue   << 16;
2815   aColorInt += anAlpha << 24;
2816
2817   // setup colors array per vertex
2818   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2819   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2820   {
2821     aColorArray->SetValue (aNodeId, aColorInt);
2822   }
2823   aShape->SetColors (aColorArray);
2824
2825   // show statistics
2826   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2827   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2828   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2829   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2830   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
2831   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
2832   aTotalSize >>= 20; //MB
2833   aNormalsSize >>= 20;
2834   aColorsSize >>= 20;
2835   aTrianglesSize >>= 20;
2836   aPolyConnectSize >>= 20;
2837   std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
2838             << "NumberOfTriangles: " << aNumberTriangles << "\n"
2839             << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
2840             << "Amount of memory for colors: " << aColorsSize << " Mb\n"
2841             << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
2842             << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
2843
2844   // Setting material properties, very important for desirable visual result!
2845   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
2846   aMat.SetAmbient (0.2);
2847   aMat.SetSpecular (0.5);
2848   Handle(Graphic3d_AspectFillArea3d) anAspect
2849     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
2850                                       Quantity_NOC_RED,
2851                                       Quantity_NOC_YELLOW,
2852                                       Aspect_TOL_SOLID,
2853                                       1.0,
2854                                       aMat,
2855                                       aMat);
2856   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
2857   if (toShowEdges)
2858   {
2859     anAspect->SetEdgeOn();
2860   }
2861   else
2862   {
2863     anAspect->SetEdgeOff();
2864   }
2865   aShAsp->SetAspect (anAspect);
2866   aShape->Attributes()->SetShadingAspect (aShAsp);
2867
2868   aContextAIS->Display (aShape, Standard_False);
2869
2870   // Two viewer updates are needed in order to measure time spent on
2871   // loading triangulation to graphic card memory + redrawing (1st update) and
2872   // time spent on redrawing itself (2nd and all further updates)
2873   OSD_Chronometer aTimer;
2874   Standard_Real aUserSeconds, aSystemSeconds;
2875   aTimer.Start();
2876   const Handle(V3d_Viewer)& aViewer = aContextAIS->CurrentViewer();
2877   for (Standard_Integer anInteration = 0; anInteration < aRedrawsNb; ++anInteration)
2878   {
2879     for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
2880     {
2881       if (anInteration == 0)
2882       {
2883         aViewer->ActiveView()->Update();
2884       }
2885       else
2886       {
2887         aViewer->ActiveView()->Redraw();
2888       }
2889     }
2890   }
2891   aTimer.Show (aUserSeconds, aSystemSeconds);
2892   aTimer.Stop();
2893   std::cout << "Number of scene redrawings: " << aRedrawsNb << "\n"
2894             << "CPU user time: "
2895             << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * aUserSeconds
2896             << " msec\n"
2897             << "CPU system time: "
2898             << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * aSystemSeconds
2899             << " msec\n"
2900             << "CPU average time of scene redrawing: "
2901             << std::setiosflags(std::ios::fixed) << std::setprecision(16) << 1000.0 * (aUserSeconds / (Standard_Real )aRedrawsNb)
2902             << " msec\n";
2903   return 0;
2904 }
2905
2906 //===============================================================================================
2907 //function : VClipPlane
2908 //purpose  :
2909 //===============================================================================================
2910 static int VClipPlane (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
2911 {
2912   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
2913   Handle(V3d_View) aView = ViewerTest::CurrentView();
2914   Standard_Real coeffA, coeffB, coeffC, coeffD;
2915   if (aViewer.IsNull() || aView.IsNull())
2916   {
2917     std::cout << "Viewer not initialized!\n";
2918     return 1;
2919   }
2920
2921   // count an active planes count
2922   Standard_Integer aNewPlaneId = 1;
2923   Standard_Integer anActivePlanes = 0;
2924   for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aNewPlaneId)
2925   {
2926     Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane();
2927     if (aView->IsActivePlane (aPlaneV3d))
2928     {
2929       ++anActivePlanes;
2930     }
2931   }
2932
2933   if (argc == 1)
2934   {
2935     // just show info about existing planes
2936     Standard_Integer aPlaneId = 1;
2937     std::cout << "Active planes: " << anActivePlanes << " from maximal " << aView->View()->PlaneLimit() << "\n";
2938     for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aPlaneId)
2939     {
2940       Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane();
2941       aPlaneV3d->Plane (coeffA, coeffB, coeffC, coeffD);
2942       gp_Pln aPlane (coeffA, coeffB, coeffC, coeffD);
2943       const gp_Pnt& aLoc = aPlane.Location();
2944       const gp_Dir& aNor = aPlane.Axis().Direction();
2945       Standard_Boolean isActive = aView->IsActivePlane (aPlaneV3d);
2946       std::cout << "Plane #" << aPlaneId
2947         << " " << aLoc.X() << " " << aLoc.Y() << " " << aLoc.Z()
2948         << " " << aNor.X() << " " << aNor.Y() << " " << aNor.Z()
2949         << (isActive ? " on" : " off")
2950         << (aPlaneV3d->IsDisplayed() ? ", displayed" : ", hidden")
2951         << "\n";
2952     }
2953     if (aPlaneId == 1)
2954     {
2955       std::cout << "No defined clipping planes\n";
2956     }
2957     return 0;
2958   }
2959   else if (argc == 2 || argc == 3)
2960   {
2961     Standard_Integer aPlaneIdToOff = (argc == 3) ? atoi (argv[1]) : 1;
2962     Standard_Boolean toIterateAll = (argc == 2);
2963     TCollection_AsciiString isOnOffStr ((argc == 3) ? argv[2] : argv[1]);
2964     isOnOffStr.LowerCase();
2965     Standard_Integer aPlaneId = 1;
2966     for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aPlaneId)
2967     {
2968       if (aPlaneIdToOff == aPlaneId || toIterateAll)
2969       {
2970         Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane();
2971         if (isOnOffStr.Search ("off") >= 0)
2972         {
2973           aView->SetPlaneOff (aPlaneV3d);
2974           std::cout << "Clipping plane #" << aPlaneId << " was disabled\n";
2975         }
2976         else if (isOnOffStr.Search ("on") >= 0)
2977         {
2978           // avoid z-fighting glitches
2979           aPlaneV3d->Erase();
2980           if (!aView->IsActivePlane (aPlaneV3d))
2981           {
2982             if (anActivePlanes < aView->View()->PlaneLimit())
2983             {
2984               aView->SetPlaneOn (aPlaneV3d);
2985               std::cout << "Clipping plane #" << aPlaneId << " was enabled\n";
2986             }
2987             else
2988             {
2989               std::cout << "Maximal active planes limit exceeded (" << anActivePlanes << ")\n"
2990                         << "You should disable or remove some existing plane to activate this one\n";
2991             }
2992           }
2993           else
2994           {
2995             std::cout << "Clipping plane #" << aPlaneId << " was already enabled\n";
2996           }
2997         }
2998         else if (isOnOffStr.Search ("del") >= 0 || isOnOffStr.Search ("rem") >= 0)
2999         {
3000           aPlaneV3d->Erase(); // not performed on destructor!!!
3001           aView->SetPlaneOff (aPlaneV3d);
3002           aViewer->DelPlane (aPlaneV3d);
3003           std::cout << "Clipping plane #" << aPlaneId << " was removed\n";
3004           if (toIterateAll)
3005           {
3006             for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->InitDefinedPlanes(), ++aPlaneId)
3007             {
3008               aPlaneV3d = aViewer->DefinedPlane();
3009               aPlaneV3d->Erase(); // not performed on destructor!!!
3010               aView->SetPlaneOff (aPlaneV3d);
3011               aViewer->DelPlane (aPlaneV3d);
3012               std::cout << "Clipping plane #" << aPlaneId << " was removed\n";
3013             }
3014             break;
3015           }
3016           else
3017           {
3018             break;
3019           }
3020         }
3021         else if (isOnOffStr.Search ("disp") >= 0 || isOnOffStr.Search ("show") >= 0)
3022         {
3023           // avoid z-fighting glitches
3024           aView->SetPlaneOff (aPlaneV3d);
3025           aPlaneV3d->Display (aView);
3026           std::cout << "Clipping plane #" << aPlaneId << " was shown and disabled\n";
3027         }
3028         else if (isOnOffStr.Search ("hide") >= 0)
3029         {
3030           aPlaneV3d->Erase();
3031           std::cout << "Clipping plane #" << aPlaneId << " was hidden\n";
3032         }
3033         else
3034         {
3035           std::cout << "Usage: " << argv[0] << " [x y z dx dy dz] [planeId {on/off/del/display/hide}]\n";
3036           return 1;
3037         }
3038       }
3039     }
3040     if (aPlaneIdToOff >= aPlaneId && !toIterateAll)
3041     {
3042       std::cout << "Clipping plane with id " << aPlaneIdToOff << " not found!\n";
3043       return 1;
3044     }
3045     aView->Update();
3046     return 0;
3047   }
3048   else if (argc != 7)
3049   {
3050     std::cout << "Usage: " << argv[0] << " [x y z dx dy dz] [planeId {on/off/del/display/hide}]\n";
3051     return 1;
3052   }
3053
3054   Standard_Real aLocX = atof (argv[1]);
3055   Standard_Real aLocY = atof (argv[2]);
3056   Standard_Real aLocZ = atof (argv[3]);
3057   Standard_Real aNormDX = atof (argv[4]);
3058   Standard_Real aNormDY = atof (argv[5]);
3059   Standard_Real aNormDZ = atof (argv[6]);
3060
3061   Handle(V3d_Plane) aPlaneV3d = new V3d_Plane();
3062   gp_Pln aPlane (gp_Pnt (aLocX, aLocY, aLocZ), gp_Dir (aNormDX, aNormDY, aNormDZ));
3063   aPlane.Coefficients (coeffA, coeffB, coeffC, coeffD);
3064   aPlaneV3d->SetPlane(coeffA, coeffB, coeffC, coeffD);
3065
3066   aViewer->AddPlane (aPlaneV3d); // add to defined planes list
3067   std::cout << "Added clipping plane #" << aNewPlaneId << "\n";
3068   if (anActivePlanes < aView->View()->PlaneLimit())
3069   {
3070     aView->SetPlaneOn (aPlaneV3d); // add to enabled planes list
3071     aView->Update();
3072   }
3073   else
3074   {
3075     std::cout << "Maximal active planes limit exceeded (" << anActivePlanes << ")\n"
3076               << "You should disable or remove some existing plane to activate the new one\n";
3077   }
3078   return 0;
3079 }
3080
3081 //=============================================================================
3082 //function : VComputeHLR
3083 //purpose  :
3084 //=============================================================================
3085
3086 static int VComputeHLR (Draw_Interpretor& di,
3087                         Standard_Integer argc,
3088                         const char** argv)
3089 {
3090   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3091
3092   if (aContextAIS.IsNull ())
3093   {
3094     di << "Please call vinit before\n";
3095     return 1;
3096   }
3097
3098   if ( argc != 3 &&  argc != 12 )
3099   {
3100     di << "Usage: " << argv[0] << " ShapeName HlrName "
3101        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]" << "\n"
3102        << "                    ShapeName - name of the initial shape\n"
3103        << "                    HlrName - result hlr object from initial shape\n"
3104        << "                    eye, dir are eye position and look direction\n"
3105        << "                    up is the look up direction vector\n"
3106        << "                    Use vtop to see projected hlr shape\n";
3107     return 1;
3108   }
3109
3110   // shape and new object name
3111   TCollection_AsciiString aShapeName (argv[1]);
3112   TCollection_AsciiString aHlrName (argv[2]);
3113
3114   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3115   if (aSh.IsNull()) 
3116   {
3117     BRep_Builder aBrepBuilder;
3118     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3119     if (aSh.IsNull ())
3120     {
3121       di << "No shape with name " << argv[1] << " found\n";
3122       return 1;
3123     }
3124   }
3125
3126   if (GetMapOfAIS ().IsBound2 (aHlrName))
3127   {
3128     di << "Presentable object with name " << argv[2] << " already exists\n";
3129     return 1;
3130   }
3131
3132   // close local context
3133   if (aContextAIS->HasOpenedContext ())
3134     aContextAIS->CloseLocalContext ();
3135
3136   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3137   HLRBRep_PolyHLRToShape aHLRToShape;
3138
3139   gp_Pnt anEye;
3140   gp_Dir aDir;
3141   gp_Ax2 aProjAx;
3142   if (argc == 9)
3143   {
3144     gp_Dir anUp;
3145
3146     anEye.SetCoord (atof (argv[3]), atof (argv[4]), atof (argv[5]));
3147     aDir.SetCoord (atof (argv[6]), atof (argv[7]), atof (argv[8]));
3148     anUp.SetCoord (atof (argv[9]), atof (argv[10]), atof (argv[11]));
3149     aProjAx.SetLocation (anEye);
3150     aProjAx.SetDirection (aDir);
3151     aProjAx.SetYDirection (anUp);
3152   }
3153   else
3154   {
3155     gp_Dir aRight;
3156
3157     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3158     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3159     Standard_Integer aWidth, aHeight;
3160     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3161     Standard_Real aRightX, aRightY, aRightZ;
3162     aView->Window()->Size (aWidth, aHeight);
3163
3164     aView->ConvertWithProj (aWidth, aHeight/2, 
3165                             aRightX, aRightY, aRightZ,
3166                             aDirX, aDirY, aDirZ);
3167
3168     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3169                             aCentX, aCentY, aCentZ,
3170                             aDirX, aDirY, aDirZ);
3171
3172     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3173     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3174     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3175     aProjAx.SetLocation (anEye);
3176     aProjAx.SetDirection (aDir);
3177     aProjAx.SetXDirection (aRight);
3178   }
3179
3180   HLRAlgo_Projector aProjector (aProjAx);
3181   aPolyAlgo->Projector (aProjector);
3182   aPolyAlgo->Load (aSh);
3183   aPolyAlgo->Update ();
3184
3185   aHLRToShape.Update (aPolyAlgo);
3186
3187   // make hlr shape from input shape
3188   TopoDS_Compound aHlrShape;
3189   BRep_Builder aBuilder;
3190   aBuilder.MakeCompound (aHlrShape);
3191
3192   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3193   if (!aCompound.IsNull ())
3194   {
3195     aBuilder.Add (aHlrShape, aCompound);
3196   }
3197   
3198   // extract visible outlines
3199   aCompound = aHLRToShape.OutLineVCompound();
3200   if (!aCompound.IsNull ())
3201   {
3202     aBuilder.Add (aHlrShape, aCompound);
3203   }
3204
3205   // create an AIS shape and display it
3206   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3207   GetMapOfAIS().Bind (anObject, aHlrName);
3208   aContextAIS->Display (anObject);
3209
3210   aContextAIS->UpdateCurrentViewer ();
3211
3212   return 0;
3213 }
3214
3215 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3216 // manipulating and displaying such an array with AIS context
3217 DEFINE_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3218 class MyPArrayObject : public AIS_InteractiveObject
3219 {
3220
3221 public:
3222
3223   MyPArrayObject (const Handle(Graphic3d_ArrayOfPrimitives) theArray)
3224   {
3225     myArray = theArray;
3226   }
3227
3228   DEFINE_STANDARD_RTTI(MyPArrayObject);
3229
3230 private:
3231
3232   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3233                 const Handle(Prs3d_Presentation)& aPresentation,
3234                 const Standard_Integer aMode);
3235
3236   void ComputeSelection (const Handle(SelectMgr_Selection)& aSelection,
3237                          const Standard_Integer aMode) {};
3238
3239 protected:
3240
3241   Handle(Graphic3d_ArrayOfPrimitives) myArray;
3242
3243 };
3244
3245 IMPLEMENT_STANDARD_HANDLE(MyPArrayObject, AIS_InteractiveObject)
3246 IMPLEMENT_STANDARD_RTTIEXT(MyPArrayObject, AIS_InteractiveObject)
3247
3248 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3249                               const Handle(Prs3d_Presentation)& aPresentation,
3250                               const Standard_Integer aMode)
3251 {
3252   aPresentation->Clear();
3253
3254   Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPresentation);
3255   aGroup->BeginPrimitives ();
3256   aGroup->AddPrimitiveArray (myArray);
3257   aGroup->EndPrimitives ();
3258 }
3259
3260 static bool CheckInputCommand (const TCollection_AsciiString theCommand,
3261                                const char **theArgStr, int &theArgIndex,
3262                                int theArgCount, int theMaxArgs)
3263 {
3264   // check if there is more elements than expected
3265   if (theArgIndex >= theMaxArgs)
3266     return false;
3267
3268   TCollection_AsciiString aStrCommand(theArgStr[theArgIndex]);
3269   aStrCommand.LowerCase();
3270   if (aStrCommand.Search(theCommand) != 1 ||
3271       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3272     return false;
3273
3274   // go to the first data element
3275   theArgIndex++;
3276
3277   // check data if it can be converted to numeric
3278   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3279   {
3280     aStrCommand = theArgStr[theArgIndex];
3281     if (!aStrCommand.IsRealValue())
3282       return false;
3283   }
3284
3285   return true;
3286 }
3287
3288 //=============================================================================
3289 //function : VDrawPArray
3290 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3291 //=============================================================================
3292
3293 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3294 {
3295   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3296   if (aContextAIS.IsNull())
3297   {
3298     di << "Call vinit before!\n";
3299     return 1;
3300   }
3301   else if (argc < 3)
3302   {
3303     di << "Use: " << argv[0] << " Name TypeOfArray [EnableVBO={0 | 1}]"
3304        << " [vertex] ... [bounds] ... [edges]\n"
3305        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
3306        << "                trianglefan | trianglestrips | quads |\n"
3307        << "                quadstrips | polygons }\n"
3308        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
3309        << " [texel={ 't' tx ty }] } \n"
3310        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
3311        << "  edges={ 'e' vertex_id [hidden_edge={'h'}] }\n";
3312     return 1;
3313   }
3314
3315   // read the arguments
3316   TCollection_AsciiString aName (argv[1]);
3317   TCollection_AsciiString anArrayType (argv[2]);
3318   
3319   // is argument list has an vbo flag
3320   Standard_Boolean hasFlagVbo = Standard_False;
3321   if (isdigit (argv[3][0]) && atoi (argv[3]) >= 0 && atoi (argv[3]) <= 1)
3322     hasFlagVbo = Standard_True;
3323
3324   // parse number of verticies, bounds, edges
3325   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3326   Standard_Boolean hasVColors, hasBColors, hasNormals, hasInfos, hasTexels;
3327   hasVColors = hasNormals = hasBColors = hasInfos = hasTexels = Standard_False;
3328
3329   Standard_Integer aArgIndex = (hasFlagVbo) ? 4 : 3;
3330   TCollection_AsciiString aCommand;
3331   while (aArgIndex < argc)
3332   {
3333     aCommand = argv[aArgIndex];
3334     aCommand.LowerCase();
3335     if (!aCommand.IsAscii())
3336     {
3337       di << "Unexpected argument: #" << aArgIndex - 1 << " , "
3338          << "should be an array element: 'v', 'b', 'e' \n";
3339       break;
3340     }
3341
3342     // vertex command
3343     if (CheckInputCommand ("v", argv, aArgIndex, 3, argc))
3344     {
3345       // vertex has a normal or normal with color or texel
3346       if (CheckInputCommand ("n", argv, aArgIndex, 3, argc))
3347         hasNormals = Standard_True;
3348
3349       // vertex has a color
3350       if (CheckInputCommand ("c", argv, aArgIndex, 3, argc))
3351         hasVColors = Standard_True;
3352
3353       // vertex has a texel
3354       if (CheckInputCommand ("t", argv, aArgIndex, 2, argc))
3355         hasTexels = Standard_True;
3356
3357       aVertexNum++;
3358     }
3359     // bound command
3360     else if (CheckInputCommand ("b", argv, aArgIndex, 1, argc))
3361     {
3362       // bound has color
3363       if (CheckInputCommand ("c", argv, aArgIndex, 3, argc))
3364         hasBColors = Standard_True;
3365
3366       aBoundNum++;
3367     }
3368     // edge command
3369     else if (CheckInputCommand ("e", argv, aArgIndex, 1, argc))
3370     {
3371       // edge has a hide flag
3372       if (CheckInputCommand ("h", argv, aArgIndex, 0, argc))
3373         hasInfos = Standard_True;
3374
3375       aEdgeNum++;
3376     }
3377     // unknown command
3378     else
3379       aArgIndex++;
3380   }
3381
3382   if (aVertexNum == 0)
3383   {
3384     di << "You should pass any verticies in the list of array elements\n";
3385     return 1;
3386   }
3387
3388   // create an array of primitives by types
3389   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3390   if (anArrayType == "points")
3391     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3392   else if (anArrayType == "segments")
3393     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3394   else if (anArrayType == "polylines")
3395     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3396                                               hasVColors, hasBColors, hasInfos);
3397   else if (anArrayType == "triangles")
3398     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3399                                               hasVColors, hasTexels, hasInfos);
3400   else if (anArrayType == "trianglefans")
3401     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3402                                                  hasNormals, hasVColors,
3403                                                  hasBColors, hasTexels);
3404   else if (anArrayType == "trianglestrips")
3405     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3406                                                    hasNormals, hasVColors,
3407                                                    hasBColors, hasTexels);
3408   else if (anArrayType == "quads")
3409     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3410                                                 hasNormals, hasVColors,
3411                                                 hasTexels, hasInfos);
3412   else if (anArrayType == "quadstrips")
3413     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3414                                                      hasNormals, hasVColors,
3415                                                      hasBColors, hasTexels);
3416   else if (anArrayType == "polygons")
3417     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3418                                              hasNormals, hasVColors, hasBColors,
3419                                              hasTexels, hasInfos);
3420   else
3421   {
3422     di << "Unexpected type of primitiives array\n";
3423     return 1;
3424   }
3425
3426   // parse an array of primitives
3427   aArgIndex = (hasFlagVbo) ? 4 : 3;
3428   while (aArgIndex < argc)
3429   {
3430     aCommand = argv[aArgIndex];
3431     aCommand.LowerCase();
3432     if (!aCommand.IsAscii())
3433       break;
3434
3435     // vertex command
3436     if (CheckInputCommand ("v", argv, aArgIndex, 3, argc))
3437     {
3438       anArray->AddVertex (atof (argv[aArgIndex - 3]),
3439                           atof (argv[aArgIndex - 2]),
3440                           atof (argv[aArgIndex - 1]));
3441
3442       // vertex has a normal or normal with color or texel
3443       if (CheckInputCommand ("n", argv, aArgIndex, 3, argc))
3444         anArray->SetVertexNormal (anArray->VertexNumber (),
3445                                   atof (argv[aArgIndex - 3]),
3446                                   atof (argv[aArgIndex - 2]),
3447                                   atof (argv[aArgIndex - 1]));
3448       
3449       if (CheckInputCommand ("c", argv, aArgIndex, 3, argc))
3450         anArray->SetVertexColor (anArray->VertexNumber (),
3451                                  atof (argv[aArgIndex - 3]),
3452                                  atof (argv[aArgIndex - 2]),
3453                                  atof (argv[aArgIndex - 1]));
3454       
3455       if (CheckInputCommand ("t", argv, aArgIndex, 2, argc))
3456         anArray->SetVertexTexel (anArray->VertexNumber (),
3457                                  atof (argv[aArgIndex - 2]),
3458                                  atof (argv[aArgIndex - 1]));
3459     }
3460     // bounds command
3461     else if (CheckInputCommand ("b", argv, aArgIndex, 1, argc))
3462     {
3463       Standard_Integer aVertCount = atoi (argv[aArgIndex - 1]);
3464
3465       if (CheckInputCommand ("c", argv, aArgIndex, 3, argc))
3466         anArray->AddBound (aVertCount,
3467                            atof (argv[aArgIndex - 3]),
3468                            atof (argv[aArgIndex - 2]),
3469                            atof (argv[aArgIndex - 1]));
3470
3471       else
3472         anArray->AddBound (aVertCount);
3473     }
3474     // edge command
3475     else if (CheckInputCommand ("e", argv, aArgIndex, 1, argc))
3476     {
3477       Standard_Integer aVertIndex = atoi (argv[aArgIndex - 1]);
3478
3479       // edge has/hasn't hide flag
3480       if (CheckInputCommand ("h", argv, aArgIndex, 0, argc))
3481         anArray->AddEdge (aVertIndex, Standard_False);
3482       else
3483         anArray->AddEdge (aVertIndex, Standard_True);
3484     }
3485     // unknown command
3486     else
3487       aArgIndex++;
3488   }
3489
3490   if (hasFlagVbo)
3491   {
3492     // enable / disable vbo
3493     Handle(Graphic3d_GraphicDriver) aDriver =
3494       Handle(Graphic3d_GraphicDriver)::DownCast (
3495                       aContextAIS->CurrentViewer()->Device()->GraphicDriver());
3496
3497     if (!aDriver.IsNull())
3498       aDriver->EnableVBO ((Standard_Boolean) atoi (argv[3]));
3499   }
3500
3501   // create primitives array object
3502   Handle (MyPArrayObject) aPObject = new MyPArrayObject (anArray);
3503
3504   // register the object in map
3505   VDisplayAISObject (aName, aPObject);
3506
3507   return 0;
3508 }
3509
3510 //=======================================================================
3511 //function : VSetLocation
3512 //purpose  : Change location of AIS interactive object
3513 //=======================================================================
3514
3515 static Standard_Integer VSetLocation (Draw_Interpretor& di,
3516                                       Standard_Integer argc,
3517                                       const char ** argv)
3518 {
3519   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3520   if (aContext.IsNull())
3521   {
3522     di << argv[0] << "ERROR : use 'vinit' command before " << "\n";
3523     return 1;
3524   }
3525
3526   if (argc != 5)
3527   {
3528     di << "ERROR : Usage : " << argv[0] << " name x y z; new location" << "\n";
3529     return 1;
3530   }
3531
3532   TCollection_AsciiString aName (argv[1]);
3533   Standard_Real aX = atof (argv[2]);
3534   Standard_Real aY = atof (argv[3]);
3535   Standard_Real aZ = atof (argv[4]);
3536
3537   // find object
3538   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3539   Handle(AIS_InteractiveObject) anIObj;
3540   if (!aMap.IsBound2 (aName))
3541   {
3542     di << "Use 'vdisplay' before" << "\n";
3543     return 1;
3544   }
3545   else
3546   {
3547     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
3548
3549     // not an AIS_InteractiveObject
3550     if (anIObj.IsNull())
3551     {
3552       di << argv[1] << " : Not an AIS interactive object" << "\n";
3553       return 1;
3554     }
3555
3556     gp_Trsf aTrsf;
3557     aTrsf.SetTranslation (gp_Vec (aX, aY, aZ));
3558     TopLoc_Location aLocation (aTrsf);
3559     aContext->SetLocation (anIObj, aLocation);
3560     aContext->UpdateCurrentViewer();
3561   }
3562
3563   return 0;
3564 }
3565
3566 //===============================================================================================
3567 //function : VConnect
3568 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3569 //Draw arg : vconnect name object Xo Yo Zo Xu Xv Xw Zu Zv Zw
3570 //===============================================================================================
3571
3572 static Standard_Integer VConnect(Draw_Interpretor& di, 
3573                                  Standard_Integer argc, 
3574                                  const char ** argv) 
3575 {
3576   // Check argumnets 
3577   if(argc != 12)
3578   {
3579     std::cout << "vconnect error: expect 11 argumnets\n"; 
3580     return 1; // TCL_ERROR
3581   }
3582   // Get values 
3583   TCollection_AsciiString aName(argv[1]); 
3584   TCollection_AsciiString anOriginObjectName(argv[2]); 
3585   if(aName.IsEqual(anOriginObjectName))
3586   {
3587     std::cout << "vconnect error: equal names for connected objects\n"; 
3588     return 1; // TCL_ERROR
3589   }
3590   // Check if the origin shape is not null
3591   Handle(AIS_InteractiveObject) anOriginObject;
3592   if(GetMapOfAIS().IsBound2(anOriginObjectName))
3593   {
3594     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(anOriginObjectName);
3595     anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3596     if(anOriginObject.IsNull())
3597     {
3598       std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n!";
3599       return 1; // TCL_ERROR
3600     }
3601   }
3602   
3603   // Get location data
3604   Standard_Real aXo = atof(argv[3]);
3605   Standard_Real aYo = atof(argv[4]);
3606   Standard_Real aZo = atof(argv[5]);
3607   Standard_Real aXu = atof(argv[6]);
3608   Standard_Real aXv = atof(argv[7]);
3609   Standard_Real aXw = atof(argv[8]);
3610   Standard_Real aZu = atof(argv[9]);
3611   Standard_Real aZv = atof(argv[10]);
3612   Standard_Real aZw = atof(argv[11]);
3613
3614   // Create transformation
3615   gp_Pnt aPoint(aXo, aYo, aZo);
3616   gp_Dir anXDir(aXu, aXv, aXw), aZDir(aZu, aZv, aZw);
3617   if(!anXDir.IsNormal(aZDir, Precision::Angular()))
3618   {
3619     std::cout << "vconnect error : XDir expects to be normal to ZDir\n"; 
3620     return 1; // TCL_ERROR
3621   } 
3622   gp_Ax3 anAx3(aPoint, aZDir, anXDir); 
3623   gp_Trsf aTrsf; 
3624   aTrsf.SetTransformation(anAx3); 
3625   TopLoc_Location aLocation(aTrsf);
3626
3627   // Create connected object
3628   Handle(AIS_ConnectedInteractive) aConnectedObject = new AIS_ConnectedInteractive();
3629   aConnectedObject->Connect(anOriginObject, aLocation);
3630
3631   // Check if there is another object with given name
3632   // and remove it from context
3633   if(GetMapOfAIS().IsBound2(aName))
3634   {
3635     Handle(AIS_InteractiveObject) anObj = 
3636       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3637     TheAISContext()->Remove(anObj, Standard_False);
3638     GetMapOfAIS().UnBind2(aName);
3639   }
3640
3641   // Bind connected object to its name 
3642   GetMapOfAIS().Bind(aConnectedObject, aName); 
3643
3644   // Display connected object
3645   TheAISContext()->Display(aConnectedObject);
3646
3647   return 0;
3648 }
3649
3650 //===============================================================================================
3651 //function : VConnectShape
3652 //purpose  : Creates and displays AIS_ConnectedShape from input shape and location 
3653 //Draw arg : vconnectsh name shape Xo Yo Zo Xu Xv Xw Zu Zv Zw
3654 //===============================================================================================
3655
3656 static Standard_Integer VConnectShape(Draw_Interpretor& di, 
3657                                       Standard_Integer argc, 
3658                                       const char ** argv) 
3659 {
3660   // Check argumnets 
3661   if(argc != 12)
3662   {
3663     std::cout << "vconnectsh error: expect 11 argumnets\n"; 
3664     return 1; // TCL_ERROR
3665   }
3666   // Get values 
3667   TCollection_AsciiString aName(argv[1]); 
3668   TCollection_AsciiString anOriginShapeName(argv[2]); 
3669   if(aName.IsEqual(anOriginShapeName))
3670   {
3671     std::cout << "vconnectsh error: equal names for connected shapes\n"; 
3672     return 1; // TCL_ERROR
3673   }
3674   // Check if the origin shape is not null
3675   Handle(AIS_InteractiveObject) anOriginShape;
3676   if(GetMapOfAIS().IsBound2(anOriginShapeName))
3677   {
3678     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(anOriginShapeName);
3679     anOriginShape = Handle(AIS_InteractiveObject)::DownCast(anObj);
3680     if(anOriginShape.IsNull())
3681     {
3682       std::cout << "Shape " << anOriginShapeName << " is used for non AIS viewer\n!";
3683       return 1; // TCL_ERROR
3684     }
3685   }
3686
3687   // Get location data  
3688   Standard_Real aXo = atof(argv[3]);
3689   Standard_Real aYo = atof(argv[4]);
3690   Standard_Real aZo = atof(argv[5]);
3691   Standard_Real aXu = atof(argv[6]);
3692   Standard_Real aXv = atof(argv[7]);
3693   Standard_Real aXw = atof(argv[8]);
3694   Standard_Real aZu = atof(argv[9]);
3695   Standard_Real aZv = atof(argv[10]);
3696   Standard_Real aZw = atof(argv[11]);
3697
3698   // Create transformation
3699   gp_Pnt aPoint(aXo, aYo, aZo);
3700   gp_Dir anXDir(aXu, aXv, aXw), aZDir(aZu, aZv, aZw);
3701   if(!anXDir.IsNormal(aZDir, Precision::Angular()))
3702   {
3703     std::cout << "vconnectsh error : XDir expects to be normal to ZDir\n"; 
3704     return 1; // TCL_ERROR
3705   } 
3706   gp_Ax3 anAx3(aPoint, aZDir, anXDir); 
3707   gp_Trsf aTrsf; 
3708   aTrsf.SetTransformation(anAx3); 
3709   TopLoc_Location aLocation(aTrsf);
3710
3711   // Create connected shape
3712   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(anOriginShape);
3713   Handle(AIS_ConnectedShape) aConnectedShape = new AIS_ConnectedShape(aShape);
3714   aConnectedShape->Connect(anOriginShape, aLocation);
3715
3716   // Check if there is another object with given name
3717   // and remove it from context
3718   if(GetMapOfAIS().IsBound2(aName))
3719   {
3720     Handle(AIS_InteractiveObject) anObj = 
3721       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
3722     TheAISContext()->Remove(anObj, Standard_False);
3723     GetMapOfAIS().UnBind2(aName);
3724   }
3725
3726   // Bind connected shape to its name 
3727   GetMapOfAIS().Bind(aConnectedShape, aName); 
3728
3729   // Display connected shape
3730   TheAISContext()->Display(aConnectedShape);
3731
3732   return 0;
3733 }
3734
3735 //===============================================================================================
3736 //function : VSetSelectionMode
3737 //purpose  : Sets input selection mode for input object or for all displayed objects 
3738 //Draw arg : vselmode [object] mode On/Off (1/0)
3739 //===============================================================================================
3740
3741 // function : InList 
3742 // purpose  : checks if theMode is already turned on for theObj
3743 Standard_Boolean InList(Handle(AIS_InteractiveContext) theAISContext, 
3744                           Handle(AIS_InteractiveObject) theObj, 
3745                           Standard_Integer theMode)
3746 {
3747   TColStd_ListOfInteger anArray; 
3748   theAISContext->ActivatedModes(theObj, anArray);
3749   TColStd_ListIteratorOfListOfInteger anIt(anArray);
3750   for(; anIt.More(); anIt.Next())
3751   {
3752     if(anIt.Value() == theMode) 
3753       return Standard_True;
3754   }
3755   return Standard_False;
3756 }
3757
3758 static Standard_Integer VSetSelectionMode(Draw_Interpretor& di, 
3759                                           Standard_Integer argc, 
3760                                           const char ** argv)
3761 {
3762   // Check errors
3763   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
3764   if(anAISContext.IsNull())
3765   {
3766     std::cout << "Call vinit before!\n";
3767     return 1; // TCL_ERROR
3768   }
3769
3770   // Check the arguments 
3771   if(argc != 3 && argc != 4)
3772   {
3773     std::cout << "vselmode error : expects at least 2 arguments\n"; 
3774     return 1; // TCL_ERROR
3775   }
3776
3777   Handle(AIS_InteractiveObject) anObj;
3778
3779   // Set new selection mode for all objects in context
3780   if(argc == 3)
3781   {
3782     // Get arguments 
3783     Standard_Integer aMode = atoi(argv[1]);
3784     Standard_Boolean isTurnOn = atoi(argv[2]); 
3785
3786     // Get all displayed objects
3787     AIS_ListOfInteractive anObjList;
3788     anAISContext->DisplayedObjects(anObjList);
3789     AIS_ListIteratorOfListOfInteractive anObjIter;
3790
3791     if(aMode == 0)
3792     {
3793       if(anAISContext->HasOpenedContext())
3794         anAISContext->CloseLocalContext();
3795     }
3796
3797     // Turn on aMode
3798     if(aMode != 0 && isTurnOn)
3799     {
3800       if(!anAISContext->HasOpenedContext())
3801       {
3802         anAISContext->OpenLocalContext(); 
3803         for(anObjIter.Initialize(anObjList); anObjIter.More(); anObjIter.Next())
3804         {
3805           anAISContext->Activate(anObjIter.Value(), aMode); 
3806         }
3807       }
3808       else
3809       {
3810         for(anObjIter.Initialize(anObjList); anObjIter.More(); anObjIter.Next())
3811         {
3812           anObj = anObjIter.Value();
3813           if(!InList(anAISContext, anObj, aMode))
3814             anAISContext->Activate(anObj, aMode);
3815         }
3816       }
3817     }
3818
3819     // Turn off aMode
3820     if(aMode != 0 && !isTurnOn)
3821     {
3822       if(anAISContext->HasOpenedContext())
3823       {
3824         for(anObjIter.Initialize(anObjList); anObjIter.More(); anObjIter.Next())
3825         {
3826           anObj = anObjIter.Value();
3827           if(InList(anAISContext, anObj, aMode))
3828             anAISContext->Deactivate(anObj, aMode);
3829         }
3830       }
3831     }
3832   }
3833
3834   // Set new selection mode for named object 
3835   else
3836   {
3837     // Get argumnets 
3838     Standard_Integer aMode = atoi(argv[2]);
3839     Standard_Boolean isTurnOn = atoi(argv[3]);
3840     TCollection_AsciiString aName(argv[1]); 
3841
3842     // Check if there is an object with given name in context
3843     if(GetMapOfAIS().IsBound2(aName))
3844     {
3845       anObj = Handle(AIS_InteractiveObject)::
3846         DownCast(GetMapOfAIS().Find2(aName));
3847       if(anObj.IsNull())
3848       {
3849         std::cout << "vselmode error : object name is used for non AIS viewer\n"; 
3850         return 1; // TCL_ERROR
3851       }
3852     }
3853
3854     if(aMode == 0)
3855     {
3856       if(anAISContext->HasOpenedContext())
3857         anAISContext->CloseLocalContext();
3858     }
3859     // Turn on aMode
3860     if(aMode != 0 && isTurnOn) 
3861     {
3862       if(!anAISContext->HasOpenedContext())
3863       {
3864         anAISContext->OpenLocalContext(); 
3865         anAISContext->Activate(anObj, aMode);
3866       }
3867       else
3868       {
3869         if(!InList(anAISContext, anObj, aMode))
3870           anAISContext->Activate(anObj, aMode);
3871       }
3872     }
3873
3874     // Turn off aMode
3875     if(aMode != 0 && !isTurnOn)
3876     {
3877       if(anAISContext->HasOpenedContext())
3878       {
3879         if(InList(anAISContext, anObj, aMode))
3880           anAISContext->Deactivate(anObj, aMode);
3881       }
3882     }
3883   }
3884   return 0;
3885 }
3886
3887 //==========================================================================
3888 //class   : Triangle 
3889 //purpose : creates Triangle based on AIS_InteractiveObject. 
3890 //          This class was implemented for testing Select3D_SensitiveTriangle
3891 //===========================================================================
3892 DEFINE_STANDARD_HANDLE(Triangle, AIS_InteractiveObject)
3893 class Triangle: public AIS_InteractiveObject 
3894 {
3895 public: 
3896   // CASCADE RTTI
3897   DEFINE_STANDARD_RTTI(FilledCircle); 
3898   Triangle (const gp_Pnt& theP1, 
3899             const gp_Pnt& theP2, 
3900             const gp_Pnt& theP3);
3901 protected:
3902   void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
3903                   const Handle(Prs3d_Presentation)& thePresentation,
3904                   const Standard_Integer theMode);
3905
3906   void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
3907                            const Standard_Integer theMode);
3908 private: 
3909   gp_Pnt myPoint1;
3910   gp_Pnt myPoint2;
3911   gp_Pnt myPoint3;
3912 };
3913 IMPLEMENT_STANDARD_HANDLE(Triangle, AIS_InteractiveObject)
3914 IMPLEMENT_STANDARD_RTTIEXT(Triangle, AIS_InteractiveObject)
3915
3916 Triangle::Triangle (const gp_Pnt& theP1,
3917                     const gp_Pnt& theP2,
3918                     const gp_Pnt& theP3)
3919 {
3920   myPoint1 = theP1;
3921   myPoint2 = theP2;
3922   myPoint3 = theP3;
3923 }
3924
3925 void Triangle::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
3926                        const Handle(Prs3d_Presentation)& thePresentation,
3927                        const Standard_Integer theMode)
3928 {
3929   thePresentation->Clear();
3930
3931   BRepBuilderAPI_MakeEdge anEdgeMaker1(myPoint1, myPoint2),
3932                           anEdgeMaker2(myPoint2, myPoint3),
3933                           anEdgeMaker3(myPoint3, myPoint1);
3934
3935   TopoDS_Edge anEdge1 = anEdgeMaker1.Edge(),
3936               anEdge2 = anEdgeMaker2.Edge(),
3937               anEdge3 = anEdgeMaker3.Edge();
3938   if(anEdge1.IsNull() || anEdge2.IsNull() || anEdge3.IsNull())
3939     return;
3940
3941   BRepBuilderAPI_MakeWire aWireMaker(anEdge1, anEdge2, anEdge3);
3942   TopoDS_Wire aWire = aWireMaker.Wire();
3943   if(aWire.IsNull()) return;
3944
3945   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
3946   TopoDS_Face aFace = aFaceMaker.Face();
3947   if(aFace.IsNull()) return;
3948
3949   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
3950 }
3951
3952 void Triangle::ComputeSelection(const Handle(SelectMgr_Selection)& theSelection, 
3953                                 const Standard_Integer theMode)
3954 {
3955   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
3956   Handle(Select3D_SensitiveTriangle) aSensTriangle = 
3957     new Select3D_SensitiveTriangle(anEntityOwner, myPoint1, myPoint2, myPoint3);
3958   theSelection->Add(aSensTriangle);
3959 }
3960
3961 //===========================================================================
3962 //function : VTriangle 
3963 //Draw arg : vtriangle Name PointName PointName PointName
3964 //purpose  : creates and displays Triangle
3965 //===========================================================================
3966
3967 //function: IsPoint
3968 //purpose : checks if the object with theName is AIS_Point, 
3969 //          if yes initialize thePoint from MapOfAIS
3970 Standard_Boolean IsPoint (const TCollection_AsciiString& theName,
3971                           Handle(AIS_Point)& thePoint)
3972 {
3973   Handle(AIS_InteractiveObject) anObject = 
3974     Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(theName));
3975   if(anObject.IsNull() || 
3976      anObject->Type() != AIS_KOI_Datum || 
3977      anObject->Signature() != 1)
3978   {
3979     return Standard_False;
3980   }
3981   thePoint = Handle(AIS_Point)::DownCast(anObject);
3982   if(thePoint.IsNull())
3983     return Standard_False;
3984   return Standard_True;
3985 }
3986
3987 //function: IsMatch
3988 //purpose: checks if thePoint1 is equal to thePoint2
3989 Standard_Boolean IsMatch (const Handle(Geom_CartesianPoint)& thePoint1,
3990                           const Handle(Geom_CartesianPoint)& thePoint2)
3991 {
3992   if(abs(thePoint1->X()-thePoint2->X()) <= Precision::Confusion() &&
3993      abs(thePoint1->Y()-thePoint2->Y()) <= Precision::Confusion() &&
3994      abs(thePoint1->Z()-thePoint2->Z()) <= Precision::Confusion())
3995   {
3996     return Standard_True;
3997   }
3998   return Standard_False;
3999 }
4000
4001 static Standard_Integer VTriangle (Draw_Interpretor& di,
4002                                    Standard_Integer argc,
4003                                    const char ** argv)
4004 {
4005   // Check arguments
4006   if (argc != 5)
4007   {
4008     std::cout<<"vtriangle error: expects 4 argumnets\n";
4009     return 1; // TCL_ERROR
4010   }
4011
4012   TheAISContext()->CloseAllContexts();
4013
4014   // Get and check values
4015   TCollection_AsciiString aName(argv[1]);
4016
4017   Handle(AIS_Point) aPoint1, aPoint2, aPoint3;
4018   if (!IsPoint(argv[2], aPoint1))
4019   {
4020     std::cout<<"vtriangle error: the 2nd argument must be a point\n";
4021     return 1; // TCL_ERROR
4022   }
4023   if (!IsPoint(argv[3], aPoint2))
4024   {
4025     std::cout<<"vtriangle error: the 3d argument must be a point\n";
4026     return 1; // TCL_ERROR
4027   }
4028   if (!IsPoint(argv[4], aPoint3))
4029   {
4030     std::cout<<"vtriangle error: the 4th argument must be a point\n";
4031     return 1; // TCL_ERROR
4032   }
4033
4034   // Check that points are different
4035   Handle(Geom_CartesianPoint) aCartPoint1 = 
4036     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4037   Handle(Geom_CartesianPoint) aCartPoint2 = 
4038     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4039   // Test aPoint1 = aPoint2
4040   if (IsMatch(aCartPoint1, aCartPoint2))
4041   {
4042     std::cout<<"vtriangle error: the 1st and the 2nd points are equal\n";
4043     return 1; // TCL_ERROR
4044   }
4045   // Test aPoint2 = aPoint3
4046   Handle(Geom_CartesianPoint) aCartPoint3 = 
4047     Handle(Geom_CartesianPoint)::DownCast(aPoint3->Component());
4048   if (IsMatch(aCartPoint2, aCartPoint3))
4049   {
4050     std::cout<<"vtriangle error: the 2nd and the 3d points are equal\n";
4051     return 1; // TCL_ERROR
4052   }
4053   // Test aPoint3 = aPoint1
4054   if (IsMatch(aCartPoint1, aCartPoint3))
4055   {
4056     std::cout<<"vtriangle error: the 1st and the 3d points are equal\n";
4057     return 1; // TCL_ERROR
4058   }
4059
4060   // Create triangle
4061   Handle(Triangle) aTriangle = new Triangle(aCartPoint1->Pnt(),
4062                                             aCartPoint2->Pnt(),
4063                                             aCartPoint3->Pnt());
4064
4065   // Check if there is an object with given name
4066   // and remove it from context
4067   if (GetMapOfAIS().IsBound2(aName))
4068   {
4069     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4070     Handle(AIS_InteractiveObject) anInterObj = 
4071          Handle(AIS_InteractiveObject)::DownCast(anObj);
4072     TheAISContext()->Remove(anInterObj, Standard_False);
4073     GetMapOfAIS().UnBind2(aName);
4074   }
4075
4076   // Bind triangle to its name
4077   GetMapOfAIS().Bind(aTriangle, aName);
4078
4079   // Display triangle
4080   TheAISContext()->Display(aTriangle);
4081   return 0;
4082 }
4083
4084 //class  : SegmentObject
4085 //purpose: creates segment based on AIS_InteractiveObject.
4086 //         This class was implemented for testing Select3D_SensitiveCurve
4087 DEFINE_STANDARD_HANDLE(SegmentObject, AIS_InteractiveObject)
4088 class SegmentObject: public AIS_InteractiveObject
4089 {
4090 public:
4091   // CASCADE RTTI
4092   DEFINE_STANDARD_RTTI(SegmentObject); 
4093   SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2);
4094 protected:
4095   void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
4096                 const Handle(Prs3d_Presentation)& thePresentation,
4097                 const Standard_Integer theMode);
4098
4099   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
4100                          const Standard_Integer theMode);
4101 private:
4102   gp_Pnt myPoint1;
4103   gp_Pnt myPoint2;
4104 };
4105 IMPLEMENT_STANDARD_HANDLE(SegmentObject, AIS_InteractiveObject)
4106 IMPLEMENT_STANDARD_RTTIEXT(SegmentObject, AIS_InteractiveObject)
4107
4108 SegmentObject::SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2)
4109 {
4110   myPoint1 = thePnt1;
4111   myPoint2 = thePnt2;
4112 }
4113
4114 void SegmentObject::Compute (const Handle_PrsMgr_PresentationManager3d &thePresentationManager,
4115                              const Handle_Prs3d_Presentation &thePresentation,
4116                              const Standard_Integer theMode)
4117 {
4118   thePresentation->Clear();
4119   BRepBuilderAPI_MakeEdge anEdgeMaker(myPoint1, myPoint2);
4120   TopoDS_Edge anEdge = anEdgeMaker.Edge();
4121   if (anEdge.IsNull())
4122     return;
4123   BRepAdaptor_Curve aCurveAdaptor(anEdge);
4124   StdPrs_Curve::Add(thePresentation, aCurveAdaptor, myDrawer);
4125 }
4126
4127 void SegmentObject::ComputeSelection (const Handle_SelectMgr_Selection &theSelection,
4128                                       const Standard_Integer theMode)
4129 {
4130   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
4131   Handle(TColgp_HArray1OfPnt) anArray = new TColgp_HArray1OfPnt(1, 2);
4132   anArray->SetValue(1, myPoint1);
4133   anArray->SetValue(2, myPoint2);
4134   Handle(Select3D_SensitiveCurve) aSensCurve = 
4135     new Select3D_SensitiveCurve(anOwner, anArray);
4136   theSelection->Add(aSensCurve);
4137 }
4138
4139 //=======================================================================
4140 //function  : VSegment
4141 //Draw args : vsegment Name PointName PointName
4142 //purpose   : creates and displays Segment
4143 //=======================================================================
4144 static Standard_Integer VSegment (Draw_Interpretor& di,
4145                                   Standard_Integer argc,
4146                                   const char ** argv)
4147 {
4148   // Check arguments
4149   if(argc!=4)
4150   {
4151     std::cout<<"vsegment error: expects 3 arguments\n";
4152     return 1; // TCL_ERROR
4153   }
4154
4155   TheAISContext()->CloseAllContexts();
4156
4157   // Get and check arguments
4158   TCollection_AsciiString aName(argv[1]);
4159   Handle(AIS_Point) aPoint1, aPoint2;
4160   if (!IsPoint(argv[2], aPoint1))
4161   {
4162     std::cout<<"vsegment error: the 2nd argument should be a point\n";
4163     return 1; // TCL_ERROR
4164   }
4165   if (!IsPoint(argv[3], aPoint2))
4166   {
4167     std::cout<<"vsegment error: the 3d argument should be a point\n";
4168     return 1; // TCL_ERROR
4169   }
4170   //Check that points are different
4171   Handle(Geom_CartesianPoint) aCartPoint1 = 
4172     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4173   Handle(Geom_CartesianPoint) aCartPoint2 = 
4174     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4175   if(IsMatch(aCartPoint1, aCartPoint2))
4176   {
4177     std::cout<<"vsegment error: equal points\n";
4178     return 1; // TCL_ERROR
4179   }
4180   
4181   // Create segment
4182   Handle(SegmentObject) aSegment = new SegmentObject(aCartPoint1->Pnt(), aCartPoint2->Pnt());
4183   // Check if there is an object with given name
4184   // and remove it from context
4185   if (GetMapOfAIS().IsBound2(aName))
4186   {
4187     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4188     Handle(AIS_InteractiveObject) anInterObj = 
4189          Handle(AIS_InteractiveObject)::DownCast(anObj);
4190     TheAISContext()->Remove(anInterObj, Standard_False);
4191     GetMapOfAIS().UnBind2(aName);
4192   }
4193
4194   // Bind segment to its name
4195   GetMapOfAIS().Bind(aSegment, aName);
4196
4197   // Display segment
4198   TheAISContext()->Display(aSegment);
4199   return 0;
4200 }
4201
4202 //=======================================================================
4203 //function : VObjZLayer
4204 //purpose  : Set or get z layer id for presentable object
4205 //=======================================================================
4206
4207 static Standard_Integer VObjZLayer (Draw_Interpretor& di,
4208                                     Standard_Integer argc,
4209                                     const char ** argv)
4210 {
4211   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4212   if (aContext.IsNull())
4213   {
4214     di << argv[0] << "Call 'vinit' before!\n";
4215     return 1;
4216   }
4217
4218   // get operation
4219   TCollection_AsciiString aOperation;
4220   if (argc >= 2)
4221     aOperation = TCollection_AsciiString (argv [1]);
4222
4223   // check for correct arguments
4224   if (!(argc == 4 && aOperation.IsEqual ("set")) &&
4225       !(argc == 3 && aOperation.IsEqual ("get")))
4226   {
4227     di << "Usage : " << argv[0] << " set/get object [layerid]\n";
4228     di << " set - set layer id for interactive object, layerid - z layer id\n";
4229     di << " get - get layer id of interactive object\n";
4230     di << " argument layerid should be passed for set operation only\n";
4231     return 1;
4232   }
4233
4234   // find object
4235   TCollection_AsciiString aName (argv[2]);
4236   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4237   if (!aMap.IsBound2 (aName))
4238   {
4239     di << "Use 'vdisplay' before" << "\n";
4240     return 1;
4241   }
4242
4243   // find interactive object
4244   Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
4245   Handle(AIS_InteractiveObject) anInterObj =
4246     Handle(AIS_InteractiveObject)::DownCast (anObj);
4247   if (anInterObj.IsNull())
4248   {
4249     di << "Not an AIS interactive object!\n";
4250     return 1;
4251   }
4252
4253   // process operation
4254   if (aOperation.IsEqual ("set"))
4255   {
4256     Standard_Integer aLayerId = atoi (argv [3]);
4257     aContext->SetZLayer (anInterObj, aLayerId);
4258   }
4259   else if (aOperation.IsEqual ("get"))
4260   {
4261     di << "Z layer id: " << aContext->GetZLayer (anInterObj);
4262   }
4263   
4264   return 0;
4265 }
4266
4267 //=======================================================================
4268 //function : ObjectsCommands
4269 //purpose  :
4270 //=======================================================================
4271
4272 void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
4273 {
4274   const char *group ="AISObjects";
4275   theCommands.Add("vtrihedron",
4276     "vtrihedron         : vtrihedron name [Xo] [Yo] [Zo] [Zu] [Zv] [Zw] [Xu] [Xv] [Xw] ",
4277     __FILE__,VTrihedron,group);
4278
4279   theCommands.Add("vtri2d",
4280     "vtri2d Name Selection in the viewer only ",
4281     __FILE__,VTrihedron2D ,group);
4282
4283   theCommands.Add("vplanetri",
4284     "vplanetri Name Selection in the viewer only ",
4285     __FILE__,VPlaneTrihedron ,group);
4286
4287   theCommands.Add("vsize",
4288     "vsize       : vsize [name(Default=Current)] [size(Default=100)] ",
4289     __FILE__,VSize,group);
4290
4291   theCommands.Add("vaxis",
4292     "vaxis nom [Xa] [Ya] [Za] [Xb] [Yb] [Zb]",
4293     __FILE__,VAxisBuilder,group);
4294
4295   theCommands.Add("vaxispara",
4296     "vaxispara  nom ",
4297     __FILE__,VAxisBuilder,group);
4298
4299   theCommands.Add("vaxisortho",
4300     "vaxisotho  nom ",
4301     __FILE__,VAxisBuilder,group);
4302
4303   theCommands.Add("vpoint",
4304     "vpoint  PointName [Xa] [Ya] [Za] ",
4305     __FILE__,VPointBuilder,group);
4306
4307   theCommands.Add("vplane",
4308     "vplane  PlaneName [AxisName/PlaneName/PointName] [PointName/PointName/PointName] [Nothing/Nothing/PointName] ",
4309     __FILE__,VPlaneBuilder,group);
4310
4311   theCommands.Add("vplanepara",
4312     "vplanepara  PlaneName  ",
4313     __FILE__,VPlaneBuilder,group);
4314
4315   theCommands.Add("vplaneortho",
4316     "vplaneortho  PlaneName  ",
4317     __FILE__,VPlaneBuilder,group);
4318
4319   theCommands.Add("vline",
4320     "vline: vline LineName [Xa/PointName] [Ya/PointName] [Za] [Xb] [Yb] [Zb]  ",
4321     __FILE__,VLineBuilder,group);
4322
4323   theCommands.Add("vcircle",
4324     "vcircle CircleName [PointName PointName PointName IsFilled]\n\t\t\t\t\t[PlaneName PointName Radius IsFilled]",
4325     __FILE__,VCircleBuilder,group);
4326
4327   theCommands.Add("vdrawtext",
4328     "vdrawtext  : vdrawtext name X Y Z R G B hor_align ver_align angle zoomable height Aspect [Font [isMultiByte]]",
4329     __FILE__,VDrawText,group);
4330
4331   theCommands.Add("vdrawsphere",
4332     "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToEnableVBO=1] [NumberOfViewerUpdate=1] [ToShowEdges=0]\n",
4333     __FILE__,VDrawSphere,group);
4334
4335   theCommands.Add("vclipplane",
4336     "vclipplane : vclipplane [x y z dx dy dz] [planeId {on/off/del/display/hide}]",
4337     __FILE__,VClipPlane,group);
4338
4339   theCommands.Add ("vsetlocation",
4340         "vsetlocation : name x y z; set new location for an interactive object",
4341         __FILE__, VSetLocation, group);
4342
4343   theCommands.Add (
4344     "vcomputehlr",
4345     "vcomputehlr: shape hlrname [ eyex eyey eyez lookx looky lookz ]",
4346     __FILE__, VComputeHLR, group);
4347
4348   theCommands.Add("vdrawparray",
4349     "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' }] ]",
4350     __FILE__,VDrawPArray,group);
4351
4352   theCommands.Add("vconnect", 
4353     "vconnect : name object Xo Yo Zo Xu Xv Xw Zu Zv Zw", 
4354     __FILE__, VConnect, group);
4355
4356   theCommands.Add("vconnectsh", 
4357     "vconnectsh : name shape Xo Yo Zo Xu Xv Xw Zu Zv Zw", 
4358     __FILE__, VConnectShape, group);
4359
4360   theCommands.Add("vselmode", 
4361     "vselmode : [object] mode On/Off (1/0)", 
4362     __FILE__, VSetSelectionMode, group);
4363
4364   theCommands.Add("vtriangle",
4365     "vtriangle Name PointName PointName PointName", 
4366     __FILE__, VTriangle,group);
4367
4368   theCommands.Add("vsegment",
4369     "vsegment Name PointName PointName", 
4370     __FILE__, VSegment,group);
4371
4372   theCommands.Add("vobjzlayer",
4373     "vobjzlayer : set/get object [layerid] - set or get z layer id for the interactive object",
4374     __FILE__, VObjZLayer, group);
4375 }