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