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