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