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