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