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