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