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