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