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