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