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