0025467: Visualization - Possibility to remove AIS_LocalContext class
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
1 // Created on: 1998-11-12
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ViewerTest.hxx>
18
19 #include <AIS_PlaneTrihedron.hxx>
20
21 #include <Quantity_NameOfColor.hxx>
22 #include <Draw_Interpretor.hxx>
23 #include <Draw.hxx>
24 #include <Draw_Appli.hxx>
25 #include <DBRep.hxx>
26 #include <DBRep_DrawableShape.hxx>
27
28 #include <Font_BRepFont.hxx>
29 #include <Font_BRepTextBuilder.hxx>
30 #include <Font_FontMgr.hxx>
31
32 #include <NCollection_List.hxx>
33
34 #include <OSD_Chronometer.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <V3d_Viewer.hxx>
37 #include <V3d_View.hxx>
38 #include <V3d.hxx>
39
40 #include <AIS_Shape.hxx>
41 #include <AIS_DisplayMode.hxx>
42 #include <AIS_PointCloud.hxx>
43 #include <TColStd_MapOfInteger.hxx>
44 #include <AIS_MapOfInteractive.hxx>
45 #include <ViewerTest_AutoUpdater.hxx>
46 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
47 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
48 #include <ViewerTest_EventManager.hxx>
49
50 #include <TopoDS_Solid.hxx>
51 #include <BRepTools.hxx>
52 #include <BRep_Builder.hxx>
53 #include <TopAbs_ShapeEnum.hxx>
54
55 #include <TopoDS.hxx>
56 #include <BRep_Tool.hxx>
57 #include <TopExp_Explorer.hxx>
58
59 #include <BRepAdaptor_Curve.hxx>
60 #include <BRepAdaptor_Surface.hxx>
61
62 #include <TopAbs.hxx>
63 #include <TopExp.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopoDS_Face.hxx>
67
68 #include <Draw_Window.hxx>
69 #include <AIS_ListIteratorOfListOfInteractive.hxx>
70 #include <AIS_ListOfInteractive.hxx>
71 #include <AIS_DisplayMode.hxx>
72 #include <AIS_Shape.hxx>
73
74 #include <AIS_InteractiveContext.hxx>
75 #include <Geom_Plane.hxx>
76 #include <gp_Pln.hxx>
77 #include <TCollection_ExtendedString.hxx>
78 #include <TCollection_HAsciiString.hxx>
79 #include <GC_MakePlane.hxx>
80 #include <gp_Circ.hxx>
81 #include <AIS_Axis.hxx>
82 #include <Geom_Axis2Placement.hxx>
83 #include <Geom_Axis1Placement.hxx>
84 #include <AIS_Trihedron.hxx>
85 #include <AIS_Axis.hxx>
86 #include <gp_Trsf.hxx>
87 #include <gp_Quaternion.hxx>
88 #include <TopLoc_Location.hxx>
89
90 #include <HLRAlgo_Projector.hxx>
91 #include <HLRBRep_PolyAlgo.hxx>
92 #include <HLRBRep_PolyHLRToShape.hxx>
93 #include <Aspect_Window.hxx>
94
95 #include <Graphic3d_ArrayOfPoints.hxx>
96 #include <Graphic3d_ArrayOfSegments.hxx>
97 #include <Graphic3d_ArrayOfPolylines.hxx>
98 #include <Graphic3d_ArrayOfTriangles.hxx>
99 #include <Graphic3d_ArrayOfTriangleFans.hxx>
100 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
101 #include <Graphic3d_ArrayOfQuadrangles.hxx>
102 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
103 #include <Graphic3d_ArrayOfPolygons.hxx>
104 #include <Graphic3d_AspectMarker3d.hxx>
105 #include <Graphic3d_Group.hxx>
106 #include <Standard_Real.hxx>
107
108 #include <AIS_Circle.hxx>
109 #include <BRepBuilderAPI_MakeEdge.hxx>
110 #include <BRepBuilderAPI_MakeFace.hxx>
111 #include <BRepBuilderAPI_MakeWire.hxx>
112 #include <Geom_Circle.hxx>
113 #include <GC_MakeCircle.hxx>
114 #include <Select3D_SensitiveCircle.hxx>
115 #include <SelectMgr_EntityOwner.hxx>
116 #include <SelectMgr_Selection.hxx>
117 #include <StdFail_NotDone.hxx>
118 #include <StdPrs_ShadedShape.hxx>
119 #include <TopoDS_Wire.hxx>
120
121 #include <AIS_MultipleConnectedInteractive.hxx>
122 #include <AIS_ConnectedInteractive.hxx>
123 #include <AIS_TextLabel.hxx>
124 #include <TopLoc_Location.hxx>
125 #include <TColStd_ListOfInteger.hxx>
126 #include <TColStd_ListIteratorOfListOfInteger.hxx>
127
128 #include <Select3D_SensitiveTriangle.hxx>
129 #include <Select3D_SensitiveCurve.hxx>
130 #include <Select3D_SensitivePoint.hxx>
131 #include <BRepAdaptor_Curve.hxx>
132 #include <StdPrs_Curve.hxx>
133
134 #include <BRepExtrema_ExtPC.hxx>
135 #include <BRepExtrema_ExtPF.hxx>
136
137 #include <Prs3d_Arrow.hxx>
138 #include <Prs3d_ArrowAspect.hxx>
139 #include <Prs3d_DatumAttribute.hxx>
140 #include <Prs3d_DatumAspect.hxx>
141 #include <Prs3d_Drawer.hxx>
142 #include <Prs3d_VertexDrawMode.hxx>
143 #include <Prs3d_LineAspect.hxx>
144 #include <Prs3d_PointAspect.hxx>
145 #include <Prs3d_Presentation.hxx>
146 #include <Prs3d_TextAspect.hxx>
147
148 #include <Image_AlienPixMap.hxx>
149 #include <TColStd_HArray1OfAsciiString.hxx>
150 #include <TColStd_HSequenceOfAsciiString.hxx>
151
152 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
153 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
154                                            const Handle(AIS_InteractiveObject)& theAISObj,
155                                            Standard_Boolean theReplaceIfExists = Standard_True);
156 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
157 extern Handle(AIS_InteractiveContext)& TheAISContext();
158
159 namespace
160 {
161   static bool convertToColor (const Handle(TColStd_HSequenceOfAsciiString)& theColorValues,
162                               Quantity_Color& theColor)
163   {
164     const char* anArgs[3] =
165     {
166       theColorValues->Size() >= 1 ? theColorValues->Value (1).ToCString() : "",
167       theColorValues->Size() >= 2 ? theColorValues->Value (2).ToCString() : "",
168       theColorValues->Size() >= 3 ? theColorValues->Value (3).ToCString() : ""
169     };
170     return ViewerTest::ParseColor (theColorValues->Size(), anArgs, theColor) != 0;
171   }
172
173   static bool convertToDatumPart (const TCollection_AsciiString& theValue,
174                                   Prs3d_DatumParts& theDatumPart)
175   {
176     TCollection_AsciiString aValue = theValue;
177     aValue.LowerCase();
178     if      (aValue == "origin")  theDatumPart = Prs3d_DP_Origin;
179     else if (aValue == "xaxis")   theDatumPart = Prs3d_DP_XAxis;
180     else if (aValue == "yaxis")   theDatumPart = Prs3d_DP_YAxis;
181     else if (aValue == "zaxis")   theDatumPart = Prs3d_DP_ZAxis;
182     else if (aValue == "xarrow")  theDatumPart = Prs3d_DP_XArrow;
183     else if (aValue == "yarrow")  theDatumPart = Prs3d_DP_YArrow;
184     else if (aValue == "zarrow")  theDatumPart = Prs3d_DP_ZArrow;
185     else if (aValue == "xoyaxis") theDatumPart = Prs3d_DP_XOYAxis;
186     else if (aValue == "yozaxis") theDatumPart = Prs3d_DP_YOZAxis;
187     else if (aValue == "xozaxis") theDatumPart = Prs3d_DP_XOZAxis;
188     else if (aValue == "whole")   theDatumPart = Prs3d_DP_None;
189     else
190     {
191       return false;
192     }
193     return true;
194   }
195
196   static void convertToDatumParts (const TCollection_AsciiString& theValue,
197                                    NCollection_List<Prs3d_DatumParts>& theParts)
198   {
199     TCollection_AsciiString aValue = theValue;
200     const Standard_Integer aSplitPos = theValue.Search ("|");
201     Prs3d_DatumParts aPart = Prs3d_DP_None;
202     if (aSplitPos > 0)
203     {
204       convertToDatumParts (theValue.SubString (aSplitPos + 1, theValue.Length()), theParts);
205       if (aSplitPos == 1) // first symbol
206       {
207         return;
208       }
209       aValue = theValue.SubString (1, aSplitPos - 1);
210     }
211     if (convertToDatumPart (aValue, aPart))
212     {
213       theParts.Append (aPart);
214     }
215   }
216
217   static bool convertToDatumAttribute (const TCollection_AsciiString& theValue,
218                                        Prs3d_DatumAttribute& theAttribute)
219   {
220     TCollection_AsciiString aValue = theValue;
221     aValue.LowerCase();
222     if      (aValue == "xaxislength")       theAttribute = Prs3d_DA_XAxisLength;
223     else if (aValue == "yaxislength")       theAttribute = Prs3d_DA_YAxisLength;
224     else if (aValue == "zaxislength")       theAttribute = Prs3d_DA_ZAxisLength;
225     else if (aValue == "tuberadiuspercent") theAttribute = Prs3d_DP_ShadingTubeRadiusPercent;
226     else if (aValue == "coneradiuspercent") theAttribute = Prs3d_DP_ShadingConeRadiusPercent;
227     else if (aValue == "conelengthpercent") theAttribute = Prs3d_DP_ShadingConeLengthPercent;
228     else if (aValue == "originradiuspercent") theAttribute = Prs3d_DP_ShadingOriginRadiusPercent;
229     else if (aValue == "shadingnumberoffacettes") theAttribute = Prs3d_DP_ShadingNumberOfFacettes;
230     else
231       return false;
232     return true;
233   }
234
235   static void convertToDatumAttributes (const TCollection_AsciiString& theValue,
236                                         NCollection_List<Prs3d_DatumAttribute>& theAttributes)
237   {
238     TCollection_AsciiString aValue = theValue;
239     const Standard_Integer aSplitPos = theValue.Search ("|");
240     Prs3d_DatumAttribute anAttribute = Prs3d_DA_XAxisLength;
241     if (aSplitPos > 0)
242     {
243       convertToDatumAttributes (theValue.SubString (aSplitPos + 1, theValue.Length()), theAttributes);
244       if (aSplitPos == 1) // first symbol
245       {
246         return;
247       }
248       aValue = theValue.SubString (1, aSplitPos - 1);
249     }
250     if (convertToDatumAttribute (aValue, anAttribute))
251     {
252       theAttributes.Append (anAttribute);
253     }
254   }
255
256   static bool convertToDatumAxes (const TCollection_AsciiString& theValue,
257                                   Prs3d_DatumAxes& theDatumAxes)
258   {
259     TCollection_AsciiString aValue = theValue;
260     aValue.LowerCase();
261     if      (aValue == "x")   theDatumAxes = Prs3d_DA_XAxis;
262     else if (aValue == "y")   theDatumAxes = Prs3d_DA_YAxis;
263     else if (aValue == "z")   theDatumAxes = Prs3d_DA_ZAxis;
264     else if (aValue == "xy")  theDatumAxes = Prs3d_DA_XYAxis;
265     else if (aValue == "zy")  theDatumAxes = Prs3d_DA_YZAxis;
266     else if (aValue == "xz")  theDatumAxes = Prs3d_DA_XZAxis;
267     else if (aValue == "xyz") theDatumAxes = Prs3d_DA_XYZAxis;
268     else
269     {
270       return false;
271     }
272     return true;
273   }
274
275   static Standard_Boolean setTrihedronParams (Standard_Integer  theArgsNb,
276                                               const char** theArgVec,
277                                               Handle(AIS_Trihedron) theTrihedron)
278   {
279     NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
280     TCollection_AsciiString aParseKey;
281     for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
282     {
283       TCollection_AsciiString anArg (theArgVec [anArgIt]);
284       if (anArg.Value (1) == '-'
285       && !anArg.IsRealValue())
286       {
287         aParseKey = anArg;
288         aParseKey.Remove (1);
289         aParseKey.LowerCase();
290         std::string aKey = aParseKey.ToCString();
291         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString());
292         continue;
293       }
294
295       if (aParseKey.IsEmpty())
296       {
297         continue;
298       }
299
300       aMapOfArgs (aParseKey)->Append (anArg);
301     }
302
303     // Check parameters
304     if ((aMapOfArgs.IsBound ("xaxis") && !aMapOfArgs.IsBound ("zaxis"))
305     || (!aMapOfArgs.IsBound ("xaxis") &&  aMapOfArgs.IsBound ("zaxis")))
306     {
307       std::cout << "Syntax error: -xaxis and -zaxis parameters are to set together.\n";
308       return Standard_False;
309     }
310
311     Handle(TColStd_HSequenceOfAsciiString) aValues;
312     Handle(Geom_Axis2Placement) aComponent = theTrihedron->Component();
313     if (aMapOfArgs.Find ("origin", aValues))
314     {
315       aComponent->SetLocation (gp_Pnt (aValues->Value (1).RealValue(),
316                                        aValues->Value (2).RealValue(),
317                                        aValues->Value (3).RealValue()));
318     }
319     Handle(TColStd_HSequenceOfAsciiString) aXValues, aZValues;
320     if (aMapOfArgs.Find ("xaxis", aXValues) && aMapOfArgs.Find ("zaxis", aZValues))
321     {
322       gp_Dir aXDir (aXValues->Value (1).RealValue(),
323                     aXValues->Value (2).RealValue(),
324                     aXValues->Value (3).RealValue());
325
326       gp_Dir aZDir (aZValues->Value (1).RealValue(),
327                     aZValues->Value (2).RealValue(),
328                     aZValues->Value (3).RealValue());
329
330       if (!aZDir.IsNormal (aXDir, M_PI / 180.0))
331       {
332         std::cout << "Syntax error - parameters 'xaxis' and 'zaxis' are not applied as VectorX is not normal to VectorZ\n";
333         return Standard_False;
334       }
335
336       aComponent->SetXDirection(aXDir);
337       aComponent->SetDirection (aZDir);
338     }
339
340     if (aMapOfArgs.Find ("dispmode", aValues))
341     {
342       TCollection_AsciiString aValue (aValues->Value (1));
343       bool isWireframe = true;
344       if (aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
345         isWireframe = false;
346       theTrihedron->SetDatumDisplayMode (isWireframe ? Prs3d_DM_WireFrame
347                                                      : Prs3d_DM_Shaded);
348     }
349
350     if (aMapOfArgs.Find ("hidelabels", aValues))
351     {
352       Standard_Boolean toHideLabels = Standard_True;
353       if (aValues->Size() == 1)
354       {
355         ViewerTest::ParseOnOff (aValues->First().ToCString(), toHideLabels);
356       }
357       else if (aValues->Size() != 0)
358       {
359         std::cout << "Syntax error: -hidelabels expects parameter 'on' or 'off' after.\n";
360         return Standard_False;
361       }
362
363       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
364       {
365         theTrihedron->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
366       }
367       theTrihedron->Attributes()->DatumAspect()->SetDrawLabels (!toHideLabels);
368     }
369
370     if (aMapOfArgs.Find ("hidearrows", aValues))
371     {
372       Standard_Boolean toHideArrows = Standard_True;
373       if (aValues->Size() == 1)
374       {
375         ViewerTest::ParseOnOff (aValues->First().ToCString(), toHideArrows);
376       }
377       else if (aValues->Size() != 0)
378       {
379         std::cout << "Syntax error: -hidearrows expects parameter 'on' or 'off' after.\n";
380         return Standard_False;
381       }
382
383       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
384       {
385         theTrihedron->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
386       }
387       theTrihedron->Attributes()->DatumAspect()->SetDrawArrows (!toHideArrows);
388     }
389
390     if (aMapOfArgs.Find ("color", aValues))
391     {
392       NCollection_List<Prs3d_DatumParts> aParts;
393       if (aValues->Size() < 2)
394       {
395         std::cout << "Syntax error: -color wrong parameters.\n";
396         return Standard_False;
397       }
398
399       convertToDatumParts (aValues->Value(1), aParts);
400       aValues->Remove (1); // datum part is processed
401       Quantity_Color aColor;
402       if (!convertToColor (aValues, aColor))
403       {
404         std::cout << "Syntax error: -color wrong parameters.\n";
405         return Standard_False;
406       }
407
408       for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator (aParts); anIterator.More(); anIterator.Next())
409       {
410         Prs3d_DatumParts aDatumPart = anIterator.Value();
411         if (aDatumPart == Prs3d_DP_None)
412         {
413           theTrihedron->SetColor (aColor);
414         }
415         else
416         {
417           theTrihedron->SetDatumPartColor (aDatumPart, aColor);
418         }
419       }
420     }
421
422     if (aMapOfArgs.Find ("textcolor", aValues))
423     {
424       Quantity_Color aColor;
425       if (!convertToColor (aValues, aColor))
426       {
427         std::cout << "Syntax error: -textcolor wrong parameters.\n";
428         return Standard_False;
429       }
430       theTrihedron->SetTextColor (aColor);
431     }
432
433     if (aMapOfArgs.Find ("arrowcolor", aValues))
434     {
435       Quantity_Color aColor;
436       if (!convertToColor (aValues, aColor))
437       {
438         std::cout << "Syntax error: -arrowcolor wrong parameters.\n";
439         return Standard_False;
440       }
441       theTrihedron->SetArrowColor (aColor);
442     }
443
444     if (aMapOfArgs.Find ("attribute", aValues))
445     {
446       NCollection_List<Prs3d_DatumAttribute> anAttributes;
447       if (aValues->Size() != 2)
448       {
449         std::cout << "Syntax error: -attribute wrong parameters.\n";
450         return Standard_False;
451       }
452
453       convertToDatumAttributes (aValues->Value (1), anAttributes);
454       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
455         theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
456       for (NCollection_List<Prs3d_DatumAttribute>::Iterator anIterator (anAttributes); anIterator.More(); anIterator.Next())
457       {
458         theTrihedron->Attributes()->DatumAspect()->SetAttribute (anIterator.Value(), aValues->Value (2).RealValue());
459       }
460     }
461
462     if (aMapOfArgs.Find ("priority", aValues))
463     {
464       Prs3d_DatumParts aDatumPart;
465       if (aValues->Size() < 2
466       || !convertToDatumPart (aValues->Value (1), aDatumPart))
467       {
468         std::cout << "Syntax error: -priority wrong parameters.\n";
469         return Standard_False;
470       }
471       theTrihedron->SetSelectionPriority (aDatumPart, aValues->Value (2).IntegerValue());
472     }
473
474     if (aMapOfArgs.Find ("labels", aValues))
475     {
476       Prs3d_DatumParts aDatumPart = Prs3d_DP_None;
477       if (aValues->Size() > 2
478        && convertToDatumPart(aValues->Value(1), aDatumPart)
479        && aDatumPart >= Prs3d_DP_XAxis
480        && aDatumPart <= Prs3d_DP_ZAxis) // labels are set to axes only
481       {
482         theTrihedron->SetLabel (aDatumPart, aValues->Value (2));
483       }
484       else
485       {
486         std::cout << "Syntax error: -labels wrong parameters.\n";
487         return Standard_False;
488       }
489     }
490
491     if (aMapOfArgs.Find ("drawaxes", aValues))
492     {
493       Prs3d_DatumAxes aDatumAxes = Prs3d_DA_XAxis;
494       if (aValues->Size() < 1
495       || !convertToDatumAxes (aValues->Value (1), aDatumAxes))
496       {
497         std::cout << "Syntax error: -drawaxes wrong parameters.\n";
498         return Standard_False;
499       }
500       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
501         theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
502       theTrihedron->Attributes()->DatumAspect()->SetDrawDatumAxes (aDatumAxes);
503     }
504     return Standard_True;
505   }
506 }
507
508 //==============================================================================
509 //function : Vtrihedron 2d
510 //purpose  : Create a plane with a 2D  trihedron from a faceselection
511 //Draw arg : vtri2d  name
512 //==============================================================================
513 static int VTrihedron2D (Draw_Interpretor& /*theDI*/,
514                          Standard_Integer  theArgsNum,
515                          const char**      theArgVec)
516 {
517   if (theArgsNum != 2)
518   {
519     std::cerr << theArgVec[0]<< " error.\n";
520     return 1;
521   }
522
523   TopTools_ListOfShape aShapes;
524   ViewerTest::GetSelectedShapes (aShapes);
525
526   if (aShapes.Extent() != 1)
527   {
528     std::cerr << "Error: wrong number of selected shapes.\n";
529     return 1;
530   }
531
532   const TopoDS_Shape& aShape = aShapes.First();
533
534   TopoDS_Face     aFace = TopoDS::Face (aShape);
535   TopExp_Explorer aFaceExp (aFace, TopAbs_EDGE);
536   TopoDS_Edge     anEdge0 = TopoDS::Edge (aFaceExp.Current());
537
538   gp_Pnt A,B,C;
539   if (aFaceExp.More())
540   {
541     aFaceExp.Next();
542     TopoDS_Edge anEdge1 = TopoDS::Edge (aFaceExp.Current() );
543     BRepAdaptor_Curve aCurve0 (anEdge0);
544     BRepAdaptor_Curve aCurve1 (anEdge1);
545     A = aCurve1.Value (0.1);
546     B = aCurve1.Value (0.9);
547     C = aCurve0.Value (0.5);
548   }
549   else
550   {
551     BRepAdaptor_Curve aCurve0 (anEdge0);
552     A = aCurve0.Value (0.1);
553     B = aCurve0.Value (0.9);
554     C = aCurve0.Value (0.5);
555   }
556
557   GC_MakePlane aMkPlane (A,B,C);
558
559   Handle(AIS_PlaneTrihedron) anAISPlaneTri = new AIS_PlaneTrihedron (aMkPlane.Value());
560   TCollection_AsciiString aName (theArgVec[1]);
561
562   VDisplayAISObject (aName, anAISPlaneTri);
563
564   return 0;
565 }
566
567 //=======================================================================
568 //function : VTrihedron
569 //purpose  :
570 //=======================================================================
571 static int VTrihedron (Draw_Interpretor& ,
572                        Standard_Integer theArgsNb,
573                        const char** theArgVec)
574 {
575   if (theArgsNb < 2)
576   {
577     std::cout << "Syntax error: the wrong number of input parameters.\n";
578     return 1;
579   }
580
581   TCollection_AsciiString aName (theArgVec[1]);
582   gp_Pln aWorkingPlane;
583   Standard_Boolean toUpdate = Standard_True;
584
585   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
586   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
587
588   Handle(AIS_Trihedron) aTrihedron;
589   if (GetMapOfAIS().IsBound2 (aName))
590   {
591     Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
592     aTrihedron = Handle(AIS_Trihedron)::DownCast (anObject);
593     if (aTrihedron.IsNull())
594     {
595       std::cout << "Syntax error: no trihedron with this name.\n";
596       return 1;
597     }
598   }
599   else
600   {
601     Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (gp_Pnt (0.0, 0.0, 0.0),
602                                                                       gp::DZ(), gp::DX());
603     aTrihedron = new AIS_Trihedron (aPlacement);
604   }
605
606   if (!setTrihedronParams (theArgsNb, theArgVec, aTrihedron))
607   {
608     return 1;
609   }
610
611   // Redisplay a dimension after parameter changing.
612   if (ViewerTest::GetAISContext()->IsDisplayed (aTrihedron))
613   {
614     ViewerTest::GetAISContext()->Redisplay (aTrihedron, toUpdate);
615   }
616   else
617   {
618     VDisplayAISObject (theArgVec[1], aTrihedron);
619   }
620
621   return 0;
622 }
623
624 //==============================================================================
625 //function : VSize
626 //author   : ege
627 //purpose  : Change the size of a named or selected trihedron
628 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
629 //           if no value, the value is set at 100 by default
630 //Draw arg : vsize [name] [size]
631 //==============================================================================
632
633 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
634
635 {
636   // Declaration de booleens
637   Standard_Boolean             ThereIsName;
638   Standard_Boolean             ThereIsCurrent;
639   Standard_Real                value;
640   Standard_Boolean             hascol;
641
642   Quantity_Color col = Quantity_NOC_BLACK;
643
644   // Verification des arguments
645   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error\n"; return 1;}
646
647   // Verification du nombre d'arguments
648   if (argc==1)      {ThereIsName=Standard_False;value=100;}
649   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
650   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
651
652   // On set le booleen ThereIsCurrent
653   if (TheAISContext() -> NbSelected() > 0) {ThereIsCurrent=Standard_True;}
654   else {ThereIsCurrent=Standard_False;}
655
656
657
658   //===============================================================
659   // Il n'y a pas de nom  mais des objets selectionnes
660   //===============================================================
661   if (!ThereIsName && ThereIsCurrent)
662   {
663
664     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
665       it (GetMapOfAIS());
666
667     while ( it.More() ) {
668
669       Handle(AIS_InteractiveObject) aShape=
670         Handle(AIS_InteractiveObject)::DownCast(it.Key1());
671
672       if (!aShape.IsNull() &&  TheAISContext()->IsSelected(aShape) )
673       {
674
675         // On verifie que l'AIS InteraciveObject selectionne est bien
676         // un AIS_Trihedron
677         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
678
679           if (aShape->HasColor())
680           {
681             hascol = Standard_True;
682
683             // On recupere la couleur de aShape
684             aShape->Color (col);
685           }
686           else
687           {
688             hascol = Standard_False;
689           }
690
691           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
692           // pour lui appliquer la methode SetSize()
693           Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
694
695           // C'est bien un triedre,on chage sa valeur!
696           aTrihedron->SetSize(value);
697
698           // On donne la couleur au Trihedron
699           if(hascol)   aTrihedron->SetColor(col);
700           else         aTrihedron->UnsetColor();
701
702
703           // The trihedron hasn't be errased from the map
704           // so you just have to redisplay it
705           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
706
707         }
708
709       }
710
711       it.Next();
712     }
713
714     TheAISContext() ->UpdateCurrentViewer();
715   }
716
717   //===============================================================
718   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
719   //===============================================================
720
721
722
723   //===============================================================
724   // Il y a un nom de triedre passe en argument
725   //===============================================================
726   if (ThereIsName) {
727     TCollection_AsciiString name=argv[1];
728
729     // on verifie que ce nom correspond bien a une shape
730     Standard_Boolean IsBound= GetMapOfAIS().IsBound2(name);
731
732     if (IsBound) {
733
734       // on recupere la shape dans la map des objets displayes
735       Handle(AIS_InteractiveObject) aShape =
736         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(name));
737
738       // On verifie que l'AIS InteraciveObject est bien
739       // un AIS_Trihedron
740       if (!aShape.IsNull() &&
741         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
742       {
743         if (aShape->HasColor())
744         {
745           hascol=Standard_True;
746
747           // On recupere la couleur de aShape
748           aShape->Color (col);
749         }
750         else
751         {
752           hascol = Standard_False;
753         }
754
755         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
756         // pour lui appliquer la methode SetSize()
757         Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
758
759         // C'est bien un triedre,on chage sa valeur
760         aTrihedron->SetSize(value);
761
762         // On donne la couleur au Trihedron
763         if(hascol)   aTrihedron->SetColor(col);
764         else         aTrihedron->UnsetColor();
765
766         // The trihedron hasn't be errased from the map
767         // so you just have to redisplay it
768         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
769
770         TheAISContext() ->UpdateCurrentViewer();
771       }
772     }
773   }
774   return 0;
775 }
776
777
778 //==============================================================================
779
780 //==============================================================================
781 //function : VPlaneTrihedron
782 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
783 //Draw arg : vplanetri  name
784 //==============================================================================
785 #include <AIS_Plane.hxx>
786
787
788
789 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
790
791 {
792   // Verification des arguments
793   if ( argc!=2) {di<<argv[0]<<" error\n"; return 1;}
794
795   if (TheAISContext()->NbSelected() != 1)
796   {
797     std::cerr << "Error: Wrong number of selected shapes.\n";
798     return 1;
799   }
800
801   TheAISContext()->InitSelected();
802   Handle(AIS_InteractiveObject) aTest = TheAISContext()->SelectedInteractive();
803   Handle(AIS_Plane) aPlane = Handle(AIS_Plane)::DownCast (aTest);
804   if (aPlane.IsNull())
805   {
806     std::cerr << "Error: Selected shape is not a plane.\n";
807     return 1;
808   }
809
810   VDisplayAISObject (argv[1], aPlane);
811
812   return 0;
813 }
814
815
816
817 //==============================================================================
818 // Fonction        First click      2de click
819 //
820 // vaxis           vertex           vertex
821 //                 edge             None
822 // vaxispara       edge             vertex
823 // vaxisortho      edge             Vertex
824 // vaxisinter      Face             Face
825 //==============================================================================
826
827 //==============================================================================
828 //function : VAxisBuilder
829 //purpose  :
830 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
831 //==============================================================================
832 #include <TopoDS_Edge.hxx>
833 #include <TopoDS_Vertex.hxx>
834 #include <TopExp.hxx>
835 #include <Geom_Line.hxx>
836
837 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
838 {
839   // Declarations
840   Standard_Boolean HasArg;
841   TCollection_AsciiString name;
842
843   // Verification
844   if (argc<2 || argc>8 ) {di<<" Syntaxe error\n";return 1;}
845   if (argc==8) HasArg=Standard_True;
846   else HasArg=Standard_False;
847
848   name=argv[1];
849
850   TopTools_ListOfShape aShapes;
851   ViewerTest::GetSelectedShapes (aShapes);
852
853   // Cas ou il y a des arguments
854   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
855   if (HasArg) {
856     Standard_Real coord[6];
857     for(Standard_Integer i=0;i<=5;i++){
858       coord[i]=Draw::Atof(argv[2+i]);
859     }
860     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
861
862     gp_Vec myVect (p1,p2);
863     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
864     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
865     GetMapOfAIS().Bind (TheAxis,name);
866     TheAISContext()->Display(TheAxis, Standard_True);
867   }
868
869   // Pas d'arguments
870   else {
871     // fonction vaxis
872     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
873     if ( !strcasecmp(argv[0], "vaxis")) {
874       if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
875       {
876         std::cerr << "Error: Wrong number of selected shapes.\n";
877         return 1;
878       }
879
880       const TopoDS_Shape& aShapeA = aShapes.First();
881       if (aShapeA.ShapeType() == TopAbs_VERTEX)
882       {
883         if (aShapes.Extent() != 2)
884         {
885           std::cerr << "Error: Wron number of selected shapes.\n";
886           return 1;
887         }
888
889         const TopoDS_Shape& aShapeB = aShapes.Last();
890         if (aShapeB.ShapeType() != TopAbs_VERTEX)
891         {
892           std::cerr << "Syntax error: You should select two vertices or one edge.\n";
893           return 1;
894         }
895
896         // Construction de l'axe
897         gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
898         gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
899         gp_Vec V (A,B);
900         gp_Dir D (V);
901         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
902         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
903         GetMapOfAIS().Bind (TheAxis,name);
904         TheAISContext()->Display (TheAxis, Standard_True);
905       }
906       else
907       {
908         TopoDS_Edge    ed =TopoDS::Edge (aShapeA);
909         TopoDS_Vertex  Va,Vb;
910         TopExp::Vertices(ed,Va,Vb );
911         gp_Pnt A=BRep_Tool::Pnt(Va);
912         gp_Pnt B=BRep_Tool::Pnt(Vb);
913         gp_Vec  V (A,B);
914         gp_Dir   D (V);
915         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
916         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
917         GetMapOfAIS().Bind (TheAxis,name);
918         TheAISContext()->Display (TheAxis, Standard_True);
919       }
920
921     }
922
923     // Fonction axispara
924     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
925     else if ( !strcasecmp(argv[0], "vaxispara"))
926     {
927       if (aShapes.Extent() != 2)
928       {
929         std::cerr << "Error: Wrong number of selected shapes.\n";
930         return 1;
931       }
932
933       const TopoDS_Shape& aShapeA = aShapes.First();
934       const TopoDS_Shape& aShapeB = aShapes.Last();
935       if (!(aShapeA.ShapeType() == TopAbs_EDGE
936          && aShapeB.ShapeType() == TopAbs_VERTEX))
937       {
938         std::cerr << "Syntax error: You should select face and then vertex.\n";
939         return 1;
940       }
941
942       TopoDS_Edge    ed=TopoDS::Edge (aShapeA);
943       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
944       TopoDS_Vertex  Va,Vc;
945       TopExp::Vertices(ed,Va,Vc );
946       gp_Pnt A=BRep_Tool::Pnt(Va);
947       gp_Pnt C=BRep_Tool::Pnt(Vc);
948       gp_Vec  V (A,C);
949       gp_Dir   D (V);
950       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
951       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
952       GetMapOfAIS().Bind (TheAxis,name);
953       TheAISContext()->Display (TheAxis, Standard_True);
954
955     }
956
957     // Fonction axisortho
958     else
959     {
960       if (aShapes.Extent() != 2)
961       {
962         std::cerr << "Error: Wrong number of selected shapes.\n";
963         return 1;
964       }
965
966       const TopoDS_Shape& aShapeA = aShapes.First();
967       const TopoDS_Shape& aShapeB = aShapes.Last();
968       if (!(aShapeA.ShapeType() == TopAbs_EDGE
969          && aShapeB.ShapeType() == TopAbs_VERTEX))
970       {
971         std::cerr << "Syntax error: You should select face and then vertex.\n";
972         return 1;
973       }
974
975       // Construction de l'axe
976       TopoDS_Edge    ed=TopoDS::Edge(aShapeA) ;
977       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(aShapeB) );
978       TopoDS_Vertex  Va,Vc;
979       TopExp::Vertices(ed,Va,Vc );
980       gp_Pnt A=BRep_Tool::Pnt(Va);
981       gp_Pnt C=BRep_Tool::Pnt(Vc);
982       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
983       gp_Vec  V (A,E);
984       gp_Dir   D (V);
985       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
986       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
987       GetMapOfAIS().Bind (TheAxis,name);
988       TheAISContext()->Display (TheAxis, Standard_True);
989
990     }
991
992   }
993   return 0;
994 }
995
996
997 //==============================================================================
998 // Fonction        First click      Result
999 //
1000 // vpoint          vertex           AIS_Point=Vertex
1001 //                 edge             AIS_Point=Middle of the edge
1002 //==============================================================================
1003
1004 //==============================================================================
1005 //function : VPointBuilder
1006 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
1007 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
1008 //==============================================================================
1009 #include <TopoDS_Edge.hxx>
1010 #include <TopoDS_Vertex.hxx>
1011 #include <TopExp.hxx>
1012 #include <AIS_Point.hxx>
1013 #include <Geom_CartesianPoint.hxx>
1014
1015 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1016 {
1017   // Declarations
1018   Standard_Boolean HasArg;
1019   TCollection_AsciiString name;
1020
1021   // Verification
1022   if (argc<2 || argc>5 ) {di<<" Syntaxe error\n";return 1;}
1023   if (argc==5) HasArg=Standard_True;
1024   else HasArg=Standard_False;
1025
1026   name=argv[1];
1027
1028   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
1029   if (HasArg) {
1030     Standard_Real thecoord[3];
1031     for(Standard_Integer i=0;i<=2;i++)
1032       thecoord[i]=Draw::Atof(argv[2+i]);
1033     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
1034     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
1035     GetMapOfAIS().Bind (myAISPoint,name);
1036     TheAISContext()->Display (myAISPoint, Standard_True);
1037   }
1038
1039   // Il n'a pas d'arguments
1040   else
1041   {
1042     TopTools_ListOfShape aShapes;
1043     ViewerTest::GetSelectedShapes (aShapes);
1044
1045     if (aShapes.Extent() != 1)
1046     {
1047       std::cerr << "Error: Wrong number of selected shapes.\n";
1048       std::cerr << "\tYou should select one edge or vertex.\n";
1049       return 1;
1050     }
1051
1052     const TopoDS_Shape& aShapeA = aShapes.First();
1053
1054     if (aShapeA.ShapeType()==TopAbs_VERTEX )
1055     {
1056       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(aShapeA ) );
1057       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
1058       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
1059       GetMapOfAIS().Bind(myAISPoint,name);
1060       TheAISContext()->Display (myAISPoint, Standard_True);
1061     }
1062     else
1063     {
1064       TopoDS_Edge myEdge=TopoDS::Edge(aShapeA);
1065       TopoDS_Vertex myVertexA,myVertexB;
1066       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
1067       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
1068       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
1069       // M est le milieu de [AB]
1070       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
1071       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
1072       GetMapOfAIS().Bind(myAISPointM,name);
1073       TheAISContext()->Display (myAISPointM, Standard_True);
1074     }
1075
1076   }
1077   return 0;
1078
1079 }
1080
1081 //==============================================================================
1082 // Function        1st click   2de click  3de click
1083 // vplane          Vertex      Vertex     Vertex
1084 //                 Vertex      Edge
1085 //                 Edge        Vertex
1086 //                 Face
1087 // vplanepara      Face        Vertex
1088 //                 Vertex      Face
1089 // vplaneortho     Face        Edge
1090 //                 Edge        Face
1091 //==============================================================================
1092
1093 //==============================================================================
1094 //function : VPlaneBuilder
1095 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
1096 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
1097 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
1098 //                            [PlaneName] [PointName] [TypeOfSensitivity]
1099 //==============================================================================
1100
1101 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
1102                                        Standard_Integer argc,
1103                                        const char** argv)
1104 {
1105   // Declarations
1106   Standard_Boolean hasArg;
1107   TCollection_AsciiString aName;
1108
1109   // Verification
1110   if (argc<2 || argc>6 )
1111   {
1112     std::cout<<" Syntax error\n";
1113     return 1;
1114   }
1115   if (argc == 6 || argc==5 || argc==4)
1116     hasArg=Standard_True;
1117   else 
1118     hasArg=Standard_False;
1119
1120   aName=argv[1];
1121
1122   // There are some arguments
1123   if (hasArg)
1124   {
1125     if (!GetMapOfAIS().IsBound2(argv[2] ))
1126     {
1127       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
1128       return 1;
1129     }
1130     // Get shape from map
1131     Handle(AIS_InteractiveObject) aShapeA =
1132       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2] ));
1133
1134     // The first argument is an AIS_Point
1135     if (!aShapeA.IsNull() &&
1136         aShapeA->Type()==AIS_KOI_Datum &&
1137         aShapeA->Signature()==1)
1138     {
1139         // The second argument must also be an AIS_Point
1140         if (argc<5 || !GetMapOfAIS().IsBound2(argv[3]))
1141         {
1142           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
1143           return 1;
1144         }
1145         // Get shape from map
1146         Handle(AIS_InteractiveObject) aShapeB =
1147           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1148         // If B is not an AIS_Point
1149         if (aShapeB.IsNull() ||
1150           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1151         {
1152           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
1153           return 1;
1154         }
1155         // The third object is an AIS_Point
1156         if (!GetMapOfAIS().IsBound2(argv[4]) ) 
1157         {
1158           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
1159           return 1; 
1160         }
1161         // Get shape from map
1162         Handle(AIS_InteractiveObject) aShapeC =
1163           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[4]));
1164         // If C is not an AIS_Point
1165         if (aShapeC.IsNull() ||
1166           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
1167         {
1168           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
1169           return 1;
1170         }
1171
1172         // Treatment of objects A, B, C
1173         // Downcast an AIS_IO to AIS_Point
1174         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
1175         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
1176         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
1177
1178         Handle(Geom_CartesianPoint ) aCartPointA = 
1179           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
1180
1181         Handle(Geom_CartesianPoint ) aCartPointB = 
1182           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
1183
1184         Handle(Geom_CartesianPoint ) aCartPointC = 
1185           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
1186
1187         // Verification that the three points are different
1188         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
1189            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1190            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
1191         {
1192           // B=A
1193           std::cout<<"vplane error: same points\n";return 1;
1194         }
1195         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
1196            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1197            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
1198         {
1199           // C=A
1200           std::cout<<"vplane error: same points\n";return 1;
1201         }
1202         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
1203            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
1204            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
1205         {
1206           // C=B
1207           std::cout<<"vplane error: same points\n";return 1;
1208         }
1209
1210         gp_Pnt A = aCartPointA->Pnt();
1211         gp_Pnt B = aCartPointB->Pnt();
1212         gp_Pnt C = aCartPointC->Pnt();
1213
1214         // Construction of AIS_Plane
1215         GC_MakePlane MkPlane (A,B,C);
1216         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1217         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1218         GetMapOfAIS().Bind (anAISPlane,aName );
1219         if (argc == 6)
1220         {
1221           Standard_Integer aType = Draw::Atoi (argv[5]);
1222           if (aType != 0 && aType != 1)
1223           {
1224             std::cout << "vplane error: wrong type of sensitivity!\n"
1225                       << "Should be one of the following values:\n"
1226                       << "0 - Interior\n"
1227                       << "1 - Boundary"
1228                       << std::endl;
1229             return 1;
1230           }
1231           else
1232           {
1233             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1234           }
1235         }
1236         TheAISContext()->Display (anAISPlane, Standard_True);
1237       }
1238
1239       // The first argument is an AIS_Axis
1240       // Creation of a plane orthogonal to the axis through a point
1241     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1242       // The second argument should be an AIS_Point
1243       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3] ) )
1244       {
1245         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1246         return 1;
1247       }
1248       // Get shape from map
1249       Handle(AIS_InteractiveObject) aShapeB =
1250         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1251       // If B is not an AIS_Point
1252       if (aShapeB.IsNull() ||
1253         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1254       {
1255         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1256         return 1;
1257       }
1258
1259       // Treatment of objects A and B
1260       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1261       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1262
1263       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1264       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1265
1266       gp_Ax1 anAxis = aGeomLineA->Position();
1267       Handle(Geom_CartesianPoint) aCartPointB = 
1268         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1269
1270       gp_Dir D =anAxis.Direction();
1271       gp_Pnt B = aCartPointB->Pnt();
1272
1273       // Construction of AIS_Plane
1274       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1275       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1276       GetMapOfAIS().Bind (anAISPlane,aName );
1277       if (argc == 5)
1278       {
1279         Standard_Integer aType = Draw::Atoi (argv[4]);
1280         if (aType != 0 && aType != 1)
1281         {
1282           std::cout << "vplane error: wrong type of sensitivity!\n"
1283                     << "Should be one of the following values:\n"
1284                     << "0 - Interior\n"
1285                     << "1 - Boundary"
1286                     << std::endl;
1287           return 1;
1288         }
1289         else
1290         {
1291           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1292         }
1293       }
1294       TheAISContext()->Display (anAISPlane, Standard_True);
1295
1296     }
1297     // The first argumnet is an AIS_Plane
1298     // Creation of a plane parallel to the plane passing through the point
1299     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1300     {
1301       // The second argument should be an AIS_Point
1302       if (argc!=4 || !GetMapOfAIS().IsBound2(argv[3]))
1303       {
1304         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1305         return 1;
1306       }
1307       // Get shape from map
1308       Handle(AIS_InteractiveObject) aShapeB =
1309         Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1310       // B should be an AIS_Point
1311       if (aShapeB.IsNull() ||
1312          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1313       {
1314         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1315         return 1;
1316       }
1317
1318       // Treatment of objects A and B
1319       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1320       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1321
1322       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1323       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1324
1325       Handle(Geom_CartesianPoint) aCartPointB = 
1326         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1327       gp_Pnt B= aCartPointB->Pnt();
1328
1329       // Construction of an AIS_Plane
1330       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1331       GetMapOfAIS().Bind (anAISPlane, aName);
1332       if (argc == 5)
1333       {
1334         Standard_Integer aType = Draw::Atoi (argv[4]);
1335         if (aType != 0 && aType != 1)
1336         {
1337           std::cout << "vplane error: wrong type of sensitivity!\n"
1338                     << "Should be one of the following values:\n"
1339                     << "0 - Interior\n"
1340                     << "1 - Boundary"
1341                     << std::endl;
1342           return 1;
1343         }
1344         else
1345         {
1346           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1347         }
1348       }
1349       TheAISContext()->Display (anAISPlane, Standard_True);
1350     }
1351     // Error
1352     else
1353     {
1354       std::cout<<"vplane: error 1st object is not an AIS\n";
1355       return 1;
1356     }
1357   }
1358   // There are no arguments
1359   else 
1360   {
1361     TopTools_ListOfShape aShapes;
1362     ViewerTest::GetSelectedShapes (aShapes);
1363
1364     // Function vplane
1365     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1366     if (!strcasecmp(argv[0], "vplane"))
1367     {
1368       if (aShapes.Extent() < 1 || aShapes.Extent() > 3)
1369       {
1370         std::cerr << "Error: Wront number of selected shapes.\n";
1371         std::cerr << "\tYou should one of variant: face, edge and vertex or three vertices.\n";
1372         return 1;
1373       }
1374
1375       const TopoDS_Shape& aShapeA = aShapes.First();
1376       if (aShapeA.ShapeType() == TopAbs_VERTEX)
1377       {
1378         if (aShapes.Extent() == 2)
1379         {
1380           const TopoDS_Shape& aShapeB = aShapes.Last();
1381           if (aShapeB.ShapeType() != TopAbs_EDGE)
1382           {
1383             std::cerr << "Syntax error: Together with vertex should be edge.\n";
1384             return 1;
1385           }
1386
1387           // Verify that the vertex is not on the edge ShapeB
1388           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1389           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1390
1391           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1392           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1393           {
1394             // The vertex is on the edge
1395             std::cout<<" vplane: error point is on the edge\n";
1396             return 1;
1397           }
1398           else
1399           {
1400             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1401             TopoDS_Vertex aVBa, aVBb;
1402             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1403             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1404             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1405             GC_MakePlane MkPlane (A, aBa, aBb);
1406             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1407             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1408             GetMapOfAIS().Bind (anAISPlane, aName);
1409             TheAISContext()->Display (anAISPlane, Standard_True);
1410           }
1411         }
1412         else if (aShapes.Extent() == 3)
1413         {
1414           TopTools_ListOfShape::Iterator anIter (aShapes);
1415
1416           anIter.Next();
1417           const TopoDS_Shape& aShapeB = anIter.Value();
1418
1419           anIter.Next();
1420           const TopoDS_Shape& aShapeC = anIter.Value();
1421
1422           if (!(aShapeB.ShapeType() == TopAbs_VERTEX
1423              && aShapeC.ShapeType() == TopAbs_VERTEX))
1424           {
1425             std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
1426             return 1;
1427           }
1428
1429           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1430           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1431           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1432           GC_MakePlane MkPlane(A, B, C);
1433           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1434           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1435           GetMapOfAIS().Bind (anAISPlane, aName);
1436           TheAISContext()->Display (anAISPlane, Standard_True);
1437         }
1438         else
1439         {
1440           std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
1441           return 1;
1442         }
1443       }
1444       else if (aShapeA.ShapeType() == TopAbs_EDGE)
1445       {
1446         if (aShapes.Extent() != 2)
1447         {
1448           std::cerr << "Error: wrong number of selected shapes.\n";
1449           return 1;
1450         }
1451
1452         const TopoDS_Shape& aShapeB = aShapes.Last();
1453         if (aShapeB.ShapeType() != TopAbs_VERTEX)
1454         {
1455           std::cerr << "Syntax error: Together with edge should be vertex.\n";
1456           return 1;
1457         }
1458
1459         // Check that the vertex aShapeB is not on the edge
1460         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1461         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1462
1463         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1464         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1465         {
1466           // The vertex is on the edge
1467           std::cout<<" vplane: error point is on the edge\n";
1468           return 1;
1469         }
1470
1471         gp_Pnt B = BRep_Tool::Pnt(aVertB);
1472         TopoDS_Vertex aVAa, aVAb;
1473         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1474         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1475         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1476         GC_MakePlane MkPlane (B,Aa,Ab);
1477         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1478         Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1479         GetMapOfAIS().Bind (anAISPlane ,aName);
1480         TheAISContext()->Display (anAISPlane, Standard_True);
1481       }
1482       else if (aShapeA.ShapeType() == TopAbs_FACE)
1483       {
1484         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1485         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1486         if (aSurface.GetType()==GeomAbs_Plane)
1487         {
1488           gp_Pln aPlane = aSurface.Plane();
1489           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1490           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1491           GetMapOfAIS().Bind (anAISPlane, aName);
1492           TheAISContext()->Display (anAISPlane, Standard_True);
1493         }
1494         else
1495         {
1496           std::cout<<" vplane: error\n";
1497           return 1;
1498         }
1499       }
1500       else
1501       {
1502         std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
1503         return 1;
1504       }
1505     }
1506
1507     // Function vPlanePara
1508     // ===================
1509     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1510     else if (!strcasecmp(argv[0], "vplanepara"))
1511     {
1512       if (aShapes.Extent() != 2)
1513       {
1514         std::cerr << "Error: Wrong number of selected shapes.\n";
1515         return 1;
1516       }
1517
1518       const TopoDS_Shape* aShapeA = &aShapes.First();
1519       const TopoDS_Shape* aShapeB = &aShapes.Last();
1520       if (aShapeA->ShapeType() != TopAbs_VERTEX)
1521       {
1522         std::swap (aShapeA, aShapeB);
1523       }
1524
1525       if (!(aShapeA->ShapeType() == TopAbs_VERTEX
1526          && aShapeB->ShapeType() == TopAbs_FACE))
1527       {
1528         std::cerr << "Syntax error: you should select face and vertex.\n";
1529         return 1;
1530       }
1531
1532       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(*aShapeA));
1533
1534       TopoDS_Face aFace = TopoDS::Face(*aShapeB);
1535       BRepAdaptor_Surface aSurface (aFace, Standard_False);
1536       if (aSurface.GetType() == GeomAbs_Plane)
1537       {
1538         gp_Pln aPlane = aSurface.Plane();
1539         // Construct a plane parallel to aGeomPlane through A
1540         aPlane.SetLocation(A);
1541         Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1542         Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1543         GetMapOfAIS().Bind (aAISPlane ,aName);
1544         TheAISContext()->Display (aAISPlane, Standard_True);
1545       }
1546       else
1547       {
1548         std::cerr << "Error: Builded surface is not a plane.\n";
1549         return 1;
1550       }
1551     }
1552
1553     // Function vplaneortho
1554     // ====================
1555     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1556     else
1557     {
1558       if (aShapes.Extent() != 2)
1559       {
1560         std::cerr << "Error: wrong number of selected shapes.\n";
1561         return 1;
1562       }
1563
1564       const TopoDS_Shape* aShapeA = &aShapes.First();
1565       const TopoDS_Shape* aShapeB = &aShapes.Last();
1566
1567       if (aShapeA->ShapeType() != TopAbs_EDGE)
1568       {
1569         std::swap (aShapeA, aShapeB);
1570       }
1571
1572       if (!(aShapeA->ShapeType() == TopAbs_EDGE
1573          && aShapeB->ShapeType() == TopAbs_FACE))
1574       {
1575         std::cerr << "Error: you should select edge and face.\n";
1576         return 1;
1577       }
1578
1579       // Construction of plane
1580       TopoDS_Edge anEdgeA = TopoDS::Edge(*aShapeA);
1581       TopoDS_Vertex aVAa, aVAb;
1582       TopExp::Vertices(anEdgeA, aVAa, aVAb);
1583       gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1584       gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1585       gp_Vec ab (Aa,Ab);
1586
1587       gp_Dir Dab (ab);
1588       // Creation of rotation axis
1589       gp_Ax1 aRotAxis (Aa,Dab);
1590
1591       TopoDS_Face aFace = TopoDS::Face(*aShapeB);
1592       // The edge must be parallel to the face
1593       BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1594       BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1595       // Compare to heights
1596       if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1597           >Precision::Confusion())
1598       {
1599         // the edge is not parallel to the face
1600         std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1601         return 1;
1602       }
1603       // the edge is OK
1604       BRepAdaptor_Surface aSurface (aFace, Standard_False);
1605       if (aSurface.GetType()==GeomAbs_Plane)
1606       {
1607         gp_Pln aPlane = aSurface.Plane();
1608         // It rotates a half turn round the axis of rotation
1609         aPlane.Rotate(aRotAxis , M_PI/2);
1610
1611         Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1612         // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1613         gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1614         Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1615         GetMapOfAIS().Bind (anAISPlane, aName);
1616         TheAISContext()->Display (anAISPlane, Standard_True);
1617       }
1618       else
1619       {
1620         std::cout<<" vplaneortho: error\n";
1621         return 1;
1622       }
1623     }
1624   }
1625   return 0;
1626 }
1627
1628 //===============================================================================================
1629 //function : VChangePlane
1630 //purpose  :
1631 //===============================================================================================
1632 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1633 {
1634   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1635   if (aContextAIS.IsNull())
1636   {
1637     std::cout << theArgVec[0] << "AIS context is not available.\n";
1638     return 1;
1639   }
1640
1641   if (theArgsNb < 3 || theArgsNb > 11)
1642   {
1643     std::cerr << theArgVec[0] 
1644               << ": incorrect number of command arguments.\n"
1645               << "Type help for more information.\n";
1646     return 1;
1647   }
1648
1649   TCollection_AsciiString aName (theArgVec[1]);
1650
1651   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1652     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1653     : NULL;
1654
1655   if ( aPlane.IsNull() )
1656   {
1657     std::cout << theArgVec[0] 
1658               << ": there is no interactive plane with the given name."
1659               << "Type help for more information.\n";
1660     return 1;
1661   }
1662
1663   Standard_Real aCenterX = aPlane->Center().X();
1664   Standard_Real aCenterY = aPlane->Center().Y();
1665   Standard_Real aCenterZ = aPlane->Center().Z();
1666
1667   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1668   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1669   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1670
1671   Standard_Real aSizeX = 0.0;
1672   Standard_Real aSizeY = 0.0;
1673   aPlane->Size (aSizeX, aSizeY);
1674   Standard_Boolean isUpdate = Standard_True;
1675
1676   TCollection_AsciiString aPName, aPValue;
1677   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1678   {
1679     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1680     TCollection_AsciiString anArgCase = anArg;
1681     anArgCase.UpperCase();
1682     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1683     {
1684       aPName.UpperCase();
1685       if (aPName.IsEqual ("X"))
1686       {
1687         aCenterX = aPValue.RealValue();
1688       }
1689       else if (aPName.IsEqual ("Y"))
1690       {
1691         aCenterY = aPValue.RealValue();
1692       }
1693       else if (aPName.IsEqual ("Z"))
1694       {
1695         aCenterZ = aPValue.RealValue();
1696       }
1697       else if (aPName.IsEqual ("DX"))
1698       {
1699         aDirX = aPValue.RealValue();
1700       }
1701       else if (aPName.IsEqual ("DY"))
1702       {
1703         aDirY = aPValue.RealValue();
1704       }
1705       else if (aPName.IsEqual ("DZ"))
1706       {
1707         aDirZ = aPValue.RealValue();
1708       }
1709       else if (aPName.IsEqual ("SX"))
1710       {
1711         aSizeX = aPValue.RealValue();
1712       }
1713       else if (aPName.IsEqual ("SY"))
1714       {
1715         aSizeY = aPValue.RealValue();
1716       }
1717     }
1718     else if (anArg.IsEqual ("NOUPDATE"))
1719     {
1720       isUpdate = Standard_False;
1721     }
1722   }
1723
1724   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1725   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1726   aPlane->SetCenter (aCenterPnt);
1727   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1728   aPlane->SetSize (aSizeX, aSizeY);
1729
1730   aContextAIS->Update (aPlane, isUpdate);
1731
1732   return 0;
1733 }
1734
1735 //==============================================================================
1736 // Fonction  vline
1737 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1738 //==============================================================================
1739
1740 //==============================================================================
1741 //function : VLineBuilder
1742 //purpose  : Build an AIS_Line
1743 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1744 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1745 //==============================================================================
1746 #include <Geom_CartesianPoint.hxx>
1747 #include <AIS_Line.hxx>
1748
1749
1750 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1751 {
1752   // Verifications
1753   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct \n";return 1; }
1754
1755   // On recupere les parametres
1756   Handle(AIS_InteractiveObject) theShapeA;
1757   Handle(AIS_InteractiveObject) theShapeB;
1758
1759   // Parametres: AIS_Point AIS_Point
1760   // ===============================
1761   if (argc==4) {
1762     theShapeA=
1763       Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[2]));
1764     // On verifie que c'est bien une AIS_Point
1765     if (!theShapeA.IsNull() &&
1766       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1767         // on recupere le deuxieme AIS_Point
1768         theShapeB=
1769           Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(argv[3]));
1770         if (theShapeA.IsNull() ||
1771           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1772         {
1773           di <<"vline error: wrong type of 2de argument.\n";
1774           return 1;
1775         }
1776       }
1777     else {di <<"vline error: wrong type of 1st argument.\n";return 1; }
1778     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1779     Handle(AIS_Point) theAISPointA= Handle(AIS_Point)::DownCast (theShapeA);
1780     Handle(AIS_Point) theAISPointB= Handle(AIS_Point)::DownCast (theShapeB);
1781
1782     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1783     Handle(Geom_CartesianPoint ) myCartPointA= Handle(Geom_CartesianPoint)::DownCast (myGeomPointBA);
1784     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1785
1786     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1787     Handle(Geom_CartesianPoint ) myCartPointB= Handle(Geom_CartesianPoint)::DownCast (myGeomPointB);
1788     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1789
1790     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1791       // B=A
1792       di<<"vline error: same points\n";return 1;
1793     }
1794     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1795     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1796     GetMapOfAIS().Bind(theAISLine,argv[1] );
1797     TheAISContext()->Display (theAISLine, Standard_True);
1798
1799   }
1800
1801   // Parametres 6 Reals
1802   // ==================
1803
1804   else if (argc==8) {
1805     // On verifie que les deux points ne sont pas confondus
1806
1807     Standard_Real coord[6];
1808     for(Standard_Integer i=0;i<=2;i++){
1809       coord[i]=Draw::Atof(argv[2+i]);
1810       coord[i+3]=Draw::Atof(argv[5+i]);
1811     }
1812
1813     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1814     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1815
1816     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1817     GetMapOfAIS().Bind(theAISLine,argv[1] );
1818     TheAISContext()->Display (theAISLine, Standard_True);
1819
1820   }
1821
1822   // Pas de parametres: Selection dans le viewer.
1823   // ============================================
1824
1825   else
1826   {
1827     TopTools_ListOfShape aShapes;
1828     ViewerTest::GetSelectedShapes (aShapes);
1829     if (aShapes.Extent() != 2)
1830     {
1831       std::cerr << "Error: wrong number of selected shapes.\n";
1832       return 1;
1833     }
1834
1835     const TopoDS_Shape& aShapeA = aShapes.First();
1836     const TopoDS_Shape& aShapeB = aShapes.Last();
1837
1838     if (!(aShapeA.ShapeType() == TopAbs_VERTEX
1839        && aShapeB.ShapeType() == TopAbs_VERTEX))
1840     {
1841       std::cerr << "Error: you should select two different vertex.\n";
1842       return 1;
1843     }
1844
1845     // Construction de la line
1846     gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
1847     gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
1848
1849     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1850     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1851
1852     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1853     GetMapOfAIS().Bind(theAISLine,argv[1] );
1854     TheAISContext()->Display (theAISLine, Standard_True);
1855   }
1856
1857   return 0;
1858 }
1859
1860 //==============================================================================
1861 // class   : FilledCircle
1862 // purpose : creates filled circle based on AIS_InteractiveObject 
1863 //           and Geom_Circle.
1864 //           This class is used to check method Matches() of class 
1865 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1866 //           because none of AIS classes provides creation of 
1867 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1868 //           (look method ComputeSelection() )
1869 //============================================================================== 
1870
1871 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1872 {
1873   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
1874   gp_Circ aCirc(anAxes, theRadius);
1875   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
1876   return aCircle;
1877 }
1878
1879 class FilledCircle : public AIS_InteractiveObject 
1880 {
1881 public:
1882     // CASCADE RTTI
1883     DEFINE_STANDARD_RTTI_INLINE(FilledCircle,AIS_InteractiveObject); 
1884
1885     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1886     FilledCircle(Handle(Geom_Circle) theCircle);
1887
1888 private:
1889     TopoDS_Face ComputeFace();
1890
1891     // Virtual methods implementation
1892     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1893                   const Handle(Prs3d_Presentation)& thePresentation,
1894                   const Standard_Integer theMode) Standard_OVERRIDE;
1895
1896     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1897                            const Standard_Integer theMode) Standard_OVERRIDE;
1898
1899 protected:
1900     Handle(Geom_Circle) myCircle;
1901     Standard_Boolean myFilledStatus;
1902
1903 }; 
1904
1905
1906 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1907 {
1908   myCircle = CreateCircle(theCenter, theRadius);
1909   myFilledStatus = Standard_True;
1910 }
1911
1912 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1913 {
1914   myCircle = theCircle;
1915   myFilledStatus = Standard_True;
1916 }
1917
1918 TopoDS_Face FilledCircle::ComputeFace() 
1919 {
1920   // Create edge from myCircle 
1921   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1922   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1923
1924   // Create wire from anEdge 
1925   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1926   TopoDS_Wire aWire = aWireMaker.Wire();
1927
1928   // Create face from aWire
1929   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1930   TopoDS_Face aFace = aFaceMaker.Face();
1931
1932   return aFace;
1933 }
1934
1935 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
1936                            const Handle(Prs3d_Presentation) &thePresentation, 
1937                            const Standard_Integer theMode) 
1938 {
1939   thePresentation->Clear();
1940
1941   TopoDS_Face aFace = ComputeFace();
1942
1943   if (aFace.IsNull()) return;
1944   if (theMode != 0) return;
1945
1946   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
1947 }
1948
1949 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
1950                                     const Standard_Integer /*theMode*/)
1951 {
1952   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
1953   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
1954       myCircle, myFilledStatus);
1955   theSelection->Add(aSensitiveCircle);
1956 }
1957
1958 //==============================================================================
1959 // Fonction  vcircle
1960 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
1961 //==============================================================================
1962
1963 //==============================================================================
1964 //function : VCircleBuilder
1965 //purpose  : Build an AIS_Circle
1966 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
1967 //                              PointName PointName PointName IsFilled
1968 //==============================================================================
1969
1970 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
1971                     TCollection_AsciiString theName, 
1972                     Standard_Boolean isFilled) 
1973 {
1974   Handle(AIS_InteractiveObject) aCircle;
1975   if (isFilled) 
1976   {
1977     aCircle = new FilledCircle(theGeomCircle);
1978   }
1979   else
1980   {
1981     aCircle = new AIS_Circle(theGeomCircle);
1982     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
1983   }
1984
1985   // Check if there is an object with given name
1986   // and remove it from context
1987   if (GetMapOfAIS().IsBound2(theName)) 
1988   {
1989     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(theName);
1990     Handle(AIS_InteractiveObject) anInterObj = 
1991          Handle(AIS_InteractiveObject)::DownCast(anObj);
1992     TheAISContext()->Remove(anInterObj, Standard_False);
1993     GetMapOfAIS().UnBind2(theName);
1994    }
1995
1996    // Bind the circle to its name
1997    GetMapOfAIS().Bind(aCircle, theName);
1998
1999    // Display the circle
2000    TheAISContext()->Display (aCircle, Standard_True);
2001   
2002 }
2003
2004 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2005 {
2006   // Verification of the arguments
2007   if (argc>6 || argc<2) 
2008   { 
2009     std::cout << "vcircle error: expect 4 arguments.\n"; 
2010     return 1; // TCL_ERROR 
2011   }
2012
2013   // There are all arguments
2014   if (argc == 6) 
2015   {
2016     // Get arguments
2017     TCollection_AsciiString aName(argv[1]);
2018     Standard_Boolean isFilled = Draw::Atoi(argv[5]) != 0;
2019
2020     Handle(AIS_InteractiveObject) theShapeA;
2021     Handle(AIS_InteractiveObject) theShapeB;
2022
2023     theShapeA =
2024       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[2]));
2025     theShapeB =
2026       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[3]));
2027
2028
2029     // Arguments: AIS_Point AIS_Point AIS_Point
2030     // ========================================
2031     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2032       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2033     {
2034       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2035       {
2036         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2037         return 1; // TCL_ERROR 
2038       }
2039       // The third object must be a point
2040       Handle(AIS_InteractiveObject) theShapeC =
2041         Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(argv[4]));
2042       if (theShapeC.IsNull() ||
2043         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2044       {
2045         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2046         return 1; // TCL_ERROR 
2047       }
2048         // tag
2049         // Verify that the three points are different
2050         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2051         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2052         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2053         
2054         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2055         Handle(Geom_CartesianPoint) myCartPointA = 
2056           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2057
2058         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2059         Handle(Geom_CartesianPoint) myCartPointB =
2060           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2061
2062         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2063         Handle(Geom_CartesianPoint) myCartPointC =
2064           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2065
2066         // Test A=B
2067         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2068             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2069             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2070         {
2071           std::cout << "vcircle error: Same points.\n"; 
2072           return 1; // TCL_ERROR 
2073         }
2074         // Test A=C
2075         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2076             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2077             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2078         {
2079           std::cout << "vcircle error: Same points.\n"; 
2080           return 1; // TCL_ERROR 
2081         }
2082         // Test B=C
2083         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2084             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2085             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2086         {
2087           std::cout << "vcircle error: Same points.\n"; 
2088           return 1;// TCL_ERROR 
2089         }
2090         // Construction of the circle
2091         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2092           myCartPointB->Pnt(), myCartPointC->Pnt() );
2093         Handle (Geom_Circle) theGeomCircle;
2094         try 
2095         {
2096           theGeomCircle = Cir.Value();
2097         }
2098         catch (StdFail_NotDone)
2099         {
2100           std::cout << "vcircle error: can't create circle\n";
2101           return -1; // TCL_ERROR
2102         }
2103         
2104         DisplayCircle(theGeomCircle, aName, isFilled);
2105     }
2106
2107     // Arguments: AIS_Plane AIS_Point Real
2108     // ===================================
2109     else if (theShapeA->Type() == AIS_KOI_Datum && 
2110       theShapeA->Signature() == 7 ) 
2111     {
2112       if (theShapeB->Type() != AIS_KOI_Datum || 
2113         theShapeB->Signature() != 1 ) 
2114       {
2115         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2116         return 1; // TCL_ERROR 
2117       }
2118       // Check that the radius is >= 0
2119       if (Draw::Atof(argv[4]) <= 0 ) 
2120       {
2121         std::cout << "vcircle error: the radius must be >=0.\n"; 
2122         return 1; // TCL_ERROR 
2123       }
2124
2125       // Recover the normal to the plane
2126       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2127       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2128
2129       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2130       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2131       Handle(Geom_CartesianPoint) myCartPointB = 
2132         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2133
2134       gp_Pln mygpPlane = myGeomPlane->Pln();
2135       gp_Ax1 thegpAxe = mygpPlane.Axis();
2136       gp_Dir theDir = thegpAxe.Direction();
2137       gp_Pnt theCenter = myCartPointB->Pnt();
2138       Standard_Real TheR = Draw::Atof(argv[4]);
2139       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2140       Handle (Geom_Circle) theGeomCircle;
2141       try 
2142       {
2143         theGeomCircle = Cir.Value();
2144       }
2145       catch (StdFail_NotDone)
2146       {
2147         std::cout << "vcircle error: can't create circle\n";
2148         return -1; // TCL_ERROR
2149       }
2150
2151       DisplayCircle(theGeomCircle, aName, isFilled);
2152
2153     }
2154
2155     // Error
2156     else
2157     {
2158       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2159       return 1; // TCL_ERROR 
2160     }
2161
2162   }
2163   // No arguments: selection in the viewer
2164   // =========================================
2165   else 
2166   {
2167     // Get the name of the circle 
2168     TCollection_AsciiString aName(argv[1]);
2169
2170     TopTools_ListOfShape aShapes;
2171     ViewerTest::GetSelectedShapes (aShapes);
2172     if (aShapes.Extent() != 3 && aShapes.Extent() != 2)
2173     {
2174       std::cerr << "Error: Wrong number of selected shapes.\n";
2175       return 1;
2176     }
2177
2178     const TopoDS_Shape& aShapeA = aShapes.First();
2179     if (aShapeA.ShapeType() == TopAbs_VERTEX ) 
2180     {
2181       if (aShapes.Extent() != 3)
2182       {
2183         std::cerr << "Error: wrong number of selected shapes.\n";
2184         return 1;
2185       }
2186
2187       TopTools_ListOfShape::Iterator anIter (aShapes);
2188
2189       anIter.Next();
2190       const TopoDS_Shape& aShapeB = anIter.Value();
2191
2192       anIter.Next();
2193       const TopoDS_Shape& aShapeC = anIter.Value();
2194       
2195       // Get isFilled
2196       Standard_Boolean isFilled;
2197       std::cout << "Enter filled status (0 or 1)\n";
2198       cin >> isFilled;
2199
2200       // Construction of the circle
2201       gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
2202       gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
2203       gp_Pnt C = BRep_Tool::Pnt (TopoDS::Vertex (aShapeC));
2204
2205       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2206       Handle (Geom_Circle) theGeomCircle;
2207       try 
2208       {
2209         theGeomCircle = Cir.Value();
2210       }
2211       catch (StdFail_NotDone)
2212       {
2213         std::cout << "vcircle error: can't create circle\n";
2214         return -1; // TCL_ERROR
2215       }
2216
2217       DisplayCircle(theGeomCircle, aName, isFilled);
2218
2219     }
2220     else if (aShapeA.ShapeType() == TopAbs_FACE)
2221     {
2222       const TopoDS_Shape& aShapeB = aShapes.Last();
2223
2224       // Recover the radius 
2225       Standard_Real theRad;
2226       do 
2227       {
2228         std::cout << " Enter the value of the radius:\n";
2229         cin >> theRad;
2230       } while (theRad <= 0);
2231       
2232       // Get filled status
2233       Standard_Boolean isFilled;
2234       std::cout << "Enter filled status (0 or 1)\n";
2235       cin >> isFilled;
2236
2237       // Recover the normal to the plane. tag
2238       TopoDS_Face myFace = TopoDS::Face(aShapeA);
2239       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2240       gp_Pln myPlane = mySurface.Plane();
2241       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2242       gp_Pln mygpPlane = theGeomPlane->Pln();
2243       gp_Ax1 thegpAxe = mygpPlane.Axis();
2244       gp_Dir theDir = thegpAxe.Direction();
2245
2246       // Recover the center
2247       gp_Pnt theCenter = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
2248
2249       // Construct the circle
2250       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2251       Handle (Geom_Circle) theGeomCircle;
2252       try 
2253       {
2254         theGeomCircle = Cir.Value();
2255       }
2256       catch (StdFail_NotDone)
2257       {
2258         std::cout << "vcircle error: can't create circle\n";
2259         return -1; // TCL_ERROR
2260       }
2261
2262       DisplayCircle(theGeomCircle, aName, isFilled);
2263     }
2264     else
2265     {
2266       std::cerr << "Error: You should select face and vertex or three vertices.\n";
2267       return 1;
2268     }
2269   }
2270
2271   return 0;
2272 }
2273
2274 //=======================================================================
2275 //function : VDrawText
2276 //purpose  :
2277 //=======================================================================
2278 static int VDrawText (Draw_Interpretor& theDI,
2279                       Standard_Integer  theArgsNb,
2280                       const char**      theArgVec)
2281 {
2282   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2283   if (theArgsNb < 3)
2284   {
2285     std::cout << "Error: wrong number of arguments! See usage:\n";
2286     theDI.PrintHelp (theArgVec[0]);
2287     return 1;
2288   }
2289   else if (aContext.IsNull())
2290   {
2291     std::cout << "Error: no active view!\n";
2292     return 1;
2293   }
2294
2295   Standard_Integer           anArgIt = 1;
2296   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2297   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2298   Handle(AIS_TextLabel)      aTextPrs;
2299   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2300
2301   Standard_Boolean isNewPrs = Standard_False;
2302   if (GetMapOfAIS().IsBound2 (aName))
2303   {
2304     aTextPrs = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2305   }
2306
2307   if (aTextPrs.IsNull())
2308   {
2309     isNewPrs = Standard_True;
2310     aTextPrs = new AIS_TextLabel();
2311     aTextPrs->SetFont ("Courier");
2312   }
2313
2314   aTextPrs->SetText (aText);
2315
2316   Handle(Graphic3d_TransformPers) aTrsfPers;
2317   Aspect_TypeOfDisplayText aDisplayType = Aspect_TODT_NORMAL;
2318
2319   Standard_Boolean aHasPlane = Standard_False;
2320   gp_Dir           aNormal;
2321   gp_Dir           aDirection;
2322   gp_Pnt           aPos;
2323
2324   for (; anArgIt < theArgsNb; ++anArgIt)
2325   {
2326     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2327     aParam.LowerCase();
2328
2329     if (anAutoUpdater.parseRedrawMode (aParam))
2330     {
2331       continue;
2332     }
2333     else if (aParam == "-pos"
2334           || aParam == "-position")
2335     {
2336       if (anArgIt + 3 >= theArgsNb)
2337       {
2338         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2339         return 1;
2340       }
2341
2342       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2343       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2344       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2345       aTextPrs->SetPosition (aPos);
2346     }
2347     else if (aParam == "-color")
2348     {
2349       if (anArgIt + 1 >= theArgsNb)
2350       {
2351         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2352         return 1;
2353       }
2354
2355       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2356       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2357       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2358       {
2359         anArgIt += 1;
2360         aTextPrs->SetColor (aNameOfColor);
2361         continue;
2362       }
2363       else if (anArgIt + 3 >= theArgsNb)
2364       {
2365         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2366         return 1;
2367       }
2368
2369       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2370       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2371       if (!aColor.IsRealValue()
2372        || !aGreen.IsRealValue()
2373        || !aBlue.IsRealValue())
2374       {
2375         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2376         return 1;
2377       }
2378
2379       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2380                                    aGreen.RealValue(),
2381                                    aBlue.RealValue());
2382
2383       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2384       anArgIt += 3;
2385     }
2386     else if (aParam == "-halign")
2387     {
2388       if (++anArgIt >= theArgsNb)
2389       {
2390         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2391         return 1;
2392       }
2393
2394       TCollection_AsciiString aType (theArgVec[anArgIt]);
2395       aType.LowerCase();
2396       if (aType == "left")
2397       {
2398         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2399       }
2400       else if (aType == "center")
2401       {
2402         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2403       }
2404       else if (aType == "right")
2405       {
2406         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2407       }
2408       else
2409       {
2410         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2411         return 1;
2412       }
2413     }
2414     else if (aParam == "-valign")
2415     {
2416       if (++anArgIt >= theArgsNb)
2417       {
2418         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2419         return 1;
2420       }
2421
2422       TCollection_AsciiString aType (theArgVec[anArgIt]);
2423       aType.LowerCase();
2424       if (aType == "top")
2425       {
2426         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2427       }
2428       else if (aType == "center")
2429       {
2430         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2431       }
2432       else if (aType == "bottom")
2433       {
2434         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2435       }
2436       else if (aType == "topfirstline")
2437       {
2438         aTextPrs->SetVJustification (Graphic3d_VTA_TOPFIRSTLINE);
2439       }
2440       else
2441       {
2442         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2443         return 1;
2444       }
2445     }
2446     else if (aParam == "-angle")
2447     {
2448       if (++anArgIt >= theArgsNb)
2449       {
2450         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2451         return 1;
2452       }
2453
2454       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2455     }
2456     else if (aParam == "-zoom")
2457     {
2458       if (++anArgIt >= theArgsNb)
2459       {
2460         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2461         return 1;
2462       }
2463
2464       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2465     }
2466     else if (aParam == "-height")
2467     {
2468       if (++anArgIt >= theArgsNb)
2469       {
2470         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2471         return 1;
2472       }
2473
2474       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2475     }
2476     else if (aParam == "-aspect")
2477     {
2478       if (++anArgIt >= theArgsNb)
2479       {
2480         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2481         return 1;
2482       }
2483
2484       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2485       anOption.LowerCase();
2486       if (anOption.IsEqual ("regular"))
2487       {
2488         aTextPrs->SetFontAspect (Font_FA_Regular);
2489       }
2490       else if (anOption.IsEqual ("bold"))
2491       {
2492         aTextPrs->SetFontAspect (Font_FA_Bold);
2493       }
2494       else if (anOption.IsEqual ("italic"))
2495       {
2496         aTextPrs->SetFontAspect (Font_FA_Italic);
2497       }
2498       else if (anOption.IsEqual ("bolditalic"))
2499       {
2500         aTextPrs->SetFontAspect (Font_FA_BoldItalic);
2501       }
2502     }
2503     else if (aParam == "-font")
2504     {
2505       if (++anArgIt >= theArgsNb)
2506       {
2507         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2508         return 1;
2509       }
2510
2511       aTextPrs->SetFont (theArgVec[anArgIt]);
2512     }
2513     else if (aParam == "-plane")
2514     {
2515       if (anArgIt + 6 >= theArgsNb)
2516       {
2517         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2518         return 1;
2519       }
2520
2521       Standard_Real aX = Draw::Atof (theArgVec[++anArgIt]);
2522       Standard_Real aY = Draw::Atof (theArgVec[++anArgIt]);
2523       Standard_Real aZ = Draw::Atof (theArgVec[++anArgIt]);
2524       aNormal.SetCoord (aX, aY, aZ);
2525
2526       aX = Draw::Atof (theArgVec[++anArgIt]);
2527       aY = Draw::Atof (theArgVec[++anArgIt]);
2528       aZ = Draw::Atof (theArgVec[++anArgIt]);
2529       aDirection.SetCoord (aX, aY, aZ);
2530
2531       aHasPlane = Standard_True;
2532     }
2533     else if (aParam == "-flipping")
2534     {
2535       aTextPrs->SetFlipping (Standard_True);
2536     }
2537     else if (aParam == "-disptype"
2538           || aParam == "-displaytype")
2539     {
2540       if (++anArgIt >= theArgsNb)
2541       {
2542         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2543         return 1;
2544       }
2545       TCollection_AsciiString aType (theArgVec[anArgIt]);
2546       aType.LowerCase();
2547       if (aType == "subtitle")
2548         aDisplayType = Aspect_TODT_SUBTITLE;
2549       else if (aType == "decal")
2550         aDisplayType = Aspect_TODT_DEKALE;
2551       else if (aType == "blend")
2552         aDisplayType = Aspect_TODT_BLEND;
2553       else if (aType == "dimension")
2554         aDisplayType = Aspect_TODT_DIMENSION;
2555       else if (aType == "normal")
2556         aDisplayType = Aspect_TODT_NORMAL;
2557       else if (aType == "shadow")
2558         aDisplayType = Aspect_TODT_SHADOW;
2559       else
2560       {
2561         std::cout << "Error: wrong display type '" << aType << "'.\n";
2562         return 1;
2563       }
2564     }
2565     else if (aParam == "-subcolor"
2566           || aParam == "-subtitlecolor")
2567     {
2568       if (anArgIt + 1 >= theArgsNb)
2569       {
2570         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2571         return 1;
2572       }
2573
2574       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2575       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2576       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2577       {
2578         anArgIt += 1;
2579         aTextPrs->SetColorSubTitle (aNameOfColor);
2580         continue;
2581       }
2582       else if (anArgIt + 3 >= theArgsNb)
2583       {
2584         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2585         return 1;
2586       }
2587
2588       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2589       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2590       if (!aColor.IsRealValue()
2591        || !aGreen.IsRealValue()
2592        || !aBlue.IsRealValue())
2593       {
2594         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2595         return 1;
2596       }
2597
2598       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2599                                    aGreen.RealValue(),
2600                                    aBlue.RealValue());
2601
2602       aTextPrs->SetColorSubTitle (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2603       anArgIt += 3;
2604     }
2605     else if (aParam == "-2d")
2606     {
2607       aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_2d);
2608     }
2609     else if (aParam == "-trsfperspos"
2610           || aParam == "-perspos")
2611     {
2612       if (anArgIt + 2 >= theArgsNb)
2613       {
2614         std::cerr << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2615         return 1;
2616       }
2617
2618       TCollection_AsciiString aX (theArgVec[++anArgIt]);
2619       TCollection_AsciiString aY (theArgVec[++anArgIt]);
2620       TCollection_AsciiString aZ = "0";
2621       if (!aX.IsIntegerValue()
2622        || !aY.IsIntegerValue())
2623       {
2624         std::cerr << "Error: wrong syntax at '" << aParam << "'.\n";
2625         return 1;
2626       }
2627       if (anArgIt + 1 < theArgsNb)
2628       {
2629         TCollection_AsciiString aTemp = theArgVec[anArgIt + 1];
2630         if (aTemp.IsIntegerValue())
2631         {
2632           aZ = aTemp;
2633           ++anArgIt;
2634         }
2635       }
2636
2637       aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (Graphic3d_TMF_2d, gp_Pnt (aX.IntegerValue(), aY.IntegerValue(), aZ.IntegerValue()));
2638     }
2639     else
2640     {
2641       std::cout << "Error: unknown argument '" << aParam << "'\n";
2642       return 1;
2643     }
2644   }
2645
2646   if (aHasPlane)
2647   {
2648     aTextPrs->SetOrientation3D (gp_Ax2 (aPos, aNormal, aDirection));
2649   }
2650
2651   aTextPrs->SetDisplayType (aDisplayType);
2652
2653   if (!aTrsfPers.IsNull())
2654   {
2655     aContext->SetTransformPersistence (aTextPrs, aTrsfPers);
2656     aTextPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
2657     if (aTextPrs->Position().Z() != 0)
2658     {
2659       aTextPrs->SetPosition (gp_Pnt(aTextPrs->Position().X(), aTextPrs->Position().Y(), 0));
2660     }
2661   }
2662   else if (!aTextPrs->TransformPersistence().IsNull())
2663   {
2664     aContext->SetTransformPersistence (aTextPrs, Handle(Graphic3d_TransformPers)());
2665   }
2666
2667   if (isNewPrs)
2668   {
2669     ViewerTest::Display (aName, aTextPrs, Standard_False);
2670   }
2671   else
2672   {
2673     aContext->Redisplay (aTextPrs, Standard_False, Standard_True);
2674   }
2675   return 0;
2676 }
2677
2678 #include <math.h>
2679 #include <gp_Pnt.hxx>
2680 #include <Graphic3d_ArrayOfPoints.hxx>
2681 #include <Graphic3d_ArrayOfPrimitives.hxx>
2682 #include <Graphic3d_ArrayOfTriangles.hxx>
2683 #include <Poly_Array1OfTriangle.hxx>
2684 #include <Poly_Triangle.hxx>
2685 #include <Poly_Triangulation.hxx>
2686 #include <TColgp_Array1OfPnt.hxx>
2687 #include <TShort_Array1OfShortReal.hxx>
2688 #include <TShort_HArray1OfShortReal.hxx>
2689
2690 #include <AIS_Triangulation.hxx>
2691 #include <StdPrs_ToolTriangulatedShape.hxx>
2692 #include <Poly_Connect.hxx>
2693 #include <TColgp_Array1OfDir.hxx>
2694 #include <Graphic3d_GraphicDriver.hxx>
2695
2696 #include <TColStd_Array1OfInteger.hxx>
2697 #include <TColStd_HArray1OfInteger.hxx>
2698 #include <Prs3d_ShadingAspect.hxx>
2699 #include <Graphic3d_MaterialAspect.hxx>
2700 #include <Graphic3d_AspectFillArea3d.hxx>
2701
2702 #include <BRepPrimAPI_MakeCylinder.hxx>
2703 #include <TopoDS_Shape.hxx>
2704 #include <TopExp_Explorer.hxx>
2705 #include <TopAbs.hxx>
2706 #include <StdSelect_ShapeTypeFilter.hxx>
2707 #include <AIS_InteractiveObject.hxx>
2708
2709
2710 //===============================================================================================
2711 //function : CalculationOfSphere
2712 //author   : psn
2713 //purpose  : Create a Sphere
2714 //===============================================================================================
2715
2716 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2717                                                   int res ,
2718                                                   double Radius ){
2719   double mRadius = Radius;
2720   double mCenter[3] = {X,Y,Z};
2721   int mThetaResolution;
2722   int mPhiResolution;
2723   double mStartTheta = 0;//StartTheta;
2724   double mEndTheta = 360;//EndTheta;
2725   double mStartPhi = 0;//StartPhi;
2726   double mEndPhi = 180;//EndPhi;
2727   res = res < 4 ? 4 : res;
2728
2729   mThetaResolution = res;
2730   mPhiResolution = res;
2731
2732   int i, j;
2733   int jStart, jEnd, numOffset;
2734   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2735   double startTheta, endTheta, startPhi, endPhi;
2736   int base, numPoles=0, thetaResolution, phiResolution;
2737
2738   int pts[3];
2739   int piece = -1;
2740   int numPieces = 1;
2741   if ( numPieces > mThetaResolution ) {
2742     numPieces = mThetaResolution;
2743   }
2744
2745   int localThetaResolution =  mThetaResolution;
2746   double localStartTheta =  mStartTheta;
2747   double localEndTheta =  mEndTheta;
2748
2749   while ( localEndTheta < localStartTheta ) {
2750     localEndTheta += 360.0;
2751   }
2752
2753   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2754
2755   // Change the ivars based on pieces.
2756   int start, end;
2757   start = piece * localThetaResolution / numPieces;
2758   end = (piece+1) * localThetaResolution / numPieces;
2759   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2760   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2761   localThetaResolution = end - start;
2762
2763   // Create north pole if needed
2764   int number_point = 0;
2765   int number_pointArray = 0;
2766
2767   if ( mStartPhi <= 0.0 ) {
2768     number_pointArray++;
2769     numPoles++;
2770   }
2771   if ( mEndPhi >= 180.0 ) {
2772     number_pointArray++;
2773     numPoles++;
2774   }
2775
2776   // Check data, determine increments, and convert to radians
2777   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2778   startTheta *= M_PI  / 180.0;
2779   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2780   endTheta *= M_PI  / 180.0;
2781
2782
2783   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2784   startPhi *= M_PI  / 180.0;
2785   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2786   endPhi *= M_PI  / 180.0;
2787
2788   phiResolution =  mPhiResolution - numPoles;
2789   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2790   thetaResolution = localThetaResolution;
2791   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2792     ++localThetaResolution;
2793   }
2794   deltaTheta = (endTheta - startTheta) / thetaResolution;
2795
2796   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2797   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2798
2799   // Create intermediate points
2800   for ( i = 0; i < localThetaResolution; i++ ) {
2801     for ( j = jStart; j < jEnd; j++ ) {
2802         number_pointArray++;
2803     }
2804   }
2805
2806   //Generate mesh connectivity
2807   base = phiResolution * localThetaResolution;
2808
2809   int number_triangle = 0 ;
2810   if ( mStartPhi <= 0.0 ) { // around north pole
2811     number_triangle += localThetaResolution;
2812   }
2813
2814   if ( mEndPhi >= 180.0 ) { // around south pole
2815     number_triangle += localThetaResolution;
2816   }
2817
2818   // bands in-between poles
2819   for ( i=0; i < localThetaResolution; i++){
2820     for ( j=0; j < (phiResolution-1); j++){
2821        number_triangle +=2;
2822     }
2823   }
2824
2825   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2826   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2827   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2828
2829   if (  mStartPhi <= 0.0 ){
2830       x[0] =  mCenter[0];
2831       x[1] =  mCenter[1];
2832       x[2] =  mCenter[2] +  mRadius;
2833       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2834   }
2835
2836   // Create south pole if needed
2837   if (  mEndPhi >= 180.0 ){
2838       x[0] =  mCenter[0];
2839       x[1] =  mCenter[1];
2840       x[2] =  mCenter[2] -  mRadius;
2841       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2842   }
2843
2844   number_point = 3;
2845   for ( i=0; i < localThetaResolution; i++){
2846     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2847     for ( j = jStart; j < jEnd; j++){
2848         phi = startPhi + j*deltaPhi;
2849         radius =  mRadius * sin((double)phi);
2850         n[0] = radius * cos((double)theta);
2851         n[1] = radius * sin((double)theta);
2852         n[2] =  mRadius * cos((double)phi);
2853         x[0] = n[0] +  mCenter[0];
2854         x[1] = n[1] +  mCenter[1];
2855         x[2] = n[2] +  mCenter[2];
2856         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2857         number_point++;
2858       }
2859     }
2860
2861   numPoles = 3;
2862   number_triangle = 1;
2863   if ( mStartPhi <= 0.0 ){// around north pole
2864     for (i=0; i < localThetaResolution; i++){
2865         pts[0] = phiResolution*i + numPoles;
2866         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2867         pts[2] = 1;
2868         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2869         number_triangle++;
2870       }
2871     }
2872
2873   if (  mEndPhi >= 180.0 ){ // around south pole
2874     numOffset = phiResolution - 1 + numPoles;
2875     for (i=0; i < localThetaResolution; i++){
2876         pts[0] = phiResolution*i + numOffset;
2877         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2878         pts[1] = numPoles - 1;
2879         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2880         number_triangle++;
2881       }
2882     }
2883
2884   // bands in-between poles
2885
2886   for (i=0; i < localThetaResolution; i++){
2887     for (j=0; j < (phiResolution-1); j++){
2888         pts[0] = phiResolution*i + j + numPoles;
2889         pts[1] = pts[0] + 1;
2890         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2891         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2892         number_triangle++;
2893         pts[1] = pts[2];
2894         pts[2] = pts[1] - 1;
2895         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2896         number_triangle++;
2897       }
2898     }
2899
2900   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2901
2902   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2903
2904   Standard_Integer index[3];
2905   Standard_Real Tol = Precision::Confusion();
2906
2907   gp_Dir Nor;
2908   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2909       gp_XYZ eqPlan(0, 0, 0);
2910       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2911         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2912         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2913         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2914         gp_XYZ vv = v1^v2;
2915         Standard_Real mod = vv.Modulus();
2916         if(mod < Tol) continue;
2917         eqPlan += vv/mod;
2918       }
2919
2920       Standard_Real modmax = eqPlan.Modulus();
2921
2922       if(modmax > Tol)
2923         Nor = gp_Dir(eqPlan);
2924       else
2925         Nor = gp_Dir(0., 0., 1.);
2926       
2927       Standard_Integer k = (i - PointsOfArray.Lower()) * 3;
2928       Normals->SetValue(k + 1, (Standard_ShortReal)Nor.X());
2929       Normals->SetValue(k + 2, (Standard_ShortReal)Nor.Y());
2930       Normals->SetValue(k + 3, (Standard_ShortReal)Nor.Z());
2931   }
2932
2933   delete pc;
2934   polyTriangulation->SetNormals(Normals);
2935
2936   return polyTriangulation;
2937 }
2938
2939 //===============================================================================================
2940 //function : VDrawSphere
2941 //author   : psn
2942 //purpose  : Create an AIS shape.
2943 //===============================================================================================
2944 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2945 {
2946   // check for errors
2947   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2948   if (aContextAIS.IsNull())
2949   {
2950     std::cout << "Call vinit before!\n";
2951     return 1;
2952   }
2953   else if (argc < 3)
2954   {
2955     std::cout << "Use: " << argv[0]
2956               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2957     return 1;
2958   }
2959
2960   // read the arguments
2961   TCollection_AsciiString aShapeName (argv[1]);
2962   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2963   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2964   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2965   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
2966   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
2967   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
2968   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
2969
2970   // remove AIS object with given name from map
2971   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
2972
2973   if (toPrintInfo)
2974     std::cout << "Compute Triangulation...\n";
2975   Handle(AIS_Triangulation) aShape
2976     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
2977                                                   aResolution,
2978                                                   aRadius));
2979   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
2980   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
2981
2982   // stupid initialization of Green color in RGBA space as integer
2983   // probably wrong for big-endian CPUs
2984   const Graphic3d_Vec4ub aColor (0, 255, 0, 0);
2985
2986   // setup colors array per vertex
2987   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
2988   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
2989   {
2990     aColorArray->SetValue (aNodeId, *reinterpret_cast<const Standard_Integer*> (aColor.GetData()));
2991   }
2992   aShape->SetColors (aColorArray);
2993
2994   // show statistics
2995   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2996   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
2997   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
2998   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
2999   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
3000   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
3001   aTotalSize >>= 20; //MB
3002   aNormalsSize >>= 20;
3003   aColorsSize >>= 20;
3004   aTrianglesSize >>= 20;
3005   aPolyConnectSize >>= 20;
3006   if (toPrintInfo)
3007   {
3008     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
3009       << "NumberOfTriangles: " << aNumberTriangles << "\n"
3010       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
3011       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
3012       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
3013       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
3014   }
3015
3016   // Setting material properties, very important for desirable visual result!
3017   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
3018   aMat.SetAmbient  (0.2f);
3019   aMat.SetSpecular (0.5f);
3020   Handle(Graphic3d_AspectFillArea3d) anAspect
3021     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
3022                                       Quantity_NOC_RED,
3023                                       Quantity_NOC_YELLOW,
3024                                       Aspect_TOL_SOLID,
3025                                       1.0,
3026                                       aMat,
3027                                       aMat);
3028   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
3029   if (toShowEdges)
3030   {
3031     anAspect->SetEdgeOn();
3032   }
3033   else
3034   {
3035     anAspect->SetEdgeOff();
3036   }
3037   aShAsp->SetAspect (anAspect);
3038   aShape->Attributes()->SetShadingAspect (aShAsp);
3039
3040   VDisplayAISObject (aShapeName, aShape);
3041   return 0;
3042 }
3043
3044 //=============================================================================
3045 //function : VComputeHLR
3046 //purpose  :
3047 //=============================================================================
3048
3049 static int VComputeHLR (Draw_Interpretor& di,
3050                         Standard_Integer argc,
3051                         const char** argv)
3052 {
3053   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext ();
3054
3055   if (aContextAIS.IsNull ())
3056   {
3057     di << "Please call vinit before\n";
3058     return 1;
3059   }
3060
3061   if ( argc != 3 &&  argc != 12 )
3062   {
3063     di << "Usage: " << argv[0] << " ShapeName HlrName "
3064        << "[ eye_x eye_y eye_z dir_x dir_y dir_z upx upy upz ]\n"
3065        << "                    ShapeName - name of the initial shape\n"
3066        << "                    HlrName - result hlr object from initial shape\n"
3067        << "                    eye, dir are eye position and look direction\n"
3068        << "                    up is the look up direction vector\n"
3069        << "                    Use vtop to see projected hlr shape\n";
3070     return 1;
3071   }
3072
3073   // shape and new object name
3074   TCollection_AsciiString aShapeName (argv[1]);
3075   TCollection_AsciiString aHlrName (argv[2]);
3076
3077   TopoDS_Shape aSh = DBRep::Get (argv[1]);
3078   if (aSh.IsNull()) 
3079   {
3080     BRep_Builder aBrepBuilder;
3081     BRepTools::Read (aSh, argv[1], aBrepBuilder);
3082     if (aSh.IsNull ())
3083     {
3084       di << "No shape with name " << argv[1] << " found\n";
3085       return 1;
3086     }
3087   }
3088
3089   if (GetMapOfAIS ().IsBound2 (aHlrName))
3090   {
3091     di << "Presentable object with name " << argv[2] << " already exists\n";
3092     return 1;
3093   }
3094
3095   Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3096   HLRBRep_PolyHLRToShape aHLRToShape;
3097
3098   gp_Pnt anEye;
3099   gp_Dir aDir;
3100   gp_Ax2 aProjAx;
3101   if (argc == 9)
3102   {
3103     gp_Dir anUp;
3104
3105     anEye.SetCoord (Draw::Atof (argv[3]), Draw::Atof (argv[4]), Draw::Atof (argv[5]));
3106     aDir.SetCoord (Draw::Atof (argv[6]), Draw::Atof (argv[7]), Draw::Atof (argv[8]));
3107     anUp.SetCoord (Draw::Atof (argv[9]), Draw::Atof (argv[10]), Draw::Atof (argv[11]));
3108     aProjAx.SetLocation (anEye);
3109     aProjAx.SetDirection (aDir);
3110     aProjAx.SetYDirection (anUp);
3111   }
3112   else
3113   {
3114     gp_Dir aRight;
3115
3116     Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
3117     Handle(V3d_View)   aView   = ViewerTest::CurrentView();
3118     Standard_Integer aWidth, aHeight;
3119     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3120     Standard_Real aRightX, aRightY, aRightZ;
3121     aView->Window()->Size (aWidth, aHeight);
3122
3123     aView->ConvertWithProj (aWidth, aHeight/2, 
3124                             aRightX, aRightY, aRightZ,
3125                             aDirX, aDirY, aDirZ);
3126
3127     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3128                             aCentX, aCentY, aCentZ,
3129                             aDirX, aDirY, aDirZ);
3130
3131     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3132     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3133     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3134     aProjAx.SetLocation (anEye);
3135     aProjAx.SetDirection (aDir);
3136     aProjAx.SetXDirection (aRight);
3137   }
3138
3139   HLRAlgo_Projector aProjector (aProjAx);
3140   aPolyAlgo->Projector (aProjector);
3141   aPolyAlgo->Load (aSh);
3142   aPolyAlgo->Update ();
3143
3144   aHLRToShape.Update (aPolyAlgo);
3145
3146   // make hlr shape from input shape
3147   TopoDS_Compound aHlrShape;
3148   BRep_Builder aBuilder;
3149   aBuilder.MakeCompound (aHlrShape);
3150
3151   TopoDS_Shape aCompound = aHLRToShape.VCompound();
3152   if (!aCompound.IsNull ())
3153   {
3154     aBuilder.Add (aHlrShape, aCompound);
3155   }
3156   
3157   // extract visible outlines
3158   aCompound = aHLRToShape.OutLineVCompound();
3159   if (!aCompound.IsNull ())
3160   {
3161     aBuilder.Add (aHlrShape, aCompound);
3162   }
3163
3164   // create an AIS shape and display it
3165   Handle(AIS_Shape) anObject = new AIS_Shape (aHlrShape);
3166   GetMapOfAIS().Bind (anObject, aHlrName);
3167   aContextAIS->Display (anObject, Standard_False);
3168
3169   aContextAIS->UpdateCurrentViewer ();
3170
3171   return 0;
3172 }
3173
3174 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3175 // manipulating and displaying such an array with AIS context
3176
3177 class MyPArrayObject : public AIS_InteractiveObject
3178 {
3179
3180 public:
3181
3182   MyPArrayObject (Handle(TColStd_HArray1OfAsciiString) theArrayDescription,
3183                   Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
3184   {
3185     myArrayDescription = theArrayDescription;
3186     myMarkerAspect = theMarkerAspect;
3187   }
3188
3189   DEFINE_STANDARD_RTTI_INLINE(MyPArrayObject,AIS_InteractiveObject);
3190
3191 private:
3192
3193   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3194                 const Handle(Prs3d_Presentation)& aPresentation,
3195                 const Standard_Integer aMode) Standard_OVERRIDE;
3196
3197   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3198                          const Standard_Integer /*theMode*/) Standard_OVERRIDE;
3199
3200   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3201                           const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3202                           Standard_Integer &theArgIndex,
3203                           Standard_Integer theArgCount,
3204                           Standard_Integer theMaxArgs);
3205
3206 protected:
3207
3208   Handle(TColStd_HArray1OfAsciiString) myArrayDescription;
3209   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3210
3211 };
3212
3213
3214 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3215                               const Handle(Prs3d_Presentation)& aPresentation,
3216                               const Standard_Integer /*aMode*/)
3217 {
3218
3219   // Parsing array description
3220   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3221   Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
3222   hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
3223
3224   Standard_Integer anArgIndex = 0;
3225   Standard_Integer anArgsCount = myArrayDescription->Length();
3226   TCollection_AsciiString anArrayType = myArrayDescription->Value (anArgIndex++);
3227
3228   TCollection_AsciiString aCommand;
3229   while (anArgIndex < anArgsCount)
3230   {
3231     aCommand = myArrayDescription->Value (anArgIndex);
3232     aCommand.LowerCase();
3233
3234     // vertex command
3235     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3236     {
3237       // vertex has a normal or normal with color or texel
3238       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3239         hasNormals = Standard_True;
3240
3241       // vertex has a color
3242       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3243         hasVColors = Standard_True;
3244
3245       // vertex has a texel
3246       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3247         hasTexels = Standard_True;
3248
3249       aVertexNum++;
3250     }
3251     // bound command
3252     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3253     {
3254       // bound has color
3255       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3256         hasBColors = Standard_True;
3257
3258       aBoundNum++;
3259     }
3260     // edge command
3261     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3262     {
3263       aEdgeNum++;
3264     }
3265     // unknown command
3266     else
3267       anArgIndex++;
3268   }
3269
3270   Handle(Graphic3d_ArrayOfPrimitives) anArray;
3271   if (anArrayType == "points")
3272   {
3273     anArray = new Graphic3d_ArrayOfPoints (aVertexNum);
3274   }
3275   else if (anArrayType == "segments")
3276     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
3277   else if (anArrayType == "polylines")
3278     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
3279                                               hasVColors, hasBColors);
3280   else if (anArrayType == "triangles")
3281     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
3282                                               hasVColors, hasTexels);
3283   else if (anArrayType == "trianglefans")
3284     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
3285                                                  hasNormals, hasVColors,
3286                                                  hasBColors, hasTexels);
3287   else if (anArrayType == "trianglestrips")
3288     anArray = new Graphic3d_ArrayOfTriangleStrips (aVertexNum, aBoundNum,
3289                                                    hasNormals, hasVColors,
3290                                                    hasBColors, hasTexels);
3291   else if (anArrayType == "quads")
3292     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
3293                                                 hasNormals, hasVColors,
3294                                                 hasTexels);
3295   else if (anArrayType == "quadstrips")
3296     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
3297                                                      hasNormals, hasVColors,
3298                                                      hasBColors, hasTexels);
3299   else if (anArrayType == "polygons")
3300     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
3301                                              hasNormals, hasVColors, hasBColors,
3302                                              hasTexels);
3303
3304   anArgIndex = 1;
3305   while (anArgIndex < anArgsCount)
3306   {
3307     aCommand = myArrayDescription->Value (anArgIndex);
3308     aCommand.LowerCase();
3309     if (!aCommand.IsAscii())
3310       break;
3311
3312     // vertex command
3313     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, anArgsCount))
3314     {
3315       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3316                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
3317                           myArrayDescription->Value (anArgIndex - 1).RealValue());
3318       const Standard_Integer aVertIndex = anArray->VertexNumber();
3319
3320       // vertex has a normal or normal with color or texel
3321       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
3322         anArray->SetVertexNormal (aVertIndex,
3323                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
3324                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
3325                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
3326       
3327       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3328         anArray->SetVertexColor (aVertIndex,
3329                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
3330                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3331                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3332       
3333       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
3334         anArray->SetVertexTexel (aVertIndex,
3335                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
3336                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
3337     }
3338     // bounds command
3339     else if (CheckInputCommand ("b", myArrayDescription, anArgIndex, 1, anArgsCount))
3340     {
3341       Standard_Integer aVertCount = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3342
3343       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
3344         anArray->AddBound (aVertCount,
3345                            myArrayDescription->Value (anArgIndex - 3).RealValue(),
3346                            myArrayDescription->Value (anArgIndex - 2).RealValue(),
3347                            myArrayDescription->Value (anArgIndex - 1).RealValue());
3348
3349       else
3350         anArray->AddBound (aVertCount);
3351     }
3352     // edge command
3353     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
3354     {
3355       const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
3356       anArray->AddEdge (aVertIndex);
3357     }
3358     // unknown command
3359     else
3360       anArgIndex++;
3361   }
3362
3363   aPresentation->Clear();
3364   if (!myMarkerAspect.IsNull())
3365   {
3366     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
3367   }
3368   Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
3369   Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
3370   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
3371 }
3372
3373 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3374                                        const Standard_Integer /*theMode*/)
3375 {
3376   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
3377
3378   Standard_Integer anArgIndex = 1;
3379   while (anArgIndex < myArrayDescription->Length())
3380   {
3381     if (CheckInputCommand ("v", myArrayDescription, anArgIndex, 3, myArrayDescription->Length()))
3382     {
3383       gp_Pnt aPoint (myArrayDescription->Value (anArgIndex - 3).RealValue(),
3384                      myArrayDescription->Value (anArgIndex - 2).RealValue(),
3385                      myArrayDescription->Value (anArgIndex - 1).RealValue());
3386       Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
3387       theSelection->Add (aSensetivePoint);
3388     }
3389     else
3390     {
3391       anArgIndex++;
3392     }
3393   }
3394 }
3395
3396 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3397                                        const Handle(TColStd_HArray1OfAsciiString) theArgsArray,
3398                                        Standard_Integer &theArgIndex,
3399                                        Standard_Integer theArgCount,
3400                                        Standard_Integer theMaxArgs)
3401 {
3402   // check if there is more elements than expected
3403   if (theArgIndex >= theMaxArgs)
3404     return false;
3405
3406   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3407   aStrCommand.LowerCase();
3408   if (aStrCommand.Search(theCommand) != 1 ||
3409       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3410     return false;
3411
3412   // go to the first data element
3413   theArgIndex++;
3414
3415   // check data if it can be converted to numeric
3416   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3417   {
3418     aStrCommand = theArgsArray->Value (theArgIndex);
3419     if (!aStrCommand.IsRealValue())
3420       return false;
3421   }
3422
3423   return true;
3424 }
3425
3426 //=============================================================================
3427 //function : VDrawPArray
3428 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3429 //=============================================================================
3430
3431 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3432 {
3433   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3434   if (aContextAIS.IsNull())
3435   {
3436     di << "Call vinit before!\n";
3437     return 1;
3438   }
3439   else if (argc < 3)
3440   {
3441     di << "Use: " << argv[0] << " Name TypeOfArray"
3442        << " [vertex] ... [bounds] ... [edges]\n"
3443        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
3444        << "                trianglefans | trianglestrips | quads |\n"
3445        << "                quadstrips | polygons }\n"
3446        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
3447        << " [texel={ 't' tx ty }] } \n"
3448        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
3449        << "  edges={ 'e' vertex_id }\n";
3450     return 1;
3451   }
3452
3453   // read the arguments
3454   Standard_Integer aArgIndex = 1;
3455   TCollection_AsciiString aName (argv[aArgIndex++]);
3456   TCollection_AsciiString anArrayType (argv[aArgIndex++]);
3457
3458   Standard_Boolean hasVertex = Standard_False;
3459
3460   Handle(TColStd_HArray1OfAsciiString) anArgsArray = new TColStd_HArray1OfAsciiString (0, argc - 2);
3461   anArgsArray->SetValue (0, anArrayType);
3462
3463   if (anArrayType != "points"         &&
3464       anArrayType != "segments"       &&
3465       anArrayType != "polylines"      &&
3466       anArrayType != "triangles"      &&
3467       anArrayType != "trianglefans"   &&
3468       anArrayType != "trianglestrips" &&
3469       anArrayType != "quads"          &&
3470       anArrayType != "quadstrips"     &&
3471       anArrayType != "polygons")
3472   {
3473     di << "Unexpected type of primitives array\n";
3474     return 1;
3475   }
3476
3477   TCollection_AsciiString aCommand;
3478   for (Standard_Integer anArgIndex = 3; anArgIndex < argc; anArgIndex++)
3479   {
3480     aCommand = argv[anArgIndex];
3481     aCommand.LowerCase();
3482     if (!aCommand.IsAscii())
3483     {
3484       di << "Unexpected argument: #" << aArgIndex - 1 << " , "
3485          << "should be an array element: 'v', 'b', 'e' \n";
3486       break;
3487     }
3488
3489     if (aCommand == "v")
3490     {
3491       hasVertex = Standard_True;
3492     }
3493
3494     anArgsArray->SetValue (anArgIndex - 2, aCommand);
3495   }
3496
3497   if (!hasVertex)
3498   {
3499     di << "You should pass any verticies in the list of array elements\n";
3500     return 1;
3501   }
3502
3503   Handle(Graphic3d_AspectMarker3d)    anAspPoints;
3504   if (anArrayType == "points")
3505   {
3506     anAspPoints = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
3507   }
3508
3509   // create primitives array object
3510   Handle(MyPArrayObject) aPObject = new MyPArrayObject (anArgsArray, anAspPoints);
3511
3512   // register the object in map
3513   VDisplayAISObject (aName, aPObject);
3514
3515   return 0;
3516 }
3517
3518 namespace
3519 {
3520   //! Auxiliary function for parsing translation vector - either 2D or 3D.
3521   static Standard_Integer parseTranslationVec (Standard_Integer theArgNb,
3522                                                const char**     theArgVec,
3523                                                gp_Vec&          theVec)
3524   {
3525     if (theArgNb < 2)
3526     {
3527       return 0;
3528     }
3529
3530     TCollection_AsciiString anX (theArgVec[0]);
3531     TCollection_AsciiString anY (theArgVec[1]);
3532     if (!anX.IsRealValue()
3533      || !anY.IsRealValue())
3534     {
3535       return 0;
3536     }
3537
3538     theVec.SetX (anX.RealValue());
3539     theVec.SetY (anY.RealValue());
3540     if (theArgNb >= 3)
3541     {
3542       TCollection_AsciiString anZ (theArgVec[2]);
3543       if (anZ.IsRealValue())
3544       {
3545         theVec.SetZ (anZ.RealValue());
3546         return 3;
3547       }
3548     }
3549     return 2;
3550   }
3551 }
3552
3553 //=======================================================================
3554 //function : VSetLocation
3555 //purpose  : Change location of AIS interactive object
3556 //=======================================================================
3557
3558 static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
3559                                       Standard_Integer  theArgNb,
3560                                       const char**      theArgVec)
3561 {
3562   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3563   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
3564   if (aContext.IsNull())
3565   {
3566     std::cout << "Error: no active view!\n";
3567     return 1;
3568   }
3569
3570   Standard_Boolean toPrintInfo = Standard_True;
3571   Handle(AIS_InteractiveObject) anObj;
3572   TCollection_AsciiString aCmdName (theArgVec[0]);
3573   aCmdName.LowerCase();
3574   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3575   {
3576     TCollection_AsciiString anArg = theArgVec[anArgIter];
3577     anArg.LowerCase();
3578     if (anUpdateTool.parseRedrawMode (anArg))
3579     {
3580       continue;
3581     }
3582     else if (anObj.IsNull())
3583     {
3584       const TCollection_AsciiString aName (theArgVec[anArgIter]);
3585       const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3586       if (aMap.IsBound2 (aName))
3587       {
3588         anObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName));
3589       }
3590       if (anObj.IsNull())
3591       {
3592         std::cout << "Error: object '" << aName << "' is not displayed!\n";
3593         return 1;
3594       }
3595     }
3596     else if (anArg == "-reset")
3597     {
3598       toPrintInfo = Standard_False;
3599       aContext->SetLocation (anObj, gp_Trsf());
3600     }
3601     else if (anArg == "-copyfrom"
3602           || anArg == "-copy")
3603     {
3604       if (anArgIter + 1 >= theArgNb)
3605       {
3606         std::cout << "Syntax error at '" << anArg << "'\n";
3607         return 1;
3608       }
3609
3610       const TCollection_AsciiString aName2 (theArgVec[anArgIter + 1]);
3611       const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
3612       Handle(AIS_InteractiveObject) anObj2;
3613       if (aMap.IsBound2 (aName2))
3614       {
3615         anObj2 = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (aName2));
3616       }
3617       if (anObj2.IsNull())
3618       {
3619         std::cout << "Error: object '" << aName2 << "' is not displayed!\n";
3620         return 1;
3621       }
3622
3623       ++anArgIter;
3624       aContext->SetLocation (anObj, anObj2->LocalTransformation());
3625     }
3626     else if (anArg == "-rotate")
3627     {
3628       toPrintInfo = Standard_False;
3629       if (anArgIter + 7 >= theArgNb)
3630       {
3631         std::cout << "Syntax error at '" << anArg << "'\n";
3632         return 1;
3633       }
3634
3635       gp_Trsf aTrsf;
3636       aTrsf.SetRotation (gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[anArgIter + 1]),
3637                                          Draw::Atof (theArgVec[anArgIter + 2]),
3638                                          Draw::Atof (theArgVec[anArgIter + 3])),
3639                                  gp_Vec (Draw::Atof (theArgVec[anArgIter + 4]),
3640                                          Draw::Atof (theArgVec[anArgIter + 5]),
3641                                          Draw::Atof (theArgVec[anArgIter + 6]))),
3642                                          Draw::Atof (theArgVec[anArgIter + 7]) * (M_PI / 180.0));
3643       anArgIter += 7;
3644
3645       aTrsf = anObj->LocalTransformation() * aTrsf;
3646       aContext->SetLocation (anObj, aTrsf);
3647     }
3648     else if (anArg == "-translate")
3649     {
3650       toPrintInfo = Standard_False;
3651       gp_Vec aLocVec;
3652       Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
3653       anArgIter += aNbParsed;
3654       if (aNbParsed == 0)
3655       {
3656         std::cout << "Syntax error at '" << anArg << "'\n";
3657         return 1;
3658       }
3659
3660       gp_Trsf aTrsf;
3661       aTrsf.SetTranslationPart (aLocVec);
3662       aTrsf = anObj->LocalTransformation() * aTrsf;
3663       aContext->SetLocation (anObj, aTrsf);
3664     }
3665     else if (anArg == "-scale"
3666           || anArg == "-setscale")
3667     {
3668       toPrintInfo = Standard_False;
3669       gp_XYZ aScaleLoc;
3670       Standard_Real aScale = 1.0;
3671       Standard_Boolean toPrintScale = Standard_True;
3672       Standard_Boolean hasScaleLoc  = Standard_False;
3673       if (anArgIter + 4 < theArgNb)
3674       {
3675         TCollection_AsciiString aScaleArgs[4] =
3676         {
3677           TCollection_AsciiString (theArgVec[anArgIter + 1]),
3678           TCollection_AsciiString (theArgVec[anArgIter + 2]),
3679           TCollection_AsciiString (theArgVec[anArgIter + 3]),
3680           TCollection_AsciiString (theArgVec[anArgIter + 4])
3681         };
3682         Standard_Integer aScaleArgIter = 0;
3683         for (; aScaleArgIter < 4; ++aScaleArgIter)
3684         {
3685           if (!aScaleArgs[aScaleArgIter].IsRealValue())
3686           {
3687             break;
3688           }
3689         }
3690         if (aScaleArgIter == 4)
3691         {
3692           aScaleLoc.SetCoord (aScaleArgs[0].RealValue(), aScaleArgs[1].RealValue(), aScaleArgs[2].RealValue());
3693           aScale = aScaleArgs[3].RealValue();
3694           anArgIter += 4;
3695           toPrintScale = Standard_False;
3696           hasScaleLoc  = Standard_True;
3697         }
3698         else if (aScaleArgIter >= 1)
3699         {
3700           aScale = aScaleArgs[0].RealValue();
3701           ++anArgIter;
3702           toPrintScale = Standard_False;
3703         }
3704       }
3705       else if (anArgIter + 1 < theArgNb)
3706       {
3707         TCollection_AsciiString aScaleArg (theArgVec[anArgIter + 1]);
3708         if (aScaleArg.IsRealValue())
3709         {
3710           aScale = aScaleArg.RealValue();
3711           ++anArgIter;
3712           toPrintScale = Standard_False;
3713         }
3714       }
3715
3716       if (toPrintScale)
3717       {
3718         if (anArg == "-setscale")
3719         {
3720           std::cout << "Syntax error at '" << anArg << "'\n";
3721           return 1;
3722         }
3723
3724         char aText[1024];
3725         Sprintf (aText, "%g ", anObj->LocalTransformation().ScaleFactor());
3726         theDI << aText;
3727         continue;
3728       }
3729
3730       if (anArg == "-setscale")
3731       {
3732         gp_Trsf aTrsf = anObj->LocalTransformation();
3733         if (hasScaleLoc)
3734         {
3735           aTrsf.SetScale (aScaleLoc, aScale);
3736         }
3737         else
3738         {
3739           aTrsf.SetScaleFactor (aScale);
3740         }
3741         aContext->SetLocation (anObj, aTrsf);
3742       }
3743       else
3744       {
3745         gp_Trsf aTrsf;
3746         if (hasScaleLoc)
3747         {
3748           aTrsf.SetScale (aScaleLoc, aScale);
3749           aTrsf = anObj->LocalTransformation() * aTrsf;
3750         }
3751         else
3752         {
3753           aTrsf = anObj->LocalTransformation();
3754           aTrsf.SetScaleFactor (aTrsf.ScaleFactor() * aScale);
3755         }
3756         aContext->SetLocation (anObj, aTrsf);
3757       }
3758     }
3759     else if (anArg == "-mirror")
3760     {
3761       toPrintInfo = Standard_False;
3762       if (anArgIter + 6 >= theArgNb)
3763       {
3764         std::cout << "Syntax error at '" << anArg << "'\n";
3765         return 1;
3766       }
3767
3768       gp_Trsf aTrsf;
3769       aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
3770                                        Draw::Atof(theArgVec[theArgNb - 5]),
3771                                        Draw::Atof(theArgVec[theArgNb - 4])),
3772                                gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
3773                                        Draw::Atof(theArgVec[theArgNb - 2]),
3774                                        Draw::Atof(theArgVec[theArgNb - 1]))));
3775       anArgIter += 6;
3776       aTrsf = anObj->LocalTransformation() * aTrsf;
3777       aContext->SetLocation (anObj, aTrsf);
3778     }
3779     else if (anArg == "-setrotation"
3780           || anArg == "-rotation")
3781     {
3782       toPrintInfo = Standard_False;
3783       if (anArgIter + 4 < theArgNb)
3784       {
3785         TCollection_AsciiString aQuatArgs[4] =
3786         {
3787           TCollection_AsciiString (theArgVec[anArgIter + 1]),
3788           TCollection_AsciiString (theArgVec[anArgIter + 2]),
3789           TCollection_AsciiString (theArgVec[anArgIter + 3]),
3790           TCollection_AsciiString (theArgVec[anArgIter + 4])
3791         };
3792         Standard_Integer aQuatArgIter = 0;
3793         for (; aQuatArgIter < 4; ++aQuatArgIter)
3794         {
3795           if (!aQuatArgs[aQuatArgIter].IsRealValue())
3796           {
3797             break;
3798           }
3799         }
3800
3801         if (aQuatArgIter == 4)
3802         {
3803           anArgIter += 4;
3804           const gp_Quaternion aQuat (aQuatArgs[0].RealValue(),
3805                                      aQuatArgs[1].RealValue(),
3806                                      aQuatArgs[2].RealValue(),
3807                                      aQuatArgs[3].RealValue());
3808           gp_Trsf aTrsf = anObj->LocalTransformation();
3809           aTrsf.SetRotation (aQuat);
3810           aContext->SetLocation (anObj, aTrsf);
3811           continue;
3812         }
3813         else if (anArg == "-setrotation")
3814         {
3815           std::cout << "Syntax error at '" << anArg << "'\n";
3816           return 1;
3817         }
3818       }
3819
3820       char aText[1024];
3821       const gp_Quaternion aQuat = anObj->LocalTransformation().GetRotation();
3822       Sprintf (aText, "%g %g %g %g ", aQuat.X(), aQuat.Y(), aQuat.Z(), aQuat.W());
3823       theDI << aText;
3824     }
3825     else if (anArg == "-setlocation"
3826           || anArg == "-location")
3827     {
3828       toPrintInfo = Standard_False;
3829       gp_Vec aLocVec;
3830       Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
3831       anArgIter += aNbParsed;
3832       if (aNbParsed != 0)
3833       {
3834         gp_Trsf aTrsf = anObj->LocalTransformation();
3835         aTrsf.SetTranslationPart (aLocVec);
3836         aContext->SetLocation (anObj, aTrsf);
3837       }
3838       else if (anArg == "-setlocation")
3839       {
3840         std::cout << "Syntax error at '" << anArg << "'\n";
3841         return 1;
3842       }
3843
3844       char aText[1024];
3845       const gp_XYZ aLoc = anObj->LocalTransformation().TranslationPart();
3846       Sprintf (aText, "%g %g %g ", aLoc.X(), aLoc.Y(), aLoc.Z());
3847       theDI << aText;
3848     }
3849     else if (aCmdName == "vsetlocation")
3850     {
3851       // compatibility with old syntax
3852       gp_Vec aLocVec;
3853       Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter, theArgVec + anArgIter, aLocVec);
3854       if (aNbParsed == 0)
3855       {
3856         std::cout << "Syntax error at '" << anArg << "'\n";
3857         return 1;
3858       }
3859       anArgIter = anArgIter + aNbParsed - 1;
3860
3861       gp_Trsf aTrsf;
3862       aTrsf.SetTranslationPart (aLocVec);
3863       aContext->SetLocation (anObj, aTrsf);
3864       toPrintInfo = Standard_False;
3865     }
3866     else
3867     {
3868       std::cout << "Error: unknown argument '" << anArg << "'\n";
3869       return 1;
3870     }
3871   }
3872
3873   if (anObj.IsNull())
3874   {
3875     std::cout << "Syntax error - wrong number of arguments\n";
3876     return 1;
3877   }
3878   else if (!toPrintInfo)
3879   {
3880     return 0;
3881   }
3882
3883   const gp_Trsf       aTrsf = anObj->LocalTransformation();
3884   const gp_XYZ        aLoc  = aTrsf.TranslationPart();
3885   const gp_Quaternion aRot  = aTrsf.GetRotation();
3886   char aText[4096];
3887   Sprintf (aText, "Location: %g %g %g\n"
3888                   "Rotation: %g %g %g %g\n"
3889                   "Scale:    %g\n",
3890                   aLoc.X(), aLoc.Y(), aLoc.Z(),
3891                   aRot.X(), aRot.Y(), aRot.Z(), aRot.W(),
3892                   aTrsf.ScaleFactor());
3893   theDI << aText;
3894   return 0;
3895 }
3896
3897 //===============================================================================================
3898 //function : VConnect
3899 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
3900 //Draw arg : vconnect name Xo Yo Zo object1 object2 ... [color=NAME]
3901 //===============================================================================================
3902
3903 static Standard_Integer VConnect (Draw_Interpretor& /*di*/, 
3904                                   Standard_Integer argc, 
3905                                   const char ** argv) 
3906 {
3907   // Check the viewer
3908   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3909   if (aContext.IsNull())
3910   {
3911     std::cout << "vconnect error : call vinit before\n";
3912     return 1; // TCL_ERROR
3913   }
3914   // Check argumnets 
3915   if (argc < 6)
3916   {
3917     std::cout << "vconnect error: expect at least 5 arguments\n";
3918     return 1; // TCL_ERROR
3919   }
3920
3921   // Get values
3922   Standard_Integer anArgIter = 1;
3923   TCollection_AsciiString aName (argv[anArgIter++]);
3924   Handle(AIS_MultipleConnectedInteractive) anOriginObject;
3925   TCollection_AsciiString aColorString (argv[argc-1]);
3926   Standard_CString aColorName = "";
3927   Standard_Boolean hasColor = Standard_False;
3928   if (aColorString.Search ("color=") != -1)
3929   {
3930     hasColor = Standard_True;
3931     aColorString.Remove (1, 6);
3932     aColorName = aColorString.ToCString();
3933   }
3934   Handle(AIS_InteractiveObject) anObject;
3935
3936   // AIS_MultipleConnectedInteractive
3937   const Standard_Integer aNbShapes = hasColor ? (argc - 1) : argc;
3938   for (Standard_Integer i = 5; i < aNbShapes; ++i)
3939   {
3940     TCollection_AsciiString anOriginObjectName (argv[i]);
3941     if (aName.IsEqual (anOriginObjectName))
3942     {
3943       std::cout << "vconnect error: equal names for connected objects\n";
3944       continue;
3945     }
3946     if (GetMapOfAIS().IsBound2 (anOriginObjectName))
3947     {
3948       Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
3949       anObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
3950       if (anObject.IsNull())
3951       {
3952         std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
3953         continue;
3954       }
3955     }
3956     else
3957     {
3958       Standard_CString aOriginName = anOriginObjectName.ToCString();
3959       TopoDS_Shape aTDShape = DBRep::Get (aOriginName);
3960       if (aTDShape.IsNull())
3961       {
3962         std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
3963         continue;
3964       }
3965       anObject = new AIS_Shape (aTDShape);
3966       aContext->Load (anObject);
3967       anObject->SetColor (ViewerTest::GetColorFromName (aColorName));
3968     }
3969
3970     if (anOriginObject.IsNull())
3971     {
3972       anOriginObject = new AIS_MultipleConnectedInteractive();
3973     }
3974
3975     anOriginObject->Connect (anObject);
3976   }
3977   if (anOriginObject.IsNull())
3978   {
3979     std::cout << "vconect error : can't connect input objects\n";
3980     return 1; // TCL_ERROR
3981   }
3982
3983   // Get location data
3984   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
3985   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
3986   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
3987
3988   // Create transformation
3989   gp_Vec aTranslation (aXo, aYo, aZo);
3990
3991   gp_Trsf aTrsf; 
3992   aTrsf.SetTranslationPart (aTranslation);
3993   TopLoc_Location aLocation (aTrsf);
3994
3995   anOriginObject->SetLocalTransformation (aTrsf);
3996
3997   // Check if there is another object with given name
3998   // and remove it from context
3999   if(GetMapOfAIS().IsBound2(aName))
4000   {
4001     Handle(AIS_InteractiveObject) anObj = 
4002       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
4003     TheAISContext()->Remove(anObj, Standard_False);
4004     GetMapOfAIS().UnBind2(aName);
4005   }
4006
4007   // Bind connected object to its name
4008   GetMapOfAIS().Bind (anOriginObject, aName);
4009
4010   // Display connected object
4011   TheAISContext()->Display (anOriginObject, Standard_True);
4012
4013   return 0;
4014 }
4015
4016 //===============================================================================================
4017 //function : VConnectTo
4018 //purpose  : Creates and displays AIS_ConnectedInteractive object from input object and location 
4019 //Draw arg : vconnectto name Xo Yo Zo object [-nodisplay|-noupdate|-update]
4020 //===============================================================================================
4021
4022 static Standard_Integer VConnectTo (Draw_Interpretor& /*di*/, 
4023                                     Standard_Integer argc, 
4024                                     const char ** argv) 
4025 {
4026   // Check the viewer
4027   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4028   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
4029   if (aContext.IsNull())
4030   {
4031     std::cout << "vconnect error : call vinit before\n";
4032     return 1; // TCL_ERROR
4033   }
4034   // Check argumnets 
4035   if (argc != 6 && argc != 7)
4036   {
4037     std::cout << "vconnect error: expect at least 5 arguments\n";
4038     return 1; // TCL_ERROR
4039   }
4040
4041   // Get values
4042   Standard_Integer anArgIter = 1;
4043   TCollection_AsciiString aName (argv[anArgIter++]);
4044   Handle(AIS_InteractiveObject) anOriginObject;
4045
4046   TCollection_AsciiString anOriginObjectName(argv[5]);
4047   if (aName.IsEqual (anOriginObjectName))
4048   {
4049     std::cout << "vconnect error: equal names for connected objects\n"; 
4050     return 1; // TCL_ERROR
4051   }
4052   if (GetMapOfAIS().IsBound2 (anOriginObjectName))
4053   {
4054     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (anOriginObjectName);
4055     anOriginObject = Handle(AIS_InteractiveObject)::DownCast(anObj);
4056     if (anOriginObject.IsNull())
4057     {
4058       std::cout << "Object " << anOriginObjectName << " is used for non AIS viewer\n";
4059       return 1; // TCL_ERROR
4060     }
4061   }
4062   else
4063   {
4064     Standard_CString aOriginName = anOriginObjectName.ToCString();
4065     TopoDS_Shape aTDShape = DBRep::Get (aOriginName);
4066     if (aTDShape.IsNull())
4067     {
4068       std::cout << "vconnect error: object " << anOriginObjectName << " doesn't exist\n";
4069       return 1; // TCL_ERROR
4070     }
4071     anOriginObject = new AIS_Shape (aTDShape);
4072     GetMapOfAIS().Bind (anOriginObject, anOriginObjectName);
4073   }
4074  
4075   // Get location data
4076   Standard_Real aXo = Draw::Atof (argv[anArgIter++]);
4077   Standard_Real aYo = Draw::Atof (argv[anArgIter++]);
4078   Standard_Real aZo = Draw::Atof (argv[anArgIter++]);
4079
4080   // Create transformation
4081   gp_Vec aTranslation (aXo, aYo, aZo);
4082
4083   gp_Trsf aTrsf; 
4084   aTrsf.SetTranslationPart (aTranslation);
4085  
4086   Handle(AIS_ConnectedInteractive) aConnected;
4087
4088   aConnected = new AIS_ConnectedInteractive();
4089
4090   aConnected->Connect (anOriginObject, aTrsf);
4091
4092   // Check if there is another object with given name
4093   // and remove it from context
4094   if(GetMapOfAIS().IsBound2(aName))
4095   {
4096     Handle(AIS_InteractiveObject) anObj = 
4097       Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
4098     TheAISContext()->Remove(anObj, Standard_False);
4099     GetMapOfAIS().UnBind2(aName);
4100   }
4101
4102   // Bind connected object to its name
4103   GetMapOfAIS().Bind (aConnected, aName);
4104
4105   if (argc == 7)
4106   {
4107     TCollection_AsciiString anArg = argv[6];
4108     anArg.LowerCase();
4109     if (anArg == "-nodisplay")
4110       return 0;
4111
4112     if (!anUpdateTool.parseRedrawMode (anArg))
4113     {
4114       std::cout << "Warning! Unknown argument '" << anArg << "' passed, -nodisplay|-noupdate|-update expected at this point.\n";
4115     }
4116   }
4117
4118   // Display connected object
4119   TheAISContext()->Display (aConnected, Standard_False);
4120
4121   return 0;
4122 }
4123
4124 //=======================================================================
4125 //function : VDisconnect
4126 //purpose  :
4127 //=======================================================================
4128 static Standard_Integer VDisconnect (Draw_Interpretor& di,
4129                                      Standard_Integer argc,
4130                                      const char ** argv)
4131 {
4132   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4133   if (aContext.IsNull())
4134   {
4135     std::cout << argv[0] << "ERROR : use 'vinit' command before \n";
4136     return 1;
4137   }
4138   
4139   if (argc != 3)
4140   {
4141     std::cout << "ERROR : Usage : " << argv[0] << " name object\n";
4142     return 1;
4143   }
4144
4145   TCollection_AsciiString aName (argv[1]);
4146   TCollection_AsciiString anObject (argv[2]);
4147   Standard_Integer anObjectNumber = Draw::Atoi (argv[2]);
4148
4149   // find objects
4150   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4151   Handle(AIS_MultipleConnectedInteractive) anAssembly;
4152   if (!aMap.IsBound2 (aName) )
4153   {
4154     std::cout << "Use 'vdisplay' before\n";
4155     return 1;
4156   }
4157
4158   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
4159   if (anAssembly.IsNull())
4160   {
4161     di << "Not an assembly\n";
4162     return 1;
4163   }
4164
4165   Handle(AIS_InteractiveObject) anIObj;
4166   if (!aMap.IsBound2 (anObject))
4167   {
4168     // try to interpret second argument as child number
4169     if (anObjectNumber > 0 && anObjectNumber <= anAssembly->Children().Size())
4170     {
4171       Standard_Integer aCounter = 1;
4172       for (PrsMgr_ListOfPresentableObjectsIter anIter (anAssembly->Children()); anIter.More(); anIter.Next())
4173       {
4174         if (aCounter == anObjectNumber)
4175         {
4176           anIObj = Handle(AIS_InteractiveObject)::DownCast (anIter.Value());
4177           break;
4178         }
4179         ++aCounter;
4180       }
4181     }
4182     else
4183     {
4184       std::cout << "Use 'vdisplay' before\n";
4185       return 1;
4186     }    
4187   }
4188
4189   // if object was found by name
4190   if (anIObj.IsNull())
4191   {
4192     anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (anObject));
4193   }
4194
4195   aContext->Disconnect (anAssembly, anIObj);
4196   aContext->UpdateCurrentViewer();
4197
4198   return 0;
4199 }
4200
4201 //=======================================================================
4202 //function : VAddConnected
4203 //purpose  :
4204 //=======================================================================
4205 static Standard_Integer VAddConnected (Draw_Interpretor& di,
4206                                        Standard_Integer argc,
4207                                        const char ** argv)
4208 {
4209   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4210   if (aContext.IsNull())
4211   {
4212     std::cout << argv[0] << "error : use 'vinit' command before \n";
4213     return 1;
4214   }
4215   
4216   if (argc != 6)
4217   {
4218     std::cout << argv[0] << " error: expect 5 arguments\n";
4219     return 1;
4220   }
4221
4222   TCollection_AsciiString aName (argv[1]);
4223   TCollection_AsciiString anObject (argv[5]);
4224   Standard_Real aX = Draw::Atof (argv[2]);
4225   Standard_Real aY = Draw::Atof (argv[3]);
4226   Standard_Real aZ = Draw::Atof (argv[4]);
4227
4228   // find object
4229   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4230   Handle(AIS_MultipleConnectedInteractive) anAssembly;
4231   if (!aMap.IsBound2 (aName) )
4232   {
4233     std::cout << "Use 'vdisplay' before\n";
4234     return 1;
4235   }
4236
4237   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
4238   if (anAssembly.IsNull())
4239   {
4240     di << "Not an assembly\n";
4241     return 1;
4242   }
4243
4244   Handle(AIS_InteractiveObject) anIObj;
4245   if (!aMap.IsBound2 (anObject))
4246   {
4247       std::cout << "Use 'vdisplay' before\n";
4248       return 1; 
4249   }
4250
4251   anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (anObject));
4252
4253   gp_Trsf aTrsf;
4254   aTrsf.SetTranslation (gp_Vec (aX, aY, aZ));
4255  
4256   anAssembly->Connect (anIObj, aTrsf);
4257   TheAISContext()->Display (anAssembly, Standard_False);
4258   TheAISContext()->RecomputeSelectionOnly (anAssembly);
4259   aContext->UpdateCurrentViewer();
4260
4261   return 0;
4262 }
4263
4264 //=======================================================================
4265 //function : VListConnected
4266 //purpose  :
4267 //=======================================================================
4268 static Standard_Integer VListConnected (Draw_Interpretor& /*di*/,
4269                                         Standard_Integer argc,
4270                                         const char ** argv)
4271 {
4272   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4273   if (aContext.IsNull())
4274   {
4275     std::cout << argv[0] << "ERROR : use 'vinit' command before \n";
4276     return 1;
4277   }
4278   
4279   if (argc != 2)
4280   {
4281     std::cout << "ERROR : Usage : " << argv[0] << " name\n";
4282     return 1;
4283   }
4284
4285   TCollection_AsciiString aName (argv[1]);
4286
4287   // find object
4288   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4289   Handle(AIS_MultipleConnectedInteractive) anAssembly;
4290   if (!aMap.IsBound2 (aName) )
4291   {
4292     std::cout << "Use 'vdisplay' before\n";
4293     return 1;
4294   }
4295
4296   anAssembly = Handle(AIS_MultipleConnectedInteractive)::DownCast (aMap.Find2 (aName));
4297   if (anAssembly.IsNull())
4298   {
4299     std::cout << "Not an assembly\n";
4300     return 1;
4301   }
4302
4303   std::cout << "Children of " << aName << ":\n";
4304
4305   Standard_Integer aCounter = 1;
4306   for (PrsMgr_ListOfPresentableObjectsIter anIter (anAssembly->Children()); anIter.More(); anIter.Next())
4307   {
4308     if (GetMapOfAIS().IsBound1 (anIter.Value()))
4309     {
4310       TCollection_AsciiString aCuurrentName = GetMapOfAIS().Find1 (anIter.Value());
4311       std::cout << aCounter << ")  " << aCuurrentName << "    (" << anIter.Value()->DynamicType()->Name() << ")";
4312     }
4313
4314     std::cout << aCounter << ")  " << anIter.Value()->DynamicType()->Name();
4315
4316     Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (anIter.Value());
4317     if (!aConnected.IsNull() && !aConnected->ConnectedTo().IsNull() && aMap.IsBound1 (aConnected->ConnectedTo()))
4318     {
4319       std::cout << " connected to " << aMap.Find1 (aConnected->ConnectedTo());
4320     }
4321     std::cout << std::endl;
4322     
4323     ++aCounter;
4324   }
4325
4326   return 0;
4327 }
4328
4329 //===============================================================================================
4330 //function : VSetSelectionMode
4331 //purpose  : vselmode
4332 //===============================================================================================
4333 static Standard_Integer VSetSelectionMode (Draw_Interpretor& /*di*/,
4334                                            Standard_Integer  theNbArgs,
4335                                            const char**      theArgv)
4336 {
4337   // Check errors
4338   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4339   if (anAISContext.IsNull())
4340   {
4341     std::cout << "Error: no active Viewer\n";
4342     return 1;
4343   }
4344
4345   NCollection_Sequence<TCollection_AsciiString> anObjNames;
4346   Standard_Integer aSelectionMode = -1;
4347   Standard_Boolean toTurnOn = Standard_True;
4348   AIS_SelectionModesConcurrency aSelModeConcurrency = AIS_SelectionModesConcurrency_GlobalOrLocal;
4349   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
4350   {
4351     TCollection_AsciiString anArgCase (theArgv[anArgIter]);
4352     anArgCase.LowerCase();
4353     if (anArgCase == "-set"
4354      || anArgCase == "-replace"
4355      || anArgCase == "-single"
4356      || anArgCase == "-exclusive")
4357     {
4358       aSelModeConcurrency = AIS_SelectionModesConcurrency_Single;
4359     }
4360     else if (anArgCase == "-add"
4361           || anArgCase == "-combine"
4362           || anArgCase == "-combination"
4363           || anArgCase == "-multiple")
4364     {
4365       aSelModeConcurrency = AIS_SelectionModesConcurrency_Multiple;
4366     }
4367     else if (anArgCase == "-globalorlocal"
4368           || anArgCase == "-localorglobal")
4369     {
4370       aSelModeConcurrency = AIS_SelectionModesConcurrency_GlobalOrLocal;
4371     }
4372     else
4373     {
4374       anObjNames.Append (theArgv[anArgIter]);
4375     }
4376   }
4377   if (anObjNames.Size() < 2
4378   || !ViewerTest::ParseOnOff (anObjNames.Last().ToCString(), toTurnOn))
4379   {
4380     std::cout << "Syntax error: wrong number of arguments\n";
4381     return 1;
4382   }
4383   anObjNames.Remove (anObjNames.Upper());
4384   {
4385     const TCollection_AsciiString aSelModeString = anObjNames.Last();
4386     anObjNames.Remove (anObjNames.Upper());
4387     TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
4388     if (aSelModeString.IsIntegerValue())
4389     {
4390       aSelectionMode = aSelModeString.IntegerValue();
4391     }
4392     else if (TopAbs::ShapeTypeFromString (aSelModeString.ToCString(), aShapeType))
4393     {
4394       aSelectionMode = AIS_Shape::SelectionMode (aShapeType);
4395     }
4396     else
4397     {
4398       std::cout << "Syntax error: unknown selection mode '" << aSelModeString  << "'\n";
4399       return 1;
4400     }
4401   }
4402
4403   AIS_ListOfInteractive aTargetIOs;
4404   for (NCollection_Sequence<TCollection_AsciiString>::Iterator anObjIter (anObjNames); anObjIter.More(); anObjIter.Next())
4405   {
4406     const TCollection_AsciiString& aNameIO = anObjIter.Value();
4407     Handle(AIS_InteractiveObject) anIO;
4408     if (GetMapOfAIS().IsBound2 (aNameIO))
4409     {
4410       anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aNameIO));
4411     }
4412
4413     if (anIO.IsNull())
4414     {
4415       std::cout << "Syntax error: undefined presentable object " << aNameIO << "\n";
4416       return 1;
4417     }
4418     aTargetIOs.Append (anIO);
4419   }
4420   if (aTargetIOs.IsEmpty())
4421   {
4422     anAISContext->DisplayedObjects (aTargetIOs);
4423   }
4424
4425   for (AIS_ListIteratorOfListOfInteractive aTargetIt (aTargetIOs); aTargetIt.More(); aTargetIt.Next())
4426   {
4427     const Handle(AIS_InteractiveObject)& anIO = aTargetIt.Value();
4428     anAISContext->SetSelectionModeActive (anIO, aSelectionMode, toTurnOn, aSelModeConcurrency);
4429   }
4430   return 0;
4431 }
4432
4433 //===============================================================================================
4434 //function : VSelectionNext
4435 //purpose  : 
4436 //===============================================================================================
4437 static Standard_Integer VSelectionNext(Draw_Interpretor& /*theDI*/,
4438                                  Standard_Integer /*theArgsNb*/,
4439                                  const char** /*theArgVec*/)
4440 {
4441   // Check errors
4442   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4443   Handle(V3d_View) aView = ViewerTest::CurrentView();
4444
4445   if (anAISContext.IsNull())
4446   {
4447     std::cerr << "Call vinit before!" << std::endl;
4448     return 1;
4449   }
4450
4451   anAISContext->HilightNextDetected (aView);
4452   return 0;
4453 }
4454
4455 //===============================================================================================
4456 //function : VSelectionPrevious
4457 //purpose  : 
4458 //===============================================================================================
4459 static Standard_Integer VSelectionPrevious(Draw_Interpretor& /*theDI*/,
4460                                  Standard_Integer /*theArgsNb*/,
4461                                  const char** /*theArgVec*/)
4462 {
4463   // Check errors
4464   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
4465   Handle(V3d_View) aView = ViewerTest::CurrentView();
4466
4467   if (anAISContext.IsNull())
4468   {
4469     std::cerr << "Call vinit before!" << std::endl;
4470     return 1;
4471   }
4472
4473   anAISContext->HilightPreviousDetected (aView);
4474   return 0;
4475 }
4476
4477
4478 //==========================================================================
4479 //class   : Triangle 
4480 //purpose : creates Triangle based on AIS_InteractiveObject. 
4481 //          This class was implemented for testing Select3D_SensitiveTriangle
4482 //===========================================================================
4483
4484 class Triangle: public AIS_InteractiveObject 
4485 {
4486 public: 
4487   // CASCADE RTTI
4488   DEFINE_STANDARD_RTTI_INLINE(Triangle,AIS_InteractiveObject);
4489   Triangle (const gp_Pnt& theP1, 
4490             const gp_Pnt& theP2, 
4491             const gp_Pnt& theP3);
4492 protected:
4493   void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
4494                   const Handle(Prs3d_Presentation)& thePresentation,
4495                   const Standard_Integer theMode) Standard_OVERRIDE;
4496
4497   void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
4498                            const Standard_Integer theMode) Standard_OVERRIDE;
4499 private: 
4500   gp_Pnt myPoint1;
4501   gp_Pnt myPoint2;
4502   gp_Pnt myPoint3;
4503 };
4504
4505
4506 Triangle::Triangle (const gp_Pnt& theP1,
4507                     const gp_Pnt& theP2,
4508                     const gp_Pnt& theP3)
4509 {
4510   myPoint1 = theP1;
4511   myPoint2 = theP2;
4512   myPoint3 = theP3;
4513 }
4514
4515 void Triangle::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
4516                        const Handle(Prs3d_Presentation)& thePresentation,
4517                        const Standard_Integer /*theMode*/)
4518 {
4519   thePresentation->Clear();
4520
4521   BRepBuilderAPI_MakeEdge anEdgeMaker1(myPoint1, myPoint2),
4522                           anEdgeMaker2(myPoint2, myPoint3),
4523                           anEdgeMaker3(myPoint3, myPoint1);
4524
4525   TopoDS_Edge anEdge1 = anEdgeMaker1.Edge(),
4526               anEdge2 = anEdgeMaker2.Edge(),
4527               anEdge3 = anEdgeMaker3.Edge();
4528   if(anEdge1.IsNull() || anEdge2.IsNull() || anEdge3.IsNull())
4529     return;
4530
4531   BRepBuilderAPI_MakeWire aWireMaker(anEdge1, anEdge2, anEdge3);
4532   TopoDS_Wire aWire = aWireMaker.Wire();
4533   if(aWire.IsNull()) return;
4534
4535   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
4536   TopoDS_Face aFace = aFaceMaker.Face();
4537   if(aFace.IsNull()) return;
4538
4539   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
4540 }
4541
4542 void Triangle::ComputeSelection(const Handle(SelectMgr_Selection)& theSelection, 
4543                                 const Standard_Integer /*theMode*/)
4544 {
4545   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
4546   Handle(Select3D_SensitiveTriangle) aSensTriangle = 
4547     new Select3D_SensitiveTriangle(anEntityOwner, myPoint1, myPoint2, myPoint3);
4548   theSelection->Add(aSensTriangle);
4549 }
4550
4551 //===========================================================================
4552 //function : VTriangle 
4553 //Draw arg : vtriangle Name PointName PointName PointName
4554 //purpose  : creates and displays Triangle
4555 //===========================================================================
4556
4557 //function: IsPoint
4558 //purpose : checks if the object with theName is AIS_Point, 
4559 //          if yes initialize thePoint from MapOfAIS
4560 Standard_Boolean IsPoint (const TCollection_AsciiString& theName,
4561                           Handle(AIS_Point)& thePoint)
4562 {
4563   Handle(AIS_InteractiveObject) anObject = 
4564     Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(theName));
4565   if(anObject.IsNull() || 
4566      anObject->Type() != AIS_KOI_Datum || 
4567      anObject->Signature() != 1)
4568   {
4569     return Standard_False;
4570   }
4571   thePoint = Handle(AIS_Point)::DownCast(anObject);
4572   if(thePoint.IsNull())
4573     return Standard_False;
4574   return Standard_True;
4575 }
4576
4577 //function: IsMatch
4578 //purpose: checks if thePoint1 is equal to thePoint2
4579 Standard_Boolean IsMatch (const Handle(Geom_CartesianPoint)& thePoint1,
4580                           const Handle(Geom_CartesianPoint)& thePoint2)
4581 {
4582   if(Abs(thePoint1->X()-thePoint2->X()) <= Precision::Confusion() &&
4583      Abs(thePoint1->Y()-thePoint2->Y()) <= Precision::Confusion() &&
4584      Abs(thePoint1->Z()-thePoint2->Z()) <= Precision::Confusion())
4585   {
4586     return Standard_True;
4587   }
4588   return Standard_False;
4589 }
4590
4591 static Standard_Integer VTriangle (Draw_Interpretor& /*di*/,
4592                                    Standard_Integer argc,
4593                                    const char ** argv)
4594 {
4595   // Check arguments
4596   if (argc != 5)
4597   {
4598     std::cout<<"vtriangle error: expects 4 argumnets\n";
4599     return 1; // TCL_ERROR
4600   }
4601
4602   // Get and check values
4603   TCollection_AsciiString aName(argv[1]);
4604
4605   Handle(AIS_Point) aPoint1, aPoint2, aPoint3;
4606   if (!IsPoint(argv[2], aPoint1))
4607   {
4608     std::cout<<"vtriangle error: the 2nd argument must be a point\n";
4609     return 1; // TCL_ERROR
4610   }
4611   if (!IsPoint(argv[3], aPoint2))
4612   {
4613     std::cout<<"vtriangle error: the 3d argument must be a point\n";
4614     return 1; // TCL_ERROR
4615   }
4616   if (!IsPoint(argv[4], aPoint3))
4617   {
4618     std::cout<<"vtriangle error: the 4th argument must be a point\n";
4619     return 1; // TCL_ERROR
4620   }
4621
4622   // Check that points are different
4623   Handle(Geom_CartesianPoint) aCartPoint1 = 
4624     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4625   Handle(Geom_CartesianPoint) aCartPoint2 = 
4626     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4627   // Test aPoint1 = aPoint2
4628   if (IsMatch(aCartPoint1, aCartPoint2))
4629   {
4630     std::cout<<"vtriangle error: the 1st and the 2nd points are equal\n";
4631     return 1; // TCL_ERROR
4632   }
4633   // Test aPoint2 = aPoint3
4634   Handle(Geom_CartesianPoint) aCartPoint3 = 
4635     Handle(Geom_CartesianPoint)::DownCast(aPoint3->Component());
4636   if (IsMatch(aCartPoint2, aCartPoint3))
4637   {
4638     std::cout<<"vtriangle error: the 2nd and the 3d points are equal\n";
4639     return 1; // TCL_ERROR
4640   }
4641   // Test aPoint3 = aPoint1
4642   if (IsMatch(aCartPoint1, aCartPoint3))
4643   {
4644     std::cout<<"vtriangle error: the 1st and the 3d points are equal\n";
4645     return 1; // TCL_ERROR
4646   }
4647
4648   // Create triangle
4649   Handle(Triangle) aTriangle = new Triangle(aCartPoint1->Pnt(),
4650                                             aCartPoint2->Pnt(),
4651                                             aCartPoint3->Pnt());
4652
4653   // Check if there is an object with given name
4654   // and remove it from context
4655   if (GetMapOfAIS().IsBound2(aName))
4656   {
4657     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4658     Handle(AIS_InteractiveObject) anInterObj = 
4659          Handle(AIS_InteractiveObject)::DownCast(anObj);
4660     TheAISContext()->Remove(anInterObj, Standard_False);
4661     GetMapOfAIS().UnBind2(aName);
4662   }
4663
4664   // Bind triangle to its name
4665   GetMapOfAIS().Bind(aTriangle, aName);
4666
4667   // Display triangle
4668   TheAISContext()->Display (aTriangle, Standard_True);
4669   return 0;
4670 }
4671
4672 //class  : SegmentObject
4673 //purpose: creates segment based on AIS_InteractiveObject.
4674 //         This class was implemented for testing Select3D_SensitiveCurve
4675
4676 class SegmentObject: public AIS_InteractiveObject
4677 {
4678 public:
4679   // CASCADE RTTI
4680   DEFINE_STANDARD_RTTI_INLINE(SegmentObject,AIS_InteractiveObject); 
4681   SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2);
4682 protected:
4683   void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
4684                 const Handle(Prs3d_Presentation)& thePresentation,
4685                 const Standard_Integer theMode) Standard_OVERRIDE;
4686
4687   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
4688                          const Standard_Integer theMode) Standard_OVERRIDE;
4689 private:
4690   gp_Pnt myPoint1;
4691   gp_Pnt myPoint2;
4692 };
4693
4694
4695 SegmentObject::SegmentObject (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2)
4696 {
4697   myPoint1 = thePnt1;
4698   myPoint2 = thePnt2;
4699 }
4700
4701 void SegmentObject::Compute (const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/,
4702                              const Handle(Prs3d_Presentation) &thePresentation,
4703                              const Standard_Integer /*theMode*/)
4704 {
4705   thePresentation->Clear();
4706   BRepBuilderAPI_MakeEdge anEdgeMaker(myPoint1, myPoint2);
4707   TopoDS_Edge anEdge = anEdgeMaker.Edge();
4708   if (anEdge.IsNull())
4709     return;
4710   BRepAdaptor_Curve aCurveAdaptor(anEdge);
4711   StdPrs_Curve::Add(thePresentation, aCurveAdaptor, myDrawer);
4712 }
4713
4714 void SegmentObject::ComputeSelection (const Handle(SelectMgr_Selection) &theSelection,
4715                                       const Standard_Integer /*theMode*/)
4716 {
4717   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this);
4718   Handle(TColgp_HArray1OfPnt) anArray = new TColgp_HArray1OfPnt(1, 2);
4719   anArray->SetValue(1, myPoint1);
4720   anArray->SetValue(2, myPoint2);
4721   Handle(Select3D_SensitiveCurve) aSensCurve = 
4722     new Select3D_SensitiveCurve(anOwner, anArray);
4723   theSelection->Add(aSensCurve);
4724 }
4725
4726 //=======================================================================
4727 //function  : VSegment
4728 //Draw args : vsegment Name PointName PointName
4729 //purpose   : creates and displays Segment
4730 //=======================================================================
4731 static Standard_Integer VSegment (Draw_Interpretor& /*di*/,
4732                                   Standard_Integer argc,
4733                                   const char ** argv)
4734 {
4735   // Check arguments
4736   if(argc!=4)
4737   {
4738     std::cout<<"vsegment error: expects 3 arguments\n";
4739     return 1; // TCL_ERROR
4740   }
4741
4742   // Get and check arguments
4743   TCollection_AsciiString aName(argv[1]);
4744   Handle(AIS_Point) aPoint1, aPoint2;
4745   if (!IsPoint(argv[2], aPoint1))
4746   {
4747     std::cout<<"vsegment error: the 2nd argument should be a point\n";
4748     return 1; // TCL_ERROR
4749   }
4750   if (!IsPoint(argv[3], aPoint2))
4751   {
4752     std::cout<<"vsegment error: the 3d argument should be a point\n";
4753     return 1; // TCL_ERROR
4754   }
4755   //Check that points are different
4756   Handle(Geom_CartesianPoint) aCartPoint1 = 
4757     Handle(Geom_CartesianPoint)::DownCast(aPoint1->Component());
4758   Handle(Geom_CartesianPoint) aCartPoint2 = 
4759     Handle(Geom_CartesianPoint)::DownCast(aPoint2->Component());
4760   if(IsMatch(aCartPoint1, aCartPoint2))
4761   {
4762     std::cout<<"vsegment error: equal points\n";
4763     return 1; // TCL_ERROR
4764   }
4765   
4766   // Create segment
4767   Handle(SegmentObject) aSegment = new SegmentObject(aCartPoint1->Pnt(), aCartPoint2->Pnt());
4768   // Check if there is an object with given name
4769   // and remove it from context
4770   if (GetMapOfAIS().IsBound2(aName))
4771   {
4772     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2(aName);
4773     Handle(AIS_InteractiveObject) anInterObj = 
4774          Handle(AIS_InteractiveObject)::DownCast(anObj);
4775     TheAISContext()->Remove(anInterObj, Standard_False);
4776     GetMapOfAIS().UnBind2(aName);
4777   }
4778
4779   // Bind segment to its name
4780   GetMapOfAIS().Bind(aSegment, aName);
4781
4782   // Display segment
4783   TheAISContext()->Display (aSegment, Standard_True);
4784   return 0;
4785 }
4786
4787 //=======================================================================
4788 //function : VObjZLayer
4789 //purpose  : Set or get z layer id for presentable object
4790 //=======================================================================
4791
4792 static Standard_Integer VObjZLayer (Draw_Interpretor& di,
4793                                     Standard_Integer argc,
4794                                     const char ** argv)
4795 {
4796   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4797   if (aContext.IsNull())
4798   {
4799     di << argv[0] << "Call 'vinit' before!\n";
4800     return 1;
4801   }
4802
4803   // get operation
4804   TCollection_AsciiString aOperation;
4805   if (argc >= 2)
4806     aOperation = TCollection_AsciiString (argv [1]);
4807
4808   // check for correct arguments
4809   if (!(argc == 4 && aOperation.IsEqual ("set")) &&
4810       !(argc == 3 && aOperation.IsEqual ("get")))
4811   {
4812     di << "Usage : " << argv[0] << " set/get object [layerid]\n";
4813     di << " set - set layer id for interactive object, layerid - z layer id\n";
4814     di << " get - get layer id of interactive object\n";
4815     di << " argument layerid should be passed for set operation only\n";
4816     return 1;
4817   }
4818
4819   // find object
4820   TCollection_AsciiString aName (argv[2]);
4821   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4822   if (!aMap.IsBound2 (aName))
4823   {
4824     di << "Use 'vdisplay' before\n";
4825     return 1;
4826   }
4827
4828   // find interactive object
4829   Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
4830   Handle(AIS_InteractiveObject) anInterObj =
4831     Handle(AIS_InteractiveObject)::DownCast (anObj);
4832   if (anInterObj.IsNull())
4833   {
4834     di << "Not an AIS interactive object!\n";
4835     return 1;
4836   }
4837
4838   // process operation
4839   if (aOperation.IsEqual ("set"))
4840   {
4841     Standard_Integer aLayerId = Draw::Atoi (argv [3]);
4842     aContext->SetZLayer (anInterObj, aLayerId);
4843   }
4844   else if (aOperation.IsEqual ("get"))
4845   {
4846     di << "Z layer id: " << aContext->GetZLayer (anInterObj);
4847   }
4848   
4849   return 0;
4850 }
4851
4852 //=======================================================================
4853 //function : VPolygonOffset
4854 //purpose  : Set or get polygon offset parameters
4855 //=======================================================================
4856 static Standard_Integer VPolygonOffset(Draw_Interpretor& /*di*/,
4857                                        Standard_Integer argc,
4858                                        const char ** argv)
4859 {
4860   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
4861   if (aContext.IsNull())
4862   {
4863     std::cout << argv[0] << " Call 'vinit' before!\n";
4864     return 1;
4865   }
4866
4867   if (argc > 2 && argc != 5)
4868   {
4869     std::cout << "Usage : " << argv[0] << " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
4870       "without arguments prints the default values" << std::endl;
4871     return 1;
4872   }
4873
4874   // find object
4875   Handle(AIS_InteractiveObject) anInterObj;
4876   if (argc >= 2)
4877   {
4878     TCollection_AsciiString aName (argv[1]);
4879     ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
4880     if (!aMap.IsBound2 (aName))
4881     {
4882       std::cout << "Use 'vdisplay' before" << std::endl;
4883       return 1;
4884     }
4885
4886     // find interactive object
4887     Handle(Standard_Transient) anObj = GetMapOfAIS().Find2 (aName);
4888     anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
4889     if (anInterObj.IsNull())
4890     {
4891       std::cout << "Not an AIS interactive object!" << std::endl;
4892       return 1;
4893     }
4894   }
4895
4896   Standard_Integer aMode;
4897   Standard_ShortReal    aFactor, aUnits;
4898   if (argc == 5)
4899   {
4900     aMode   = Draw::Atoi(argv[2]);
4901     aFactor = (Standard_ShortReal) Draw::Atof(argv[3]);
4902     aUnits  = (Standard_ShortReal) Draw::Atof(argv[4]);
4903
4904     anInterObj->SetPolygonOffsets(aMode, aFactor, aUnits);
4905     aContext->UpdateCurrentViewer();
4906     return 0;
4907   }
4908   else if (argc == 2)
4909   {
4910     if (anInterObj->HasPolygonOffsets())
4911     {
4912       anInterObj->PolygonOffsets(aMode, aFactor, aUnits);
4913       std::cout << "Current polygon offset parameters for " << argv[1] << ":" << std::endl;
4914       std::cout << "\tMode: "   << aMode   << std::endl;
4915       std::cout << "\tFactor: " << aFactor << std::endl;
4916       std::cout << "\tUnits: "  << aUnits  << std::endl;
4917       return 0;
4918     }
4919     else
4920     {
4921       std::cout << "Specific polygon offset parameters are not set for " << argv[1] << std::endl;
4922     }
4923   }
4924
4925   std::cout << "Default polygon offset parameters:" << std::endl;
4926   aContext->DefaultDrawer()->ShadingAspect()->Aspect()->PolygonOffsets(aMode, aFactor, aUnits);
4927   std::cout << "\tMode: "   << aMode   << std::endl;
4928   std::cout << "\tFactor: " << aFactor << std::endl;
4929   std::cout << "\tUnits: "  << aUnits  << std::endl;
4930
4931   return 0;
4932 }
4933
4934 //=======================================================================
4935 //function : VShowFaceBoundaries
4936 //purpose  : Set face boundaries drawing on/off for ais object
4937 //=======================================================================
4938 static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/,
4939                                            Standard_Integer argc,
4940                                            const char ** argv)
4941 {
4942   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext ();
4943   if (aContext.IsNull ())
4944   {
4945     std::cout << argv[0] << " Call 'vinit' before!\n";
4946     return 1;
4947   }
4948
4949   if ((argc != 3 && argc < 6) || argc > 8)
4950   {
4951     std::cout << "Usage :\n " << argv[0]
4952               << " ObjectName isOn [R G B [LineWidth [LineStyle]]]\n"
4953               << "   ObjectName - name of AIS interactive object. \n"
4954               << "                if ObjectName = \"\", then set as default\n"
4955               << "                settings for all newly displayed objects\n"
4956               << "   isOn       - flag indicating whether the boundaries\n"
4957               << "                should be turned on or off (can be set\n"
4958               << "                to 0 (off) or 1 (on)).\n"
4959               << "   R, G, B    - red, green and blue components of boundary\n"
4960               << "                color in range (0 - 255).\n"
4961               << "                (default is (0, 0, 0)\n"
4962               << "   LineWidth  - line width\n"
4963               << "                (default is 1)\n"
4964               << "   LineStyle  - line fill style :\n"
4965               << "                 0 - solid  \n"
4966               << "                 1 - dashed \n"
4967               << "                 2 - dot    \n"
4968               << "                 3 - dashdot\n"
4969               << "                 (default is solid)";
4970     return 1;
4971   }
4972
4973   TCollection_AsciiString aName (argv[1]);
4974
4975   Standard_Real aRed   = 0.0;
4976   Standard_Real aGreen = 0.0;
4977   Standard_Real aBlue  = 0.0;
4978   Standard_Real aWidth = 1.0;
4979   Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID;
4980   
4981   // find object
4982   Handle(AIS_InteractiveObject) anInterObj;
4983
4984   // if name is empty - apply attributes for default aspect
4985   if (!aName.IsEmpty ())
4986   {
4987     ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS ();
4988     if (!aMap.IsBound2 (aName))
4989     {
4990       std::cout << "Use 'vdisplay' on " << aName << " before" << std::endl;
4991       return 1;
4992     }
4993
4994     // find interactive object
4995     Handle(Standard_Transient) anObj = GetMapOfAIS ().Find2 (aName);
4996     anInterObj = Handle(AIS_InteractiveObject)::DownCast (anObj);
4997     if (anInterObj.IsNull ())
4998     {
4999       std::cout << "Not an AIS interactive object!" << std::endl;
5000       return 1;
5001     }
5002   }
5003   
5004   const Handle(Prs3d_Drawer)& aDrawer = (aName.IsEmpty ()) ?
5005     TheAISContext ()->DefaultDrawer () : anInterObj->Attributes ();
5006
5007   // turn boundaries on/off
5008   Standard_Boolean isBoundaryDraw = (Draw::Atoi (argv[2]) == 1);
5009   aDrawer->SetFaceBoundaryDraw (isBoundaryDraw);
5010   
5011   // set boundary line color
5012   if (argc >= 6)
5013   {
5014     // Text color
5015     aRed   = Draw::Atof (argv[3])/255.;
5016     aGreen = Draw::Atof (argv[4])/255.;
5017     aBlue  = Draw::Atof (argv[5])/255.;
5018   }
5019
5020   // set line width
5021   if (argc >= 7)
5022   {
5023     aWidth = (Standard_Real)Draw::Atof (argv[6]);
5024   }
5025
5026   // select appropriate line type
5027   if (argc == 8)
5028   {
5029     if (!ViewerTest::ParseLineType (argv[7], aLineType))
5030     {
5031       std::cout << "Syntax error: unknown line type '" << argv[7] << "'\n";
5032       return 1;
5033     }
5034   }
5035
5036   Quantity_Color aColor (aRed, aGreen, aBlue, Quantity_TOC_RGB);
5037
5038   Handle(Prs3d_LineAspect) aBoundaryAspect = 
5039     new Prs3d_LineAspect (aColor, aLineType, aWidth);
5040
5041   aDrawer->SetFaceBoundaryAspect (aBoundaryAspect);
5042
5043   TheAISContext()->Redisplay (anInterObj, Standard_True);
5044   
5045   return 0;
5046 }
5047
5048 // This class is used for testing markers.
5049
5050 class ViewerTest_MarkersArrayObject : public AIS_InteractiveObject
5051 {
5052
5053 public:
5054
5055   ViewerTest_MarkersArrayObject (const gp_XYZ& theStartPoint,
5056                                  const Standard_Integer& thePointsOnSide,
5057                                  Handle(Graphic3d_AspectMarker3d) theMarkerAspect = NULL)
5058   {
5059     myStartPoint = theStartPoint;
5060     myPointsOnSide = thePointsOnSide;
5061     myMarkerAspect = theMarkerAspect;
5062   }
5063
5064   DEFINE_STANDARD_RTTI_INLINE(ViewerTest_MarkersArrayObject,AIS_InteractiveObject);
5065
5066 private:
5067
5068   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
5069                 const Handle(Prs3d_Presentation)& aPresentation,
5070                 const Standard_Integer aMode) Standard_OVERRIDE;
5071
5072   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
5073                          const Standard_Integer /*theMode*/) Standard_OVERRIDE;
5074
5075 protected:
5076
5077   gp_XYZ myStartPoint;
5078   Standard_Integer myPointsOnSide;
5079   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
5080 };
5081
5082
5083 void ViewerTest_MarkersArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
5084                               const Handle(Prs3d_Presentation)& aPresentation,
5085                               const Standard_Integer /*aMode*/)
5086 {
5087   Handle(Graphic3d_ArrayOfPrimitives) anArray = new Graphic3d_ArrayOfPoints ((Standard_Integer )Pow (myPointsOnSide, 3), myPointsOnSide != 1);
5088   if (myPointsOnSide == 1)
5089   {
5090     anArray->AddVertex (myStartPoint);
5091   }
5092   else
5093   {
5094     for (Standard_Real i = 1; i <= myPointsOnSide; i++)
5095     {
5096       for (Standard_Real j = 1; j <= myPointsOnSide; j++)
5097       {
5098         for (Standard_Real k = 1; k <= myPointsOnSide; k++)
5099         {
5100           anArray->AddVertex (myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
5101           anArray->SetVertexColor (anArray->VertexNumber(),
5102                                    i / myPointsOnSide,
5103                                    j / myPointsOnSide,
5104                                    k / myPointsOnSide);
5105         }
5106       }
5107     }
5108   }
5109
5110   aPresentation->Clear();
5111   if (!myMarkerAspect.IsNull())
5112   {
5113     Prs3d_Root::CurrentGroup (aPresentation)->SetGroupPrimitivesAspect (myMarkerAspect);
5114   }
5115   Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (anArray);
5116 }
5117
5118 void ViewerTest_MarkersArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
5119                                        const Standard_Integer /*theMode*/)
5120 {
5121   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this);
5122
5123   if (myPointsOnSide == 1)
5124   {
5125     gp_Pnt aPoint (myStartPoint);
5126     Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
5127     theSelection->Add (aSensetivePoint);
5128   }
5129   else
5130   {
5131     for (Standard_Real i = 1; i <= myPointsOnSide; i++)
5132     {
5133       for (Standard_Real j = 1; j <= myPointsOnSide; j++)
5134       {
5135         for (Standard_Real k = 1; k <= myPointsOnSide; k++)
5136         {
5137           gp_Pnt aPoint (myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
5138           Handle(Select3D_SensitivePoint) aSensetivePoint = new Select3D_SensitivePoint (anEntityOwner, aPoint);
5139           theSelection->Add (aSensetivePoint);
5140         }
5141       }
5142     }
5143   }
5144 }
5145 //=======================================================================
5146 //function : VMarkersTest
5147 //purpose  : Draws an array of markers for testing purposes.
5148 //=======================================================================
5149 static Standard_Integer VMarkersTest (Draw_Interpretor&,
5150                                       Standard_Integer  theArgNb,
5151                                       const char**      theArgVec)
5152 {
5153   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5154   if (aContext.IsNull())
5155   {
5156     std::cerr << "Call 'vinit' before!\n";
5157     return 1;
5158   }
5159
5160   if (theArgNb < 5)
5161   {
5162     std::cerr << "Usage :\n " << theArgVec[0]
5163               << "name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n";
5164     return 1;
5165   }
5166
5167   Standard_Integer anArgIter = 1;
5168
5169   TCollection_AsciiString aName (theArgVec[anArgIter++]);
5170   TCollection_AsciiString aFileName;
5171   gp_XYZ aPnt (Atof (theArgVec[anArgIter]),
5172                Atof (theArgVec[anArgIter + 1]),
5173                Atof (theArgVec[anArgIter + 2]));
5174   anArgIter += 3;
5175
5176   Standard_Integer aPointsOnSide = 10;
5177   Standard_Integer aMarkerType   = -1;
5178   Standard_Real    aScale        = 1.0;
5179   for (; anArgIter < theArgNb; ++anArgIter)
5180   {
5181     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
5182     if (anArg.Search ("PointsOnSide=") > -1)
5183     {
5184       aPointsOnSide = anArg.Token ("=", 2).IntegerValue();
5185     }
5186     else if (anArg.Search ("MarkerType=") > -1)
5187     {
5188       aMarkerType = anArg.Token ("=", 2).IntegerValue();
5189     }
5190     else if (anArg.Search ("Scale=") > -1)
5191     {
5192       aScale = anArg.Token ("=", 2).RealValue();
5193     }
5194     else if (anArg.Search ("FileName=") > -1)
5195     {
5196       aFileName = anArg.Token ("=", 2);
5197     }
5198     else
5199     {
5200       std::cerr << "Wrong argument: " << anArg << "\n";
5201       return 1;
5202     }
5203   }
5204
5205   Handle(Graphic3d_AspectMarker3d) anAspect;
5206   Handle(Image_AlienPixMap) anImage;
5207   Quantity_Color aColor (Quantity_NOC_GREEN1);
5208   if ((aMarkerType == Aspect_TOM_USERDEFINED || aMarkerType < 0)
5209    && !aFileName.IsEmpty())
5210   {
5211     anImage = new Image_AlienPixMap();
5212     if (!anImage->Load (aFileName))
5213     {
5214       std::cerr << "Could not load image from file '" << aFileName << "'!\n";
5215       return 1;
5216     }
5217     if (anImage->Format() == Image_Format_Gray)
5218     {
5219       anImage->SetFormat (Image_Format_Alpha);
5220     }
5221     else if (anImage->Format() == Image_Format_GrayF)
5222     {
5223       anImage->SetFormat (Image_Format_AlphaF);
5224     }
5225     anAspect = new Graphic3d_AspectMarker3d (anImage);
5226   }
5227   else
5228   {
5229     anAspect = new Graphic3d_AspectMarker3d (aMarkerType >= 0 ? (Aspect_TypeOfMarker )aMarkerType : Aspect_TOM_POINT, aColor, aScale);
5230   }
5231
5232   Handle(ViewerTest_MarkersArrayObject) aMarkersArray = new ViewerTest_MarkersArrayObject (aPnt, aPointsOnSide, anAspect);
5233   VDisplayAISObject (aName, aMarkersArray);
5234
5235   return 0;
5236 }
5237
5238 //! Auxiliary function to parse font aspect style argument
5239 static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
5240                                         Font_FontAspect&               theAspect)
5241 {
5242   if (theArg == "regular"
5243    || *theArg.ToCString() == 'r')
5244   {
5245     theAspect = Font_FA_Regular;
5246     return Standard_True;
5247   }
5248   else if (theArg == "bolditalic")
5249   {
5250     theAspect = Font_FA_BoldItalic;
5251     return Standard_True;
5252   }
5253   else if (theArg == "bold"
5254         || *theArg.ToCString() == 'b')
5255   {
5256     theAspect = Font_FA_Bold;
5257     return Standard_True;
5258   }
5259   else if (theArg == "italic"
5260         || *theArg.ToCString() == 'i')
5261   {
5262     theAspect = Font_FA_Italic;
5263     return Standard_True;
5264   }
5265   return Standard_False;
5266 }
5267
5268 //! Auxiliary function
5269 static TCollection_AsciiString fontStyleString (const Font_FontAspect theAspect)
5270 {
5271   switch (theAspect)
5272   {
5273     case Font_FA_Regular:    return "regular";
5274     case Font_FA_BoldItalic: return "bolditalic";
5275     case Font_FA_Bold:       return "bold";
5276     case Font_FA_Italic:     return "italic";
5277     default:                 return "undefined";
5278   }
5279 }
5280
5281 //=======================================================================
5282 //function : TextToBrep
5283 //purpose  : Tool for conversion text to occt-shapes
5284 //=======================================================================
5285 static int TextToBRep (Draw_Interpretor& /*theDI*/,
5286                        Standard_Integer  theArgNb,
5287                        const char**      theArgVec)
5288 {
5289   // Check arguments
5290   if (theArgNb < 3)
5291   {
5292     std::cerr << "Error: " << theArgVec[0] << " - invalid syntax\n";
5293     return 1;
5294   }
5295
5296   Standard_Integer anArgIt = 1;
5297   Standard_CString aName   = theArgVec[anArgIt++];
5298   Standard_CString aText   = theArgVec[anArgIt++];
5299
5300   Font_BRepFont           aFont;
5301   TCollection_AsciiString aFontName ("Courier");
5302   Standard_Real           aTextHeight        = 16.0;
5303   Font_FontAspect         aFontAspect        = Font_FA_Regular;
5304   Standard_Boolean        anIsCompositeCurve = Standard_False;
5305   gp_Ax3                  aPenAx3    (gp::XOY());
5306   gp_Dir                  aNormal    (0.0, 0.0, 1.0);
5307   gp_Dir                  aDirection (1.0, 0.0, 0.0);
5308   gp_Pnt                  aPenLoc;
5309
5310   Graphic3d_HorizontalTextAlignment aHJustification = Graphic3d_HTA_LEFT;
5311   Graphic3d_VerticalTextAlignment   aVJustification = Graphic3d_VTA_BOTTOM;
5312
5313   for (; anArgIt < theArgNb; ++anArgIt)
5314   {
5315     TCollection_AsciiString aParam (theArgVec[anArgIt]);
5316     aParam.LowerCase();
5317
5318     if (aParam == "-pos"
5319      || aParam == "-position")
5320     {
5321       if (anArgIt + 3 >= theArgNb)
5322       {
5323         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5324         return 1;
5325       }
5326
5327       aPenLoc.SetX (Draw::Atof(theArgVec[++anArgIt]));
5328       aPenLoc.SetY (Draw::Atof(theArgVec[++anArgIt]));
5329       aPenLoc.SetZ (Draw::Atof(theArgVec[++anArgIt]));
5330     }
5331     else if (aParam == "-halign")
5332     {
5333       if (++anArgIt >= theArgNb)
5334       {
5335         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5336         return 1;
5337       }
5338
5339       TCollection_AsciiString aType (theArgVec[anArgIt]);
5340       aType.LowerCase();
5341       if (aType == "left")
5342       {
5343         aHJustification = Graphic3d_HTA_LEFT;
5344       }
5345       else if (aType == "center")
5346       {
5347         aHJustification = Graphic3d_HTA_CENTER;
5348       }
5349       else if (aType == "right")
5350       {
5351         aHJustification = Graphic3d_HTA_RIGHT;
5352       }
5353       else
5354       {
5355         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
5356         return 1;
5357       }
5358     }
5359     else if (aParam == "-valign")
5360     {
5361       if (++anArgIt >= theArgNb)
5362       {
5363         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5364         return 1;
5365       }
5366
5367       TCollection_AsciiString aType (theArgVec[anArgIt]);
5368       aType.LowerCase();
5369       if (aType == "top")
5370       {
5371         aVJustification = Graphic3d_VTA_TOP;
5372       }
5373       else if (aType == "center")
5374       {
5375         aVJustification = Graphic3d_VTA_CENTER;
5376       }
5377       else if (aType == "bottom")
5378       {
5379         aVJustification = Graphic3d_VTA_BOTTOM;
5380       }
5381       else if (aType == "topfirstline")
5382       {
5383         aVJustification = Graphic3d_VTA_TOPFIRSTLINE;
5384       }
5385       else
5386       {
5387         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
5388         return 1;
5389       }
5390     }
5391     else if (aParam == "-height")
5392     {
5393       if (++anArgIt >= theArgNb)
5394       {
5395         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5396         return 1;
5397       }
5398
5399       aTextHeight = Draw::Atof(theArgVec[anArgIt]);
5400     }
5401     else if (aParam == "-aspect")
5402     {
5403       if (++anArgIt >= theArgNb)
5404       {
5405         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5406         return 1;
5407       }
5408
5409       TCollection_AsciiString anOption (theArgVec[anArgIt]);
5410       anOption.LowerCase();
5411
5412       if (anOption.IsEqual ("regular"))
5413       {
5414         aFontAspect = Font_FA_Regular;
5415       }
5416       else if (anOption.IsEqual ("bold"))
5417       {
5418         aFontAspect = Font_FA_Bold;
5419       }
5420       else if (anOption.IsEqual ("italic"))
5421       {
5422         aFontAspect = Font_FA_Italic;
5423       }
5424       else if (anOption.IsEqual ("bolditalic"))
5425       {
5426         aFontAspect = Font_FA_BoldItalic;
5427       }
5428       else
5429       {
5430         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
5431         return 1;
5432       }
5433     }
5434     else if (aParam == "-font")
5435     {
5436       if (++anArgIt >= theArgNb)
5437       {
5438         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5439         return 1;
5440       }
5441
5442       aFontName = theArgVec[anArgIt];
5443     }
5444     else if (aParam == "-composite")
5445     {
5446       if (++anArgIt >= theArgNb)
5447       {
5448         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5449         return 1;
5450       }
5451
5452       ViewerTest::ParseOnOff (theArgVec[anArgIt], anIsCompositeCurve);
5453     }
5454     else if (aParam == "-plane")
5455     {
5456       if (anArgIt + 6 >= theArgNb)
5457       {
5458         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
5459         return 1;
5460       }
5461
5462       Standard_Real aX = Draw::Atof (theArgVec[++anArgIt]);
5463       Standard_Real aY = Draw::Atof (theArgVec[++anArgIt]);
5464       Standard_Real aZ = Draw::Atof (theArgVec[++anArgIt]);
5465       aNormal.SetCoord (aX, aY, aZ);
5466
5467       aX = Draw::Atof (theArgVec[++anArgIt]);
5468       aY = Draw::Atof (theArgVec[++anArgIt]);
5469       aZ = Draw::Atof (theArgVec[++anArgIt]);
5470       aDirection.SetCoord (aX, aY, aZ);
5471     }
5472     else
5473     {
5474       std::cerr << "Warning! Unknown argument '" << aParam << "'\n";
5475     }
5476   }
5477
5478   aFont.SetCompositeCurveMode (anIsCompositeCurve);
5479   if (!aFont.Init (aFontName.ToCString(), aFontAspect, aTextHeight))
5480   {
5481     std::cerr << "Font initialization error\n";
5482     return 1;
5483   }
5484
5485   aPenAx3 = gp_Ax3 (aPenLoc, aNormal, aDirection);
5486
5487   Font_BRepTextBuilder aBuilder;
5488   DBRep::Set (aName, aBuilder.Perform (aFont, aText, aPenAx3, aHJustification, aVJustification));
5489   return 0;
5490 }
5491
5492 //=======================================================================
5493 //function : VFont
5494 //purpose  : Font management
5495 //=======================================================================
5496
5497 static int VFont (Draw_Interpretor& theDI,
5498                   Standard_Integer  theArgNb,
5499                   const char**      theArgVec)
5500 {
5501   Handle(Font_FontMgr) aMgr = Font_FontMgr::GetInstance();
5502   if (theArgNb < 2)
5503   {
5504     // just print the list of available fonts
5505     Standard_Boolean isFirst = Standard_True;
5506     for (Font_NListOfSystemFont::Iterator anIter (aMgr->GetAvailableFonts());
5507          anIter.More(); anIter.Next())
5508     {
5509       const Handle(Font_SystemFont)& aFont = anIter.Value();
5510       if (!isFirst)
5511       {
5512         theDI << "\n";
5513       }
5514
5515       theDI << aFont->FontName()->String()
5516             << " " << fontStyleString (aFont->FontAspect())
5517             << " " << aFont->FontPath()->String();
5518       isFirst = Standard_False;
5519     }
5520     return 0;
5521   }
5522
5523   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
5524   {
5525     const TCollection_AsciiString anArg (theArgVec[anArgIter]);
5526     TCollection_AsciiString anArgCase (anArg);
5527     anArgCase.LowerCase();
5528     if (anArgCase == "find")
5529     {
5530       if (++anArgIter >= theArgNb)
5531       {
5532         std::cerr << "Wrong syntax at argument '" << anArg.ToCString() << "'!\n";
5533         return 1;
5534       }
5535
5536       Standard_CString aFontName   = theArgVec[anArgIter];
5537       Font_FontAspect  aFontAspect = Font_FA_Undefined;
5538       if (++anArgIter < theArgNb)
5539       {
5540         anArgCase = theArgVec[anArgIter];
5541         anArgCase.LowerCase();
5542         if (!parseFontStyle (anArgCase, aFontAspect))
5543         {
5544           --anArgIter;
5545         }
5546       }
5547       Handle(Font_SystemFont) aFont = aMgr->FindFont (new TCollection_HAsciiString (aFontName), aFontAspect, -1);
5548       if (aFont.IsNull())
5549       {
5550         std::cerr << "Error: font '" << aFontName << "' is not found!\n";
5551         continue;
5552       }
5553
5554       theDI << aFont->FontName()->String()
5555             << " " << fontStyleString (aFont->FontAspect())
5556             << " " << aFont->FontPath()->String();
5557     }
5558     else if (anArgCase == "add"
5559           || anArgCase == "register")
5560     {
5561       if (++anArgIter >= theArgNb)
5562       {
5563         std::cerr << "Error: wrong syntax at argument '" << anArg << "'!\n";
5564         return 1;
5565       }
5566
5567       Standard_CString aFontPath = theArgVec[anArgIter++];
5568       TCollection_AsciiString aFontName;
5569       Font_FontAspect  aFontAspect = Font_FA_Undefined;
5570       Standard_Integer isSingelStroke = -1;
5571       for (; anArgIter < theArgNb; ++anArgIter)
5572       {
5573         anArgCase = theArgVec[anArgIter];
5574         anArgCase.LowerCase();
5575         if (aFontAspect == Font_FA_Undefined
5576          && parseFontStyle (anArgCase, aFontAspect))
5577         {
5578           continue;
5579         }
5580         else if (anArgCase == "singlestroke"
5581               || anArgCase == "singleline"
5582               || anArgCase == "oneline")
5583         {
5584           isSingelStroke = 1;
5585         }
5586         else if (aFontName.IsEmpty())
5587         {
5588           aFontName = theArgVec[anArgIter];
5589         }
5590         else
5591         {
5592           --anArgIter;
5593           break;
5594         }
5595       }
5596
5597       Handle(Font_SystemFont) aFont = aMgr->CheckFont (aFontPath);
5598       if (aFont.IsNull())
5599       {
5600         std::cerr << "Error: font '" << aFontPath << "' is not found!\n";
5601         continue;
5602       }
5603
5604       if (aFontAspect != Font_FA_Undefined
5605       || !aFontName.IsEmpty())
5606       {
5607         if (aFontAspect == Font_FA_Undefined)
5608         {
5609           aFontAspect = aFont->FontAspect();
5610         }
5611         Handle(TCollection_HAsciiString) aName = aFont->FontName();
5612         if (!aFontName.IsEmpty())
5613         {
5614           aName = new TCollection_HAsciiString (aFontName);
5615         }
5616         aFont = new Font_SystemFont (aName, aFontAspect, new TCollection_HAsciiString (aFontPath));
5617       }
5618       if (isSingelStroke != -1)
5619       {
5620         aFont->SetSingleStrokeFont (isSingelStroke == 1);
5621       }
5622
5623       aMgr->RegisterFont (aFont, Standard_True);
5624       theDI << aFont->FontName()->String()
5625             << " " << fontStyleString (aFont->FontAspect())
5626             << " " << aFont->FontPath()->String();
5627     }
5628     else
5629     {
5630       std::cerr << "Warning! Unknown argument '" << anArg << "'\n";
5631     }
5632   }
5633
5634   return 0;
5635 }
5636
5637 //=======================================================================
5638 //function : VSetEdgeType
5639 //purpose  : Edges type management
5640 //=======================================================================
5641
5642 static int VSetEdgeType (Draw_Interpretor& theDI,
5643                          Standard_Integer  theArgNum,
5644                          const char**      theArgs)
5645 {
5646   if (theArgNum < 4 || theArgNum > 9)
5647   {
5648     theDI << theArgs[0] << " error: wrong number of parameters. Type 'help "
5649           << theArgs[0] << "' for more information.\n";
5650     return 1;
5651   }
5652
5653   Standard_Boolean isForceRedisplay = Standard_False;
5654
5655   // Get shape name
5656   TCollection_AsciiString aName(theArgs[1]);
5657   if (!GetMapOfAIS().IsBound2 (aName))
5658   {
5659     theDI <<  theArgs[0] << " error: wrong object name.\n";
5660     return 1;
5661   }
5662   
5663   Handle(AIS_InteractiveObject) anObject = 
5664     Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2(aName));
5665   
5666   // Enable triangle edge mode
5667   if (!anObject->Attributes()->HasOwnShadingAspect())
5668   {
5669     anObject->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
5670     *anObject->Attributes()->ShadingAspect()->Aspect() = *anObject->Attributes()->Link()->ShadingAspect()->Aspect();
5671   }
5672   const Handle(Prs3d_ShadingAspect)& aFillAreaAspect = anObject->Attributes()->ShadingAspect();
5673   aFillAreaAspect->Aspect()->SetEdgeOn();
5674
5675   // Parse parameters
5676   for (Standard_Integer anIt = 2; anIt < theArgNum; ++anIt)
5677   {
5678     TCollection_AsciiString aParam ((theArgs[anIt]));
5679     if (aParam.Value (1) == '-' && !aParam.IsRealValue())
5680     {
5681       if (aParam.IsEqual ("-type"))
5682       {
5683         if (theArgNum <= anIt + 1)
5684         {
5685           theDI <<  theArgs[0] << " error: wrong number of values for parameter '"
5686                 << aParam.ToCString() << "'.\n";
5687           return 1;
5688         }
5689
5690         ++anIt;
5691         Aspect_TypeOfLine aTypeEnum = Aspect_TOL_SOLID;
5692         if (!ViewerTest::ParseLineType (theArgs[anIt], aTypeEnum))
5693         {
5694           std::cout << "Syntax error: wrong line type: '" << theArgs[anIt] << "'.\n";
5695           return 1;
5696         }
5697         anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeLineType (aTypeEnum);
5698       }
5699       else if (aParam.IsEqual ("-color"))
5700       {
5701         if (theArgNum <= anIt + 3)
5702         {
5703           theDI <<  theArgs[0] << " error: wrong number of values for parameter '"
5704                 << aParam.ToCString() << "'.\n";
5705           return 1;
5706         }
5707
5708         Standard_Real aR = Draw::Atof(theArgs[++anIt]);
5709         Standard_Real aG = Draw::Atof(theArgs[++anIt]);
5710         Standard_Real aB = Draw::Atof(theArgs[++anIt]);
5711         Quantity_Color aColor = Quantity_Color (aR > 1 ? aR / 255.0 : aR,
5712                                                 aG > 1 ? aG / 255.0 : aG,
5713                                                 aB > 1 ? aB / 255.0 : aB,
5714                                                 Quantity_TOC_RGB);
5715
5716         aFillAreaAspect->Aspect()->SetEdgeColor (aColor);
5717       }
5718       else if (aParam.IsEqual ("-force"))
5719       {
5720         isForceRedisplay = Standard_True;
5721       }
5722       else
5723       {
5724         theDI <<  theArgs[0] << " error: unknown parameter '"
5725               << aParam.ToCString() << "'.\n";
5726         return 1;
5727       }
5728     }
5729   }
5730
5731   // Update shape presentation as aspect parameters were changed
5732   if (isForceRedisplay)
5733   {
5734     ViewerTest::GetAISContext()->Redisplay (anObject, Standard_False);
5735   }
5736   else
5737   {
5738     anObject->SetAspect (aFillAreaAspect);
5739   }
5740
5741   //Update view
5742   ViewerTest::CurrentView()->Redraw();
5743
5744   return 0;
5745 }
5746
5747 //=======================================================================
5748 //function : VUnsetEdgeType
5749 //purpose  : Unsets edges visibility in shading mode
5750 //=======================================================================
5751
5752 static int VUnsetEdgeType (Draw_Interpretor& theDI,
5753                          Standard_Integer  theArgNum,
5754                          const char**      theArgs)
5755 {
5756   if (theArgNum != 2 && theArgNum != 3)
5757   {
5758     theDI << theArgs[0] << " error: wrong number of parameters. Type 'help "
5759           << theArgs[0] << "' for more information.\n";
5760     return 1;
5761   }
5762
5763   Standard_Boolean isForceRedisplay = Standard_False;
5764
5765   // Get shape name
5766   TCollection_AsciiString aName (theArgs[1]);
5767   if (!GetMapOfAIS().IsBound2 (aName))
5768   {
5769     theDI <<  theArgs[0] << " error: wrong object name.\n";
5770     return 1;
5771   }
5772
5773   Handle(AIS_InteractiveObject) anObject = 
5774     Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(aName));
5775
5776   // Enable trianle edge mode
5777   anObject->Attributes()->ShadingAspect()->Aspect()->SetEdgeOff();
5778
5779   // Parse parameters
5780   if (theArgNum == 3)
5781   {
5782     TCollection_AsciiString aParam ((theArgs[2]));
5783     if (aParam.IsEqual ("-force"))
5784     {
5785       isForceRedisplay = Standard_True;
5786     }
5787     else
5788     {
5789        theDI <<  theArgs[0] << " error: unknown parameter '"
5790               << aParam.ToCString() << "'.\n";
5791        return 1;
5792     }
5793   }
5794
5795   // Update shape presentation as aspect parameters were changed
5796   if (isForceRedisplay)
5797   {
5798     ViewerTest::GetAISContext()->Redisplay (anObject, Standard_False);
5799   }
5800   else
5801   {
5802     anObject->SetAspect (anObject->Attributes()->ShadingAspect());
5803   }
5804
5805   //Update view
5806   ViewerTest::CurrentView()->Redraw();
5807
5808   return 0;
5809 }
5810
5811
5812 //=======================================================================
5813 //function : VVertexMode
5814 //purpose  : Switches vertex display mode for AIS_Shape or displays the current value
5815 //=======================================================================
5816
5817 static int VVertexMode (Draw_Interpretor& theDI,
5818                          Standard_Integer  theArgNum,
5819                          const char**      theArgs)
5820 {
5821   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
5822   if (aContext.IsNull())
5823   {
5824     std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
5825     return 1;
5826   }
5827
5828   // No arguments --> print the current default vertex draw mode
5829   if (theArgNum == 1)
5830   {
5831     Prs3d_VertexDrawMode aCurrMode = aContext->DefaultDrawer()->VertexDrawMode();
5832     theDI <<  "Default vertex draw mode: " << (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
5833     return 0;
5834   }
5835
5836   // -set argument --> change the default vertex draw mode and the mode for all displayed or given object(s)
5837   TCollection_AsciiString aParam (theArgs[1]);
5838   if (aParam == "-set")
5839   {
5840     if (theArgNum == 2)
5841     {
5842       std::cout << "Error: '-set' option not followed by the mode and optional object name(s)" << std::endl;
5843       std::cout << "Type 'help vvertexmode' for usage hints" << std::endl;
5844       return 1;
5845     }
5846
5847     TCollection_AsciiString aModeStr (theArgs[2]);
5848     Prs3d_VertexDrawMode aNewMode =
5849        aModeStr == "isolated" ? Prs3d_VDM_Isolated :
5850       (aModeStr == "all"      ? Prs3d_VDM_All :
5851                                 Prs3d_VDM_Inherited);
5852
5853     Standard_Boolean aRedrawNeeded = Standard_False;
5854     AIS_ListOfInteractive anObjs;
5855
5856     // No object(s) specified -> use all displayed
5857     if (theArgNum == 3)
5858     {
5859       theDI << "Setting the default vertex draw mode and updating all displayed objects...\n";
5860       aContext->DisplayedObjects (anObjs);
5861       aContext->DefaultDrawer()->SetVertexDrawMode (aNewMode);
5862       aRedrawNeeded = Standard_True;
5863     }
5864
5865     Handle(AIS_InteractiveObject) anObject;
5866     for (Standard_Integer aCount = 3; aCount < theArgNum; aCount++)
5867     {
5868       TCollection_AsciiString aName (theArgs[aCount]);
5869       if (!GetMapOfAIS().IsBound2 (aName))
5870       {
5871         theDI << "Warning: wrong object name ignored - " << theArgs[0] << "\n";
5872         continue;
5873       }
5874       anObject = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2(aName));
5875       anObjs.Append (anObject);
5876     }
5877
5878     for (AIS_ListIteratorOfListOfInteractive anIt (anObjs); anIt.More(); anIt.Next())
5879     {
5880       anObject = anIt.Value();
5881       anObject->Attributes()->SetVertexDrawMode (aNewMode);
5882       aContext->Redisplay (anObject, Standard_False);
5883       aRedrawNeeded = Standard_True;
5884     }
5885
5886     if (aRedrawNeeded)
5887       ViewerTest::CurrentView()->Redraw();
5888
5889     return 0;
5890   }
5891
5892   if (theArgNum > 2)
5893   {
5894     std::cout << "Error: invalid number of arguments" << std::endl;
5895     std::cout << "Type 'help vvertexmode' for usage hints" << std::endl;
5896     return 1;
5897   }
5898
5899   // One argument (object name) --> print the current vertex draw mode for the object
5900   Handle(AIS_InteractiveObject) anObject =
5901     Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aParam));
5902   Prs3d_VertexDrawMode aCurrMode = anObject->Attributes()->VertexDrawMode();
5903   theDI <<  "Object's vertex draw mode: " << (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
5904   return 0;
5905 }
5906
5907 //=======================================================================
5908 //function : VPointCloud
5909 //purpose  : Create interactive object for arbitary set of points.
5910 //=======================================================================
5911 static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
5912                                      Standard_Integer  theArgNum,
5913                                      const char**      theArgs)
5914 {
5915   Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
5916   if (anAISContext.IsNull())
5917   {
5918     std::cerr << "Error: no active view!\n";
5919     return 1;
5920   }
5921
5922   // command to execute
5923   enum Command
5924   {
5925     CloudForShape, // generate point cloud for shape
5926     CloudSphere,   // generate point cloud for generic sphere
5927     Unknow
5928   };
5929
5930   // count number of non-optional command arguments
5931   Command aCmd = Unknow;
5932   Standard_Integer aCmdArgs = 0;
5933   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
5934   {
5935     Standard_CString anArg = theArgs[anArgIter];
5936     TCollection_AsciiString aFlag (anArg);
5937     aFlag.LowerCase();
5938     if (aFlag.IsRealValue() || aFlag.Search ("-") != 1)
5939     {
5940       aCmdArgs++;
5941     }
5942   }
5943   switch (aCmdArgs)
5944   {
5945     case 2  : aCmd = CloudForShape; break;
5946     case 7  : aCmd = CloudSphere; break;
5947     default :
5948       std::cout << "Error: wrong number of arguments! See usage:\n";
5949       theDI.PrintHelp (theArgs[0]);
5950       return 1;
5951   }
5952
5953   // parse options
5954   Standard_Boolean toRandColors = Standard_False;
5955   Standard_Boolean hasNormals   = Standard_True;
5956   Standard_Boolean isSetArgNorm = Standard_False;
5957   for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
5958   {
5959     Standard_CString anArg = theArgs[anArgIter];
5960     TCollection_AsciiString aFlag (anArg);
5961     aFlag.LowerCase();
5962     if (aFlag == "-randcolors"
5963      || aFlag == "-randcolor")
5964     {
5965       if (isSetArgNorm && hasNormals)
5966       {
5967         std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
5968         return 1;
5969       }
5970       toRandColors = Standard_True;
5971       hasNormals   = Standard_False;
5972     }
5973     else if (aFlag == "-normals"
5974           || aFlag == "-normal")
5975     {
5976       if (toRandColors)
5977       {
5978         std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
5979         return 1;
5980       }
5981       isSetArgNorm = Standard_True;
5982       hasNormals   = Standard_True;
5983     }
5984     else if (aFlag == "-nonormals"
5985           || aFlag == "-nonormal")
5986     {
5987       isSetArgNorm = Standard_True;
5988       hasNormals   = Standard_False;
5989     }
5990   }
5991
5992   Standard_CString aName = theArgs[1];
5993
5994   // generate arbitrary set of points
5995   Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
5996   if (aCmd == CloudForShape)
5997   {
5998     Standard_CString aShapeName = theArgs[2];
5999     TopoDS_Shape     aShape     = DBRep::Get (aShapeName);
6000
6001     if (aShape.IsNull())
6002     {
6003       std::cout << "Error: no shape with name '" << aShapeName << "' found\n";
6004       return 1;
6005     }
6006
6007     // calculate number of points
6008     TopLoc_Location  aLocation;
6009     Standard_Integer aNbPoints = 0;
6010     for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
6011     {
6012       const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
6013       Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation);
6014       if (!aTriangulation.IsNull())
6015       {
6016         aNbPoints += aTriangulation->NbNodes();
6017       }
6018     }
6019     if (aNbPoints < 3)
6020     {
6021       std::cout << "Error: shape should be triangulated!\n";
6022       return 1;
6023     }
6024
6025     anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
6026     for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
6027     {
6028       const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
6029       Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation);
6030       if (aTriangulation.IsNull())
6031       {
6032         continue;
6033       }
6034
6035       const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
6036       const gp_Trsf&            aTrsf  = aLocation.Transformation();
6037
6038       // extract normals from nodes
6039       TColgp_Array1OfDir aNormals (aNodes.Lower(), hasNormals ? aNodes.Upper() : aNodes.Lower());
6040       if (hasNormals)
6041       {
6042         Poly_Connect aPolyConnect (aTriangulation);
6043         StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals);
6044       }
6045
6046       for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
6047       {
6048         gp_Pnt aPoint = aNodes (aNodeIter);
6049         if (!aLocation.IsIdentity())
6050         {
6051           aPoint.Transform (aTrsf);
6052           if (hasNormals)
6053           {
6054             aNormals (aNodeIter).Transform (aTrsf);
6055           }
6056         }
6057
6058         // add vertex into array of points
6059         const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
6060         if (toRandColors)
6061         {
6062           Quantity_Color aColor (360.0 * Standard_Real(anIndexOfPoint) / Standard_Real(aNbPoints),
6063                                  1.0, 0.5, Quantity_TOC_HLS);
6064           anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
6065         }
6066
6067         if (hasNormals)
6068         {
6069           anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter));
6070         }
6071       }
6072     }
6073   }
6074   else if (aCmd == CloudSphere)
6075   {
6076     Standard_Real aCenterX       = Draw::Atof (theArgs[2]);
6077     Standard_Real aCenterY       = Draw::Atof (theArgs[3]);
6078     Standard_Real aCenterZ       = Draw::Atof (theArgs[4]);
6079     Standard_Real aRadius        = Draw::Atof (theArgs[5]);
6080     Standard_Integer aNbPoints   = Draw::Atoi (theArgs[6]);
6081
6082     TCollection_AsciiString aDistribution = TCollection_AsciiString(theArgs[7]);
6083     aDistribution.LowerCase();
6084     if ( aDistribution != "surface" && aDistribution != "volume" )
6085     {
6086       std::cout << "Error: wrong arguments! See usage:\n";
6087       theDI.PrintHelp (theArgs[0]);
6088       return 1;
6089     }
6090     Standard_Boolean isSurface = aDistribution == "surface";
6091
6092     gp_Pnt aCenter(aCenterX, aCenterY, aCenterZ);
6093
6094     anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
6095     for (Standard_Integer aPntIt = 0; aPntIt < aNbPoints; ++aPntIt)
6096     {
6097       Standard_Real anAlpha   = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
6098       Standard_Real aBeta     = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
6099       Standard_Real aDistance = isSurface ?
6100         aRadius : (Standard_Real (rand() % aNbPoints) / aNbPoints) * aRadius;
6101
6102       gp_Dir aDir (Cos (anAlpha) * Sin (aBeta),
6103                    Sin (anAlpha),
6104                    Cos (anAlpha) * Cos (aBeta));
6105       gp_Pnt aPoint = aCenter.Translated (aDir.XYZ() * aDistance);
6106
6107       const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
6108       if (toRandColors)
6109       {
6110         Quantity_Color aColor (360.0 * Standard_Real (anIndexOfPoint) / Standard_Real (aNbPoints),
6111                                1.0, 0.5, Quantity_TOC_HLS);
6112         anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
6113       }
6114
6115       if (hasNormals)
6116       {
6117         anArrayPoints->SetVertexNormal (anIndexOfPoint, aDir);
6118       }
6119     }
6120   }
6121
6122   // set array of points in point cloud object
6123   Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud();
6124   aPointCloud->SetPoints (anArrayPoints);
6125   VDisplayAISObject (aName, aPointCloud);
6126   return 0;
6127 }
6128
6129 //=======================================================================
6130 //function : VPriority
6131 //purpose  : Prints or sets the display priority for an object
6132 //=======================================================================
6133
6134 static int VPriority (Draw_Interpretor& theDI,
6135                       Standard_Integer  theArgNum,
6136                       const char**      theArgs)
6137 {
6138   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6139   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
6140   if (aContext.IsNull())
6141   {
6142     std::cout << "Error: no view available, call 'vinit' before!" << std::endl;
6143     return 1;
6144   }
6145
6146   TCollection_AsciiString aLastArg (theArgs[theArgNum - 1]);
6147   Standard_Integer aPriority = -1;
6148   Standard_Integer aNbArgs   = theArgNum;
6149   if (aLastArg.IsIntegerValue())
6150   {
6151     aPriority = aLastArg.IntegerValue();
6152     --aNbArgs;
6153     if (aPriority < 0 || aPriority > 10)
6154     {
6155       std::cout << "Error: the specified display priority value '" << aLastArg
6156                 << "' is outside the valid range [0..10]" << std::endl;
6157       return 1;
6158     }
6159   }
6160   else
6161   {
6162     anUpdateTool.Invalidate();
6163   }
6164
6165   if (aNbArgs < 2)
6166   {
6167     std::cout << "Error: wrong number of arguments! See usage:\n";
6168     theDI.PrintHelp (theArgs[0]);
6169     return 1;
6170   }
6171
6172   for (Standard_Integer anArgIter = 1; anArgIter < aNbArgs; ++anArgIter)
6173   {
6174     if (anUpdateTool.parseRedrawMode (theArgs[anArgIter]))
6175     {
6176       continue;
6177     }
6178
6179     TCollection_AsciiString aName (theArgs[anArgIter]);
6180     Handle(AIS_InteractiveObject) anIObj;
6181     if (GetMapOfAIS().IsBound2 (aName))
6182     {
6183       anIObj = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
6184     }
6185
6186     if (anIObj.IsNull())
6187     {
6188       std::cout << "Error: the object '" << theArgs[1] << "' is not displayed" << std::endl;
6189       return 1;
6190     }
6191
6192     if (aPriority < 1)
6193     {
6194       theDI << aContext->DisplayPriority (anIObj) << " ";
6195     }
6196     else
6197     {
6198       aContext->SetDisplayPriority (anIObj, aPriority);
6199     }
6200   }
6201   return 0;
6202 }
6203
6204 //! Auxiliary class for command vnormals.
6205 class MyShapeWithNormals : public AIS_Shape
6206 {
6207   DEFINE_STANDARD_RTTI_INLINE(MyShapeWithNormals, AIS_Shape);
6208 public:
6209
6210   Standard_Real    NormalLength;
6211   Standard_Integer NbAlongU;
6212   Standard_Integer NbAlongV;
6213   Standard_Boolean ToUseMesh;
6214   Standard_Boolean ToOrient;
6215
6216 public:
6217
6218   //! Main constructor.
6219   MyShapeWithNormals (const TopoDS_Shape& theShape)
6220   : AIS_Shape   (theShape),
6221     NormalLength(10),
6222     NbAlongU  (1),
6223     NbAlongV  (1),
6224     ToUseMesh (Standard_False),
6225     ToOrient  (Standard_False) {}
6226
6227 protected:
6228
6229   //! Comnpute presentation.
6230   virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
6231                         const Handle(Prs3d_Presentation)&           thePrs,
6232                         const Standard_Integer                      theMode) Standard_OVERRIDE
6233   {
6234     AIS_Shape::Compute (thePrsMgr, thePrs, theMode);
6235
6236     NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > aNormalMap;
6237     if (ToUseMesh)
6238     {
6239       DBRep_DrawableShape::addMeshNormals (aNormalMap, myshape, NormalLength);
6240     }
6241     else
6242     {
6243       DBRep_DrawableShape::addSurfaceNormals (aNormalMap, myshape, NormalLength, NbAlongU, NbAlongV);
6244     }
6245
6246     Handle(Graphic3d_Group) aPrsGroup = Prs3d_Root::NewGroup (thePrs);
6247     aPrsGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
6248
6249     const Standard_Real aArrowAngle  = myDrawer->ArrowAspect()->Angle();
6250     const Standard_Real aArrowLength = myDrawer->ArrowAspect()->Length();
6251     for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormalMap);
6252          aFaceIt.More(); aFaceIt.Next())
6253     {
6254       const Standard_Boolean toReverse = ToOrient && aFaceIt.Key().Orientation() == TopAbs_REVERSED;
6255       Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (2 * aFaceIt.Value().Size());
6256       for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aPntIt (aFaceIt.Value()); aPntIt.More(); aPntIt.Next())
6257       {
6258         std::pair<gp_Pnt, gp_Pnt> aPair = aPntIt.Value();
6259         if (toReverse)
6260         {
6261           const gp_Vec aDir = aPair.first.XYZ() - aPair.second.XYZ();
6262           aPair.second = aPair.first.XYZ() + aDir.XYZ();
6263         }
6264
6265         aSegments->AddVertex (aPair.first);
6266         aSegments->AddVertex (aPair.second);
6267         Prs3d_Arrow::Draw (aPrsGroup, aPair.second, gp_Vec(aPair.first, aPair.second), aArrowAngle, aArrowLength);
6268       }
6269
6270       aPrsGroup->AddPrimitiveArray (aSegments);
6271     }
6272   }
6273
6274 };
6275
6276 //=======================================================================
6277 //function : VNormals
6278 //purpose  : Displays/Hides normals calculated on shape geometry or retrieved from triangulation
6279 //=======================================================================
6280 static int VNormals (Draw_Interpretor& theDI,
6281                      Standard_Integer  theArgNum,
6282                      const char**      theArgs)
6283 {
6284   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
6285   if (aContext.IsNull())
6286   {
6287     std::cout << "Error: no view available, call 'vinit' before!\n";
6288     return 1;
6289   }
6290   else if (theArgNum < 2)
6291   {
6292     std::cout << "Error: wrong number of arguments! See usage:\n";
6293     theDI.PrintHelp (theArgs[0]);
6294     return 1;
6295   }
6296
6297   Standard_Integer anArgIter = 1;
6298   Standard_CString aShapeName = theArgs[anArgIter++];
6299   TopoDS_Shape     aShape     = DBRep::Get (aShapeName);
6300   Standard_Boolean isOn = Standard_True;
6301   if (aShape.IsNull())
6302   {
6303     std::cout << "Error: shape with name '" << aShapeName << "' is not found\n";
6304     return 1;
6305   }
6306
6307   ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
6308   Handle(MyShapeWithNormals) aShapePrs;
6309   if (aMap.IsBound2 (aShapeName))
6310   {
6311     aShapePrs = Handle(MyShapeWithNormals)::DownCast (aMap.Find2 (aShapeName));
6312   }
6313
6314   Standard_Boolean isUseMesh = Standard_False;
6315   Standard_Real    aLength = 10.0;
6316   Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
6317   Standard_Boolean isOriented = Standard_False;
6318   for (; anArgIter < theArgNum; ++anArgIter)
6319   {
6320     TCollection_AsciiString aParam (theArgs[anArgIter]);
6321     aParam.LowerCase();
6322     if (anArgIter == 2
6323      && ViewerTest::ParseOnOff (aParam.ToCString(), isOn))
6324     {
6325       continue;
6326     }
6327     else if (aParam == "-usemesh"
6328           || aParam == "-mesh")
6329     {
6330       isUseMesh = Standard_True;
6331     }
6332     else if (aParam == "-length"
6333           || aParam == "-len")
6334     {
6335       ++anArgIter;
6336       aLength = anArgIter < theArgNum ? Draw::Atof (theArgs[anArgIter]) : 0.0;
6337       if (Abs (aLength) <= gp::Resolution())
6338       {
6339         std::cout << "Syntax error: length should not be zero\n";
6340         return 1;
6341       }
6342     }
6343     else if (aParam == "-orient"
6344           || aParam == "-oriented")
6345     {
6346       isOriented = Standard_True;
6347       if (anArgIter + 1 < theArgNum
6348         && ViewerTest::ParseOnOff (theArgs[anArgIter + 1], isOriented))
6349       {
6350         ++anArgIter;
6351       }
6352     }
6353     else if (aParam == "-nbalongu"
6354           || aParam == "-nbu")
6355     {
6356       ++anArgIter;
6357       aNbAlongU = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
6358       if (aNbAlongU < 1)
6359       {
6360         std::cout << "Syntax error: NbAlongU should be >=1\n";
6361         return 1;
6362       }
6363     }
6364     else if (aParam == "-nbalongv"
6365           || aParam == "-nbv")
6366     {
6367       ++anArgIter;
6368       aNbAlongV = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
6369       if (aNbAlongV < 1)
6370       {
6371         std::cout << "Syntax error: NbAlongV should be >=1\n";
6372         return 1;
6373       }
6374     }
6375     else if (aParam == "-nbalong"
6376           || aParam == "-nbuv")
6377     {
6378       ++anArgIter;
6379       aNbAlongU = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
6380       aNbAlongV = aNbAlongU;
6381       if (aNbAlongU < 1)
6382       {
6383         std::cout << "Syntax error: NbAlong should be >=1\n";
6384         return 1;
6385       }
6386     }
6387     else
6388     {
6389       std::cout << "Syntax error: unknwon argument '" << aParam << "'\n";
6390       return 1;
6391     }
6392   }
6393
6394   if (isOn)
6395   {
6396     if (aShapePrs.IsNull())
6397     {
6398       aShapePrs = new MyShapeWithNormals (aShape);
6399     }
6400     aShapePrs->ToUseMesh    = isUseMesh;
6401     aShapePrs->ToOrient     = isOriented;
6402     aShapePrs->NormalLength = aLength;
6403     aShapePrs->NbAlongU     = aNbAlongU;
6404     aShapePrs->NbAlongV     = aNbAlongV;
6405     VDisplayAISObject (aShapeName, aShapePrs);
6406   }
6407   else if (!aShapePrs.IsNull())
6408   {
6409     VDisplayAISObject (aShapeName, new AIS_Shape (aShape));
6410   }
6411
6412   return 0;
6413 }
6414
6415 //=======================================================================
6416 //function : ObjectsCommands
6417 //purpose  :
6418 //=======================================================================
6419
6420 void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
6421 {
6422   const char *group ="AISObjects";
6423
6424   theCommands.Add ("vtrihedron",
6425                    "vtrihedron : vtrihedron name"
6426                    "\n\t\t: [-dispMode {wireframe|shading} ]"
6427                    "\n\t\t: [-origin x y z ]"
6428                    "\n\t\t: [-zaxis u v w -xaxis u v w ]"
6429                    "\n\t\t: [-drawAxes {X|Y|Z|XY|YZ|XZ|XYZ}]"
6430                    "\n\t\t: [-hideLabels {on|off}]"
6431                    "\n\t\t: [-hideArrows {on|off}]"
6432                    "\n\t\t: [-label {XAxis|YAxis|ZAxis} value]"
6433                    "\n\t\t: [-attribute {XAxisLength|YAxisLength|ZAxisLength"
6434                    "\n\t\t:             |TubeRadiusPercent|ConeRadiusPercent"
6435                    "\n\t\t:             |ConeLengthPercent|OriginRadiusPercent"
6436                    "\n\t\t:             |ShadingNumberOfFacettes} value]"
6437                    "\n\t\t: [-color {Origin|XAxis|YAxis|ZAxis|XOYAxis|YOZAxis"
6438                    "\n\t\t:         |XOZAxis|Whole} {r g b | colorName}]"
6439                    "\n\t\t: [-textColor {r g b | colorName}]"
6440                    "\n\t\t: [-arrowColor {r g b | colorName}]"
6441                    "\n\t\t: [-priority {Origin|XAxis|YAxis|ZAxis|XArrow"
6442                    "\n\t\t:            |YArrow|ZArrow|XOYAxis|YOZAxis"
6443                    "\n\t\t:            |XOZAxis|Whole} value]"
6444                    "\n\t\t:"
6445                    "\n\t\t: Creates a new *AIS_Trihedron* object or changes parameters of "
6446                    "\n\t\t: existing trihedron. If no argument is set,"
6447                    "\n\t\t: the default trihedron (0XYZ) is created."
6448                    "\n\t\t: -dispMode mode of visualization: wf - wireframe,"
6449                    "\n\t\t:                                  sh - shading."
6450                    "\n\t\t:               Default value is wireframe."
6451                    "\n\t\t: -origin allows to set trihedron location."
6452                    "\n\t\t: -zaxis/-xaxis allows to set trihedron X and Z"
6453                    "\n\t\t:               directions. The directions should"
6454                    "\n\t\t:               be orthogonal. Y direction is calculated."
6455                    "\n\t\t: -drawAxes allows to set what axes are drawn in the"
6456                    "\n\t\t:           trihedron, default state is XYZ"
6457                    "\n\t\t: -hideLabels allows to show/hide trihedron labels"
6458                    "\n\t\t: -hideArrows allows to show/hide trihedron arrows"
6459                    "\n\t\t: -labels allows to change default X/Y/Z titles of axes"
6460                    "\n\t\t: -attribute sets parameters of trihedron"
6461                    "\n\t\t: -color sets color properties of parts of trihedron"
6462                    "\n\t\t: -textColor sets color properties of trihedron labels"
6463                    "\n\t\t: -arrowColor sets color properties of trihedron arrows"
6464                    "\n\t\t: -priority allows to change default selection priority"
6465                    "\n\t\t: of trihedron components",
6466                    __FILE__,VTrihedron,group);
6467
6468   theCommands.Add("vtri2d",
6469     "vtri2d Name"
6470     "\n\t\t: Creates a plane with a 2D trihedron from an interactively selected face.",
6471     __FILE__,VTrihedron2D ,group);
6472
6473   theCommands.Add("vplanetri",
6474     "vplanetri name"
6475     "\n\t\t: Create a plane from a trihedron selection. If no arguments are set, the default",
6476     __FILE__,VPlaneTrihedron ,group);
6477
6478   theCommands.Add("vsize",
6479     "vsize       : vsize [name(Default=Current)] [size(Default=100)] "
6480     "\n\t\t: Changes the size of a named or selected trihedron."
6481     "\n\t\t: If the name is not defined: it affects the selected trihedrons otherwise nothing is done."
6482     "\n\t\t: If the value is not defined: it is set to 100 by default.",
6483     __FILE__,VSize,group);
6484
6485   theCommands.Add("vaxis",
6486     "vaxis name [Xa] [Ya] [Za] [Xb] [Yb] [Zb]"
6487     "\n\t\t: Creates an axis. If  the values are not defined, an axis is created by interactive selection of two vertices or one edge",
6488     __FILE__,VAxisBuilder,group);
6489
6490   theCommands.Add("vaxispara",
6491     "vaxispara name "
6492     "\n\t\t: Creates an axis by interactive selection of an edge and a vertex.",
6493     __FILE__,VAxisBuilder,group);
6494
6495   theCommands.Add("vaxisortho",
6496     "vaxisortho name "
6497     "\n\t\t: Creates an axis by interactive selection of an edge and a vertex. The axis will be orthogonal to the selected edge.",
6498     __FILE__,VAxisBuilder,group);
6499
6500   theCommands.Add("vpoint",
6501     "vpoint  PointName [Xa] [Ya] [Za] "
6502     "\n\t\t: Creates a point from coordinates. If the values are not defined,"
6503     "\n\t\t: a point is created by interactive selection of a vertice or an edge (in the center of the edge).",
6504     __FILE__,VPointBuilder,group);
6505
6506   theCommands.Add("vplane",
6507     "vplane  PlaneName [AxisName/PlaneName/PointName] [PointName/PointName/PointName] [Nothing/Nothing/PointName] [TypeOfSensitivity {0|1}]"
6508     "\n\t\t: Creates a plane from named or interactively selected entities."
6509     "\n\t\t: TypeOfSensitivity:"
6510     "\n\t\t:   0 - Interior"
6511     "\n\t\t:   1 - Boundary",
6512     __FILE__,VPlaneBuilder,group);
6513
6514   theCommands.Add ("vchangeplane", "vchangeplane usage: \n"
6515     "   vchangeplane <plane_name>"
6516     " [x=center_x y=center_y z=center_z]"
6517     " [dx=dir_x dy=dir_y dz=dir_z]"
6518     " [sx=size_x sy=size_y]"
6519     " [noupdate]\n"
6520     "   - changes parameters of the plane:\n"
6521     "   - x y z     - center\n"
6522     "   - dx dy dz  - normal\n"
6523     "   - sx sy     - plane sizes\n"
6524     "   - noupdate  - do not update/redisplay the plane in context\n"
6525     "   Please enter coordinates in format \"param=value\" in arbitrary order.",
6526     __FILE__, VChangePlane, group);
6527
6528   theCommands.Add("vplanepara",
6529     "vplanepara  PlaneName  "
6530     "\n\t\t: Creates a plane from interactively selected vertex and face.",
6531     __FILE__,VPlaneBuilder,group);
6532
6533   theCommands.Add("vplaneortho",
6534     "vplaneortho  PlaneName  "
6535     "\n\t\t: Creates a plane from interactive selected face and coplanar edge. ",
6536     __FILE__,VPlaneBuilder,group);
6537
6538   theCommands.Add("vline",
6539     "vline LineName [Xa/PointName] [Ya/PointName] [Za] [Xb] [Yb] [Zb]  "
6540     "\n\t\t: Creates a line from coordinates, named or interactively selected vertices. ",
6541     __FILE__,VLineBuilder,group);
6542
6543   theCommands.Add("vcircle",
6544     "vcircle CircleName [PointName PointName PointName IsFilled]\n\t\t\t\t\t[PlaneName PointName Radius IsFilled]"
6545     "\n\t\t: Creates a circle from named or interactively selected entities."
6546     "\n\t\t: Parameter IsFilled is defined as 0 or 1.",
6547     __FILE__,VCircleBuilder,group);
6548
6549   theCommands.Add ("vdrawtext",
6550                    "vdrawtext name text"
6551                    "\n\t\t: [-pos X=0 Y=0 Z=0]"
6552                    "\n\t\t: [-color {R G B|name}=yellow]"
6553                    "\n\t\t: [-halign {left|center|right}=left]"
6554                    "\n\t\t: [-valign {top|center|bottom|topfirstline}=bottom}]"
6555                    "\n\t\t: [-angle angle=0]"
6556                    "\n\t\t: [-zoom {0|1}=0]"
6557                    "\n\t\t: [-height height=16]"
6558                    "\n\t\t: [-aspect {regular|bold|italic|bolditalic}=regular]"
6559                    "\n\t\t: [-font font=Times]"
6560                    "\n\t\t: [-2d]"
6561                    "\n\t\t: [-perspos {X Y Z}=0 0 0], where"
6562                    "\n\t\t X and Y define the coordinate origin in 2d space relative to the view window"
6563                    "\n\t\t Example: X=0 Y=0 is center, X=1 Y=1 is upper right corner etc..."
6564                    "\n\t\t Z coordinate defines the gap from border of view window (except center position)."
6565                    "\n\t\t: [-disptype {blend|decal|shadow|subtitle|dimension|normal}=normal}"
6566                    "\n\t\t: [-subcolor {R G B|name}=white]"
6567                    "\n\t\t: [-noupdate]"
6568                    "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]"
6569                    "\n\t\t: [-flipping]"
6570                    "\n\t\t: Display text label at specified position.",
6571     __FILE__, VDrawText, group);
6572
6573   theCommands.Add("vdrawsphere",
6574     "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]\n",
6575     __FILE__,VDrawSphere,group);
6576
6577   theCommands.Add ("vlocation",
6578                 "vlocation name"
6579       "\n\t\t:   [-reset]"
6580       "\n\t\t:   [-copyFrom otherName]"
6581       "\n\t\t:   [-translate X Y [Z]]"
6582       "\n\t\t:   [-rotate x y z dx dy dz angle]"
6583       "\n\t\t:   [-scale [X Y Z] scale]"
6584       "\n\t\t:   [-mirror x y z dx dy dz]"
6585       "\n\t\t:   [-setLocation X Y [Z]]"
6586       "\n\t\t:   [-setRotation QX QY QZ QW]"
6587       "\n\t\t:   [-setScale [X Y Z] scale]"
6588       "\n\t\t: Object local transformation management:"
6589       "\n\t\t:   -reset       reset transformation to identity"
6590       "\n\t\t:   -translate   translate object"
6591       "\n\t\t:   -rotate      applies rotation to local transformation"
6592       "\n\t\t:   -scale       applies scale    to local transformation"
6593       "\n\t\t:   -mirror      applies mirror   to local transformation"
6594       "\n\t\t:   -setLocation assign object location"
6595       "\n\t\t:   -setRotation assign object rotation (quaternion)"
6596       "\n\t\t:   -setScale    assign object scale factor",
6597         __FILE__, VSetLocation, group);
6598   theCommands.Add ("vsetlocation",
6599                    "alias for vlocation",
6600         __FILE__, VSetLocation, group);
6601
6602   theCommands.Add (
6603     "vcomputehlr",
6604     "vcomputehlr: shape hlrname [ eyex eyey eyez lookx looky lookz ]",
6605     __FILE__, VComputeHLR, group);
6606
6607   theCommands.Add("vdrawparray",
6608     "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id ]",
6609     __FILE__,VDrawPArray,group);
6610
6611   theCommands.Add("vconnect", 
6612     "vconnect name Xo Yo Zo object1 object2 ... [color=NAME]"
6613     "\n\t\t: Creates and displays AIS_ConnectedInteractive object from input object and location.",
6614     __FILE__, VConnect, group);
6615
6616   theCommands.Add("vconnectto",
6617     "vconnectto : instance_name Xo Yo Zo object [-nodisplay|-noupdate|-update]"
6618     "  Makes an instance 'instance_name' of 'object' with position (Xo Yo Zo)."
6619     "\n\t\t:   -nodisplay - only creates interactive object, but not displays it",
6620     __FILE__, VConnectTo,group);
6621
6622   theCommands.Add("vdisconnect",
6623     "vdisconnect assembly_name (object_name | object_number | 'all')"
6624     "  Disconnects all objects from assembly or disconnects object by name or number (use vlistconnected to enumerate assembly children).",
6625     __FILE__,VDisconnect,group);
6626
6627   theCommands.Add("vaddconnected",
6628     "vaddconnected assembly_name object_name"
6629     "Adds object to assembly.",
6630     __FILE__,VAddConnected,group);
6631
6632   theCommands.Add("vlistconnected",
6633     "vlistconnected assembly_name"
6634     "Lists objects in assembly.",
6635     __FILE__,VListConnected,group);
6636
6637
6638   theCommands.Add("vselmode", 
6639                 "vselmode [object] selectionMode {on|off}"
6640       "\n\t\t:            [{-add|-set|-globalOrLocal}=-globalOrLocal]"
6641       "\n\t\t: Switches selection mode for the specified object or for all objects in context."
6642       "\n\t\t: Selection mode is either an integer number specific to Interactive Object,"
6643       "\n\t\t: or sub-shape type in case of AIS_Shape:"
6644       "\n\t\t:   Shape, Vertex, Edge, Wire, Face, Shell, Solid, CompSolid, Compound"
6645       "\n\t\t: The integer mode 0 (Shape in case of AIS_Shape) is reserved for selecting object as whole."
6646       "\n\t\t: Additional options:"
6647       "\n\t\t:  -add           already activated selection modes will be left activated"
6648       "\n\t\t:  -set           already activated selection modes will be deactivated"
6649       "\n\t\t:  -globalOrLocal (default) if new mode is Global selection mode,"
6650       "\n\t\t:                 then active local selection modes will be deactivated"
6651       "\n\t\t:                 and the samthen active local selection modes will be deactivated",
6652     __FILE__, VSetSelectionMode, group);
6653
6654   theCommands.Add("vselnext",
6655     "vselnext : hilight next detected",
6656     __FILE__, VSelectionNext, group);
6657
6658   theCommands.Add("vselprev",
6659     "vselnext : hilight previous detected",
6660     __FILE__, VSelectionPrevious, group);
6661
6662   theCommands.Add("vtriangle",
6663     "vtriangle Name PointName PointName PointName"
6664     "\n\t\t: Creates and displays a filled triangle from named points.", 
6665     __FILE__, VTriangle,group);
6666
6667   theCommands.Add("vsegment",
6668     "vsegment Name PointName PointName"
6669     "\n\t\t: Creates and displays a segment from named points.", 
6670     __FILE__, VSegment,group);
6671
6672   theCommands.Add("vobjzlayer",
6673     "vobjzlayer : set/get object [layerid] - set or get z layer id for the interactive object",
6674     __FILE__, VObjZLayer, group);
6675   
6676   theCommands.Add("vpolygonoffset",
6677     "vpolygonoffset : [object [mode factor units]] - sets/gets polygon offset parameters for an object, without arguments prints the default values",
6678     __FILE__, VPolygonOffset, group);
6679
6680   theCommands.Add ("vshowfaceboundary",
6681     "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]]"
6682     "- turns on/off drawing of face boundaries for ais object "
6683     "and defines boundary line style.",
6684     __FILE__, VShowFaceBoundary, group);
6685
6686   theCommands.Add ("vmarkerstest",
6687                    "vmarkerstest: name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]\n",
6688                    __FILE__, VMarkersTest, group);
6689
6690   theCommands.Add ("text2brep",
6691                    "text2brep: name text"
6692                    "\n\t\t: [-pos X=0 Y=0 Z=0]"
6693                    "\n\t\t: [-halign {left|center|right}=left]"
6694                    "\n\t\t: [-valign {top|center|bottom|topfirstline}=bottom}]"
6695                    "\n\t\t: [-height height=16]"
6696                    "\n\t\t: [-aspect {regular|bold|italic|bolditalic}=regular]"
6697                    "\n\t\t: [-font font=Courier]"
6698                    "\n\t\t: [-composite {on|off}=off]"
6699                    "\n\t\t: [-plane NormX NormY NormZ DirX DirY DirZ]",
6700                    __FILE__, TextToBRep, group);
6701   theCommands.Add ("vfont",
6702                             "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined] [singleStroke]]"
6703                    "\n\t\t:        [find fontName [regular,bold,italic,bolditalic=undefined]]",
6704                    __FILE__, VFont, group);
6705   
6706   theCommands.Add ("vsetedgetype",
6707                    "vsetedgetype usage:\n"
6708                    "vsetedgetype ShapeName [-force] [-type {solid, dash, dot}] [-color R G B] "
6709                    "\n\t\t:        Sets edges type and color for input shape",
6710                    __FILE__, VSetEdgeType, group);
6711
6712   theCommands.Add ("vunsetedgetype",
6713                    "vunsetedgetype usage:\n"
6714                    "vunsetedgetype ShapeName [-force]"
6715                    "\n\t\t:        Unsets edges type and color for input shape",
6716                    __FILE__, VUnsetEdgeType, group);
6717
6718   theCommands.Add ("vvertexmode",
6719                    "vvertexmode [name | -set {isolated | all | inherited} [name1 name2 ...]]\n"
6720                    "vvertexmode - prints the default vertex draw mode\n"
6721                    "vvertexmode name - prints the vertex draw mode of the given object\n"
6722                    "vvertexmode -set {isolated | all | inherited} - sets the default vertex draw mode and updates the mode for all displayed objects\n"
6723                    "vvertexmode -set {isolated | all | inherited} name1 name2 ... - sets the vertex draw mode for the specified object(s)\n",
6724                    __FILE__, VVertexMode, group);
6725
6726   theCommands.Add ("vpointcloud",
6727                    "vpointcloud name shape [-randColor] [-normals] [-noNormals]"
6728                    "\n\t\t: Create an interactive object for arbitary set of points"
6729                    "\n\t\t: from triangulated shape."
6730                    "\n"
6731                    "vpointcloud name x y z r npts {surface|volume}\n"
6732                    "            ... [-randColor] [-normals] [-noNormals]"
6733                    "\n\t\t: Create arbitrary set of points (npts) randomly distributed"
6734                    "\n\t\t: on spheric surface or within spheric volume (x y z r)."
6735                    "\n\t\t:"
6736                    "\n\t\t: Additional options:"
6737                    "\n\t\t:  -randColor - generate random color per point"
6738                    "\n\t\t:  -normals   - generate normal per point (default)"
6739                    "\n\t\t:  -noNormals - do not generate normal per point"
6740                    "\n",
6741                    __FILE__, VPointCloud, group);
6742
6743   theCommands.Add("vpriority",
6744     "vpriority [-noupdate|-update] name [value]\n\t\t  prints or sets the display priority for an object",
6745     __FILE__,
6746     VPriority, group);
6747
6748   theCommands.Add ("vnormals",
6749                    "vnormals usage:\n"
6750                    "vnormals Shape [{on|off}=on] [-length {10}] [-nbAlongU {1}] [-nbAlongV {1}] [-nbAlong {1}]"
6751                    "\n\t\t:        [-useMesh] [-oriented {0}1}=0]"
6752                    "\n\t\t:  Displays/Hides normals calculated on shape geometry or retrieved from triangulation",
6753                    __FILE__, VNormals, group);
6754 }