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