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