954861d568e6fa1b31bf488613d808e047382b47
[occt.git] / src / ViewerTest / ViewerTest_ObjectCommands.cxx
1 // Created on: 1998-11-12
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ViewerTest.hxx>
18
19 #include <AIS_PlaneTrihedron.hxx>
20
21 #include <Quantity_NameOfColor.hxx>
22 #include <Draw_Interpretor.hxx>
23 #include <Draw.hxx>
24 #include <Draw_Appli.hxx>
25 #include <DBRep.hxx>
26 #include <DBRep_DrawableShape.hxx>
27
28 #include <Font_BRepFont.hxx>
29 #include <Font_BRepTextBuilder.hxx>
30 #include <Font_FontMgr.hxx>
31
32 #include <NCollection_List.hxx>
33
34 #include <OSD_Chronometer.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <V3d_Viewer.hxx>
37 #include <V3d_View.hxx>
38 #include <V3d.hxx>
39
40 #include <AIS_Shape.hxx>
41 #include <AIS_DisplayMode.hxx>
42 #include <AIS_PointCloud.hxx>
43 #include <TColStd_MapOfInteger.hxx>
44 #include <AIS_MapOfInteractive.hxx>
45 #include <ViewerTest_AutoUpdater.hxx>
46 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
47 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
48 #include <ViewerTest_EventManager.hxx>
49
50 #include <TopoDS_Solid.hxx>
51 #include <BRepTools.hxx>
52 #include <BRep_Builder.hxx>
53 #include <TopAbs_ShapeEnum.hxx>
54
55 #include <TopoDS.hxx>
56 #include <BRep_Tool.hxx>
57 #include <TopExp_Explorer.hxx>
58
59 #include <BRepAdaptor_Curve.hxx>
60 #include <BRepAdaptor_Surface.hxx>
61
62 #include <TopAbs.hxx>
63 #include <TopExp.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopoDS_Face.hxx>
67
68 #include <Draw_Window.hxx>
69 #include <AIS_ListIteratorOfListOfInteractive.hxx>
70 #include <AIS_ListOfInteractive.hxx>
71 #include <AIS_ColoredShape.hxx>
72 #include <AIS_DisplayMode.hxx>
73 #include <AIS_Shape.hxx>
74
75 #include <AIS_InteractiveContext.hxx>
76 #include <Geom_Plane.hxx>
77 #include <gp_Pln.hxx>
78 #include <TCollection_ExtendedString.hxx>
79 #include <TCollection_HAsciiString.hxx>
80 #include <GC_MakePlane.hxx>
81 #include <gp_Circ.hxx>
82 #include <AIS_Axis.hxx>
83 #include <Geom_Axis2Placement.hxx>
84 #include <Geom_Axis1Placement.hxx>
85 #include <AIS_Trihedron.hxx>
86 #include <AIS_Axis.hxx>
87 #include <gp_Trsf.hxx>
88 #include <gp_Quaternion.hxx>
89 #include <TopLoc_Location.hxx>
90
91 #include <HLRAlgo_Projector.hxx>
92 #include <HLRBRep_Algo.hxx>
93 #include <HLRBRep_PolyAlgo.hxx>
94 #include <HLRBRep_PolyHLRToShape.hxx>
95 #include <HLRBRep_HLRToShape.hxx>
96 #include <Aspect_Window.hxx>
97
98 #include <Graphic3d_ArrayOfPoints.hxx>
99 #include <Graphic3d_ArrayOfSegments.hxx>
100 #include <Graphic3d_ArrayOfPolylines.hxx>
101 #include <Graphic3d_ArrayOfTriangles.hxx>
102 #include <Graphic3d_ArrayOfTriangleFans.hxx>
103 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
104 #include <Graphic3d_ArrayOfQuadrangles.hxx>
105 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
106 #include <Graphic3d_ArrayOfPolygons.hxx>
107 #include <Graphic3d_AttribBuffer.hxx>
108 #include <Graphic3d_AspectMarker3d.hxx>
109 #include <Graphic3d_Group.hxx>
110 #include <Standard_Real.hxx>
111
112 #include <AIS_Circle.hxx>
113 #include <BRepBuilderAPI_MakeEdge.hxx>
114 #include <BRepBuilderAPI_MakeFace.hxx>
115 #include <BRepBuilderAPI_MakeWire.hxx>
116 #include <Geom_Circle.hxx>
117 #include <GC_MakeCircle.hxx>
118 #include <Select3D_SensitiveCircle.hxx>
119 #include <SelectMgr_EntityOwner.hxx>
120 #include <SelectMgr_Selection.hxx>
121 #include <StdFail_NotDone.hxx>
122 #include <StdPrs_ShadedShape.hxx>
123 #include <TopoDS_Wire.hxx>
124
125 #include <AIS_MultipleConnectedInteractive.hxx>
126 #include <AIS_ConnectedInteractive.hxx>
127 #include <AIS_TextLabel.hxx>
128 #include <TopLoc_Location.hxx>
129 #include <TColStd_ListOfInteger.hxx>
130 #include <TColStd_ListIteratorOfListOfInteger.hxx>
131
132 #include <Select3D_SensitiveSegment.hxx>
133 #include <Select3D_SensitivePrimitiveArray.hxx>
134 #include <Select3D_SensitiveTriangle.hxx>
135 #include <Select3D_SensitiveCurve.hxx>
136 #include <Select3D_SensitivePoint.hxx>
137 #include <BRepAdaptor_Curve.hxx>
138 #include <StdPrs_Curve.hxx>
139
140 #include <BRepExtrema_ExtPC.hxx>
141 #include <BRepExtrema_ExtPF.hxx>
142
143 #include <Prs3d_Arrow.hxx>
144 #include <Prs3d_ArrowAspect.hxx>
145 #include <Prs3d_DatumAttribute.hxx>
146 #include <Prs3d_DatumAspect.hxx>
147 #include <Prs3d_Drawer.hxx>
148 #include <Prs3d_VertexDrawMode.hxx>
149 #include <Prs3d_LineAspect.hxx>
150 #include <Prs3d_PointAspect.hxx>
151 #include <Prs3d_Presentation.hxx>
152 #include <Prs3d_TextAspect.hxx>
153
154 #include <Image_AlienPixMap.hxx>
155 #include <TColStd_HArray1OfAsciiString.hxx>
156 #include <TColStd_HSequenceOfAsciiString.hxx>
157
158 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
159 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
160                                            const Handle(AIS_InteractiveObject)& theAISObj,
161                                            Standard_Boolean theReplaceIfExists = Standard_True);
162 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
163 extern Handle(AIS_InteractiveContext)& TheAISContext();
164
165 namespace
166 {
167   static bool convertToColor (const Handle(TColStd_HSequenceOfAsciiString)& theColorValues,
168                               Quantity_Color& theColor)
169   {
170     const char* anArgs[3] =
171     {
172       theColorValues->Size() >= 1 ? theColorValues->Value (1).ToCString() : "",
173       theColorValues->Size() >= 2 ? theColorValues->Value (2).ToCString() : "",
174       theColorValues->Size() >= 3 ? theColorValues->Value (3).ToCString() : ""
175     };
176     return ViewerTest::ParseColor (theColorValues->Size(), anArgs, theColor) != 0;
177   }
178
179   static bool convertToDatumPart (const TCollection_AsciiString& theValue,
180                                   Prs3d_DatumParts& theDatumPart)
181   {
182     TCollection_AsciiString aValue = theValue;
183     aValue.LowerCase();
184     if      (aValue == "origin")  theDatumPart = Prs3d_DP_Origin;
185     else if (aValue == "xaxis")   theDatumPart = Prs3d_DP_XAxis;
186     else if (aValue == "yaxis")   theDatumPart = Prs3d_DP_YAxis;
187     else if (aValue == "zaxis")   theDatumPart = Prs3d_DP_ZAxis;
188     else if (aValue == "xarrow")  theDatumPart = Prs3d_DP_XArrow;
189     else if (aValue == "yarrow")  theDatumPart = Prs3d_DP_YArrow;
190     else if (aValue == "zarrow")  theDatumPart = Prs3d_DP_ZArrow;
191     else if (aValue == "xoyaxis") theDatumPart = Prs3d_DP_XOYAxis;
192     else if (aValue == "yozaxis") theDatumPart = Prs3d_DP_YOZAxis;
193     else if (aValue == "xozaxis") theDatumPart = Prs3d_DP_XOZAxis;
194     else if (aValue == "whole")   theDatumPart = Prs3d_DP_None;
195     else
196     {
197       return false;
198     }
199     return true;
200   }
201
202   static void convertToDatumParts (const TCollection_AsciiString& theValue,
203                                    NCollection_List<Prs3d_DatumParts>& theParts)
204   {
205     TCollection_AsciiString aValue = theValue;
206     const Standard_Integer aSplitPos = theValue.Search ("|");
207     Prs3d_DatumParts aPart = Prs3d_DP_None;
208     if (aSplitPos > 0)
209     {
210       convertToDatumParts (theValue.SubString (aSplitPos + 1, theValue.Length()), theParts);
211       if (aSplitPos == 1) // first symbol
212       {
213         return;
214       }
215       aValue = theValue.SubString (1, aSplitPos - 1);
216     }
217     if (convertToDatumPart (aValue, aPart))
218     {
219       theParts.Append (aPart);
220     }
221   }
222
223   static bool convertToDatumAttribute (const TCollection_AsciiString& theValue,
224                                        Prs3d_DatumAttribute& theAttribute)
225   {
226     TCollection_AsciiString aValue = theValue;
227     aValue.LowerCase();
228     if      (aValue == "xaxislength")       theAttribute = Prs3d_DA_XAxisLength;
229     else if (aValue == "yaxislength")       theAttribute = Prs3d_DA_YAxisLength;
230     else if (aValue == "zaxislength")       theAttribute = Prs3d_DA_ZAxisLength;
231     else if (aValue == "tuberadiuspercent") theAttribute = Prs3d_DP_ShadingTubeRadiusPercent;
232     else if (aValue == "coneradiuspercent") theAttribute = Prs3d_DP_ShadingConeRadiusPercent;
233     else if (aValue == "conelengthpercent") theAttribute = Prs3d_DP_ShadingConeLengthPercent;
234     else if (aValue == "originradiuspercent") theAttribute = Prs3d_DP_ShadingOriginRadiusPercent;
235     else if (aValue == "shadingnumberoffacettes") theAttribute = Prs3d_DP_ShadingNumberOfFacettes;
236     else
237       return false;
238     return true;
239   }
240
241   static void convertToDatumAttributes (const TCollection_AsciiString& theValue,
242                                         NCollection_List<Prs3d_DatumAttribute>& theAttributes)
243   {
244     TCollection_AsciiString aValue = theValue;
245     const Standard_Integer aSplitPos = theValue.Search ("|");
246     Prs3d_DatumAttribute anAttribute = Prs3d_DA_XAxisLength;
247     if (aSplitPos > 0)
248     {
249       convertToDatumAttributes (theValue.SubString (aSplitPos + 1, theValue.Length()), theAttributes);
250       if (aSplitPos == 1) // first symbol
251       {
252         return;
253       }
254       aValue = theValue.SubString (1, aSplitPos - 1);
255     }
256     if (convertToDatumAttribute (aValue, anAttribute))
257     {
258       theAttributes.Append (anAttribute);
259     }
260   }
261
262   static bool convertToDatumAxes (const TCollection_AsciiString& theValue,
263                                   Prs3d_DatumAxes& theDatumAxes)
264   {
265     TCollection_AsciiString aValue = theValue;
266     aValue.LowerCase();
267     if      (aValue == "x")   theDatumAxes = Prs3d_DA_XAxis;
268     else if (aValue == "y")   theDatumAxes = Prs3d_DA_YAxis;
269     else if (aValue == "z")   theDatumAxes = Prs3d_DA_ZAxis;
270     else if (aValue == "xy")  theDatumAxes = Prs3d_DA_XYAxis;
271     else if (aValue == "zy")  theDatumAxes = Prs3d_DA_YZAxis;
272     else if (aValue == "xz")  theDatumAxes = Prs3d_DA_XZAxis;
273     else if (aValue == "xyz") theDatumAxes = Prs3d_DA_XYZAxis;
274     else
275     {
276       return false;
277     }
278     return true;
279   }
280
281   static Standard_Boolean setTrihedronParams (Standard_Integer  theArgsNb,
282                                               const char** theArgVec,
283                                               Handle(AIS_Trihedron) theTrihedron)
284   {
285     NCollection_DataMap<TCollection_AsciiString, Handle(TColStd_HSequenceOfAsciiString)> aMapOfArgs;
286     TCollection_AsciiString aParseKey;
287     for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
288     {
289       TCollection_AsciiString anArg (theArgVec [anArgIt]);
290       if (anArg.Value (1) == '-'
291       && !anArg.IsRealValue())
292       {
293         aParseKey = anArg;
294         aParseKey.Remove (1);
295         aParseKey.LowerCase();
296         std::string aKey = aParseKey.ToCString();
297         aMapOfArgs.Bind (aParseKey, new TColStd_HSequenceOfAsciiString());
298         continue;
299       }
300
301       if (aParseKey.IsEmpty())
302       {
303         continue;
304       }
305
306       aMapOfArgs (aParseKey)->Append (anArg);
307     }
308
309     // Check parameters
310     if ((aMapOfArgs.IsBound ("xaxis") && !aMapOfArgs.IsBound ("zaxis"))
311     || (!aMapOfArgs.IsBound ("xaxis") &&  aMapOfArgs.IsBound ("zaxis")))
312     {
313       std::cout << "Syntax error: -xaxis and -zaxis parameters are to set together.\n";
314       return Standard_False;
315     }
316
317     Handle(TColStd_HSequenceOfAsciiString) aValues;
318     Handle(Geom_Axis2Placement) aComponent = theTrihedron->Component();
319     if (aMapOfArgs.Find ("origin", aValues))
320     {
321       aComponent->SetLocation (gp_Pnt (aValues->Value (1).RealValue(),
322                                        aValues->Value (2).RealValue(),
323                                        aValues->Value (3).RealValue()));
324     }
325     Handle(TColStd_HSequenceOfAsciiString) aXValues, aZValues;
326     if (aMapOfArgs.Find ("xaxis", aXValues) && aMapOfArgs.Find ("zaxis", aZValues))
327     {
328       gp_Dir aXDir (aXValues->Value (1).RealValue(),
329                     aXValues->Value (2).RealValue(),
330                     aXValues->Value (3).RealValue());
331
332       gp_Dir aZDir (aZValues->Value (1).RealValue(),
333                     aZValues->Value (2).RealValue(),
334                     aZValues->Value (3).RealValue());
335
336       if (!aZDir.IsNormal (aXDir, M_PI / 180.0))
337       {
338         std::cout << "Syntax error - parameters 'xaxis' and 'zaxis' are not applied as VectorX is not normal to VectorZ\n";
339         return Standard_False;
340       }
341
342       aComponent->SetAx2 (gp_Ax2 (aComponent->Location(), aZDir, aXDir));
343     }
344
345     if (aMapOfArgs.Find ("dispmode", aValues))
346     {
347       TCollection_AsciiString aValue (aValues->Value (1));
348       bool isWireframe = true;
349       if (aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
350         isWireframe = false;
351       theTrihedron->SetDatumDisplayMode (isWireframe ? Prs3d_DM_WireFrame
352                                                      : Prs3d_DM_Shaded);
353     }
354
355     if (aMapOfArgs.Find ("hidelabels", aValues))
356     {
357       Standard_Boolean toHideLabels = Standard_True;
358       if (aValues->Size() == 1)
359       {
360         ViewerTest::ParseOnOff (aValues->First().ToCString(), toHideLabels);
361       }
362       else if (aValues->Size() != 0)
363       {
364         std::cout << "Syntax error: -hidelabels expects parameter 'on' or 'off' after.\n";
365         return Standard_False;
366       }
367
368       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
369       {
370         theTrihedron->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
371       }
372       theTrihedron->Attributes()->DatumAspect()->SetDrawLabels (!toHideLabels);
373     }
374
375     if (aMapOfArgs.Find ("hidearrows", aValues))
376     {
377       Standard_Boolean toHideArrows = Standard_True;
378       if (aValues->Size() == 1)
379       {
380         ViewerTest::ParseOnOff (aValues->First().ToCString(), toHideArrows);
381       }
382       else if (aValues->Size() != 0)
383       {
384         std::cout << "Syntax error: -hidearrows expects parameter 'on' or 'off' after.\n";
385         return Standard_False;
386       }
387
388       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
389       {
390         theTrihedron->Attributes()->SetDatumAspect (new Prs3d_DatumAspect());
391       }
392       theTrihedron->Attributes()->DatumAspect()->SetDrawArrows (!toHideArrows);
393     }
394
395     if (aMapOfArgs.Find ("color", aValues))
396     {
397       NCollection_List<Prs3d_DatumParts> aParts;
398       if (aValues->Size() < 2)
399       {
400         std::cout << "Syntax error: -color wrong parameters.\n";
401         return Standard_False;
402       }
403
404       convertToDatumParts (aValues->Value(1), aParts);
405       aValues->Remove (1); // datum part is processed
406       Quantity_Color aColor;
407       if (!convertToColor (aValues, aColor))
408       {
409         std::cout << "Syntax error: -color wrong parameters.\n";
410         return Standard_False;
411       }
412
413       for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator (aParts); anIterator.More(); anIterator.Next())
414       {
415         Prs3d_DatumParts aDatumPart = anIterator.Value();
416         if (aDatumPart == Prs3d_DP_None)
417         {
418           theTrihedron->SetColor (aColor);
419         }
420         else
421         {
422           theTrihedron->SetDatumPartColor (aDatumPart, aColor);
423         }
424       }
425     }
426
427     if (aMapOfArgs.Find ("textcolor", aValues))
428     {
429       Quantity_Color aColor;
430       if (!convertToColor (aValues, aColor))
431       {
432         std::cout << "Syntax error: -textcolor wrong parameters.\n";
433         return Standard_False;
434       }
435       theTrihedron->SetTextColor (aColor);
436     }
437
438     if (aMapOfArgs.Find ("arrowcolor", aValues))
439     {
440       Quantity_Color aColor;
441       if (!convertToColor (aValues, aColor))
442       {
443         std::cout << "Syntax error: -arrowcolor wrong parameters.\n";
444         return Standard_False;
445       }
446       theTrihedron->SetArrowColor (aColor);
447     }
448
449     if (aMapOfArgs.Find ("attribute", aValues))
450     {
451       NCollection_List<Prs3d_DatumAttribute> anAttributes;
452       if (aValues->Size() != 2)
453       {
454         std::cout << "Syntax error: -attribute wrong parameters.\n";
455         return Standard_False;
456       }
457
458       convertToDatumAttributes (aValues->Value (1), anAttributes);
459       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
460         theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
461       for (NCollection_List<Prs3d_DatumAttribute>::Iterator anIterator (anAttributes); anIterator.More(); anIterator.Next())
462       {
463         theTrihedron->Attributes()->DatumAspect()->SetAttribute (anIterator.Value(), aValues->Value (2).RealValue());
464       }
465     }
466
467     if (aMapOfArgs.Find ("priority", aValues))
468     {
469       Prs3d_DatumParts aDatumPart;
470       if (aValues->Size() < 2
471       || !convertToDatumPart (aValues->Value (1), aDatumPart))
472       {
473         std::cout << "Syntax error: -priority wrong parameters.\n";
474         return Standard_False;
475       }
476       theTrihedron->SetSelectionPriority (aDatumPart, aValues->Value (2).IntegerValue());
477     }
478
479     if (aMapOfArgs.Find ("labels", aValues)
480      || aMapOfArgs.Find ("label", aValues))
481     {
482       Prs3d_DatumParts aDatumPart = Prs3d_DP_None;
483       if (aValues->Size() >= 2
484        && convertToDatumPart(aValues->Value(1), aDatumPart)
485        && aDatumPart >= Prs3d_DP_XAxis
486        && aDatumPart <= Prs3d_DP_ZAxis) // labels are set to axes only
487       {
488         theTrihedron->SetLabel (aDatumPart, aValues->Value (2));
489       }
490       else
491       {
492         std::cout << "Syntax error: -labels wrong parameters.\n";
493         return Standard_False;
494       }
495     }
496
497     if (aMapOfArgs.Find ("drawaxes", aValues))
498     {
499       Prs3d_DatumAxes aDatumAxes = Prs3d_DA_XAxis;
500       if (aValues->Size() < 1
501       || !convertToDatumAxes (aValues->Value (1), aDatumAxes))
502       {
503         std::cout << "Syntax error: -drawaxes wrong parameters.\n";
504         return Standard_False;
505       }
506       if (!theTrihedron->Attributes()->HasOwnDatumAspect())
507         theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
508       theTrihedron->Attributes()->DatumAspect()->SetDrawDatumAxes (aDatumAxes);
509     }
510     return Standard_True;
511   }
512
513   //! Auxiliary function to parse font aspect style argument
514   static Standard_Boolean parseFontStyle (const TCollection_AsciiString& theArg,
515                                           Font_FontAspect&               theAspect)
516   {
517     if (theArg == "regular"
518      || *theArg.ToCString() == 'r')
519     {
520       theAspect = Font_FA_Regular;
521       return Standard_True;
522     }
523     else if (theArg == "bolditalic"
524           || theArg == "bold-italic"
525           || theArg == "italic-bold"
526           || theArg == "italicbold")
527     {
528       theAspect = Font_FA_BoldItalic;
529       return Standard_True;
530     }
531     else if (theArg == "bold"
532           || *theArg.ToCString() == 'b')
533     {
534       theAspect = Font_FA_Bold;
535       return Standard_True;
536     }
537     else if (theArg == "italic"
538           || *theArg.ToCString() == 'i')
539     {
540       theAspect = Font_FA_Italic;
541       return Standard_True;
542     }
543     return Standard_False;
544   }
545
546   //! Auxiliary function to parse font strict level argument
547   static Standard_Integer parseFontStrictLevel (const Standard_Integer theArgNb,
548                                                 const char**           theArgVec,
549                                                 Font_StrictLevel&      theLevel)
550   {
551     if (theArgNb >= 1)
552     {
553       TCollection_AsciiString anArg (theArgVec[0]);
554       anArg.LowerCase();
555       if (anArg == "any")
556       {
557         theLevel = Font_StrictLevel_Any;
558         return 1;
559       }
560       else if (anArg == "aliases")
561       {
562         theLevel = Font_StrictLevel_Aliases;
563         return 1;
564       }
565       else if (anArg == "strict")
566       {
567         theLevel = Font_StrictLevel_Strict;
568         return 1;
569       }
570     }
571     theLevel = Font_StrictLevel_Strict;
572     return 0;
573   }
574 }
575
576 //==============================================================================
577 //function : Vtrihedron 2d
578 //purpose  : Create a plane with a 2D  trihedron from a faceselection
579 //Draw arg : vtri2d  name
580 //==============================================================================
581 static int VTrihedron2D (Draw_Interpretor& /*theDI*/,
582                          Standard_Integer  theArgsNum,
583                          const char**      theArgVec)
584 {
585   if (theArgsNum != 2)
586   {
587     std::cerr << theArgVec[0]<< " error.\n";
588     return 1;
589   }
590
591   TopTools_ListOfShape aShapes;
592   ViewerTest::GetSelectedShapes (aShapes);
593
594   if (aShapes.Extent() != 1)
595   {
596     std::cerr << "Error: wrong number of selected shapes.\n";
597     return 1;
598   }
599
600   const TopoDS_Shape& aShape = aShapes.First();
601
602   TopoDS_Face     aFace = TopoDS::Face (aShape);
603   TopExp_Explorer aFaceExp (aFace, TopAbs_EDGE);
604   TopoDS_Edge     anEdge0 = TopoDS::Edge (aFaceExp.Current());
605
606   gp_Pnt A,B,C;
607   if (aFaceExp.More())
608   {
609     aFaceExp.Next();
610     TopoDS_Edge anEdge1 = TopoDS::Edge (aFaceExp.Current() );
611     BRepAdaptor_Curve aCurve0 (anEdge0);
612     BRepAdaptor_Curve aCurve1 (anEdge1);
613     A = aCurve1.Value (0.1);
614     B = aCurve1.Value (0.9);
615     C = aCurve0.Value (0.5);
616   }
617   else
618   {
619     BRepAdaptor_Curve aCurve0 (anEdge0);
620     A = aCurve0.Value (0.1);
621     B = aCurve0.Value (0.9);
622     C = aCurve0.Value (0.5);
623   }
624
625   GC_MakePlane aMkPlane (A,B,C);
626
627   Handle(AIS_PlaneTrihedron) anAISPlaneTri = new AIS_PlaneTrihedron (aMkPlane.Value());
628   TCollection_AsciiString aName (theArgVec[1]);
629
630   VDisplayAISObject (aName, anAISPlaneTri);
631
632   return 0;
633 }
634
635 //=======================================================================
636 //function : VTrihedron
637 //purpose  :
638 //=======================================================================
639 static int VTrihedron (Draw_Interpretor& ,
640                        Standard_Integer theArgsNb,
641                        const char** theArgVec)
642 {
643   if (theArgsNb < 2)
644   {
645     std::cout << "Syntax error: the wrong number of input parameters.\n";
646     return 1;
647   }
648
649   TCollection_AsciiString aName (theArgVec[1]);
650   gp_Pln aWorkingPlane;
651   Standard_Boolean toUpdate = Standard_True;
652
653   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
654   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
655
656   Handle(AIS_Trihedron) aTrihedron;
657   Handle(AIS_InteractiveObject) anObject;
658   if (GetMapOfAIS().Find2 (aName, anObject))
659   {
660     aTrihedron = Handle(AIS_Trihedron)::DownCast (anObject);
661     if (aTrihedron.IsNull())
662     {
663       std::cout << "Syntax error: no trihedron with this name.\n";
664       return 1;
665     }
666   }
667   else
668   {
669     Handle(Geom_Axis2Placement) aPlacement = new Geom_Axis2Placement (gp_Pnt (0.0, 0.0, 0.0),
670                                                                       gp::DZ(), gp::DX());
671     aTrihedron = new AIS_Trihedron (aPlacement);
672   }
673
674   if (!setTrihedronParams (theArgsNb, theArgVec, aTrihedron))
675   {
676     return 1;
677   }
678
679   // Redisplay a dimension after parameter changing.
680   if (ViewerTest::GetAISContext()->IsDisplayed (aTrihedron))
681   {
682     ViewerTest::GetAISContext()->Redisplay (aTrihedron, toUpdate);
683   }
684   else
685   {
686     VDisplayAISObject (theArgVec[1], aTrihedron);
687   }
688
689   return 0;
690 }
691
692 //==============================================================================
693 //function : VSize
694 //author   : ege
695 //purpose  : Change the size of a named or selected trihedron
696 //           if no name : it affects the trihedrons witch are selected otherwise nothing is donne
697 //           if no value, the value is set at 100 by default
698 //Draw arg : vsize [name] [size]
699 //==============================================================================
700
701 static int VSize (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
702
703 {
704   // Declaration de booleens
705   Standard_Boolean             ThereIsName;
706   Standard_Boolean             ThereIsCurrent;
707   Standard_Real                value;
708   Standard_Boolean             hascol;
709
710   Quantity_Color col = Quantity_NOC_BLACK;
711
712   // Verification des arguments
713   if ( argc>3 ) {di<<argv[0]<<" Syntaxe error\n"; return 1;}
714
715   // Verification du nombre d'arguments
716   if (argc==1)      {ThereIsName=Standard_False;value=100;}
717   else if (argc==2) {ThereIsName=Standard_False;value=Draw::Atof(argv[1]);}
718   else              {ThereIsName=Standard_True;value=Draw::Atof(argv[2]);}
719
720   // On set le booleen ThereIsCurrent
721   if (TheAISContext() -> NbSelected() > 0) {ThereIsCurrent=Standard_True;}
722   else {ThereIsCurrent=Standard_False;}
723
724
725
726   //===============================================================
727   // Il n'y a pas de nom  mais des objets selectionnes
728   //===============================================================
729   if (!ThereIsName && ThereIsCurrent)
730   {
731
732     ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName
733       it (GetMapOfAIS());
734
735     while ( it.More() ) {
736
737       Handle(AIS_InteractiveObject) aShape = it.Key1();
738
739       if (!aShape.IsNull() &&  TheAISContext()->IsSelected(aShape) )
740       {
741
742         // On verifie que l'AIS InteraciveObject selectionne est bien
743         // un AIS_Trihedron
744         if (aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3) {
745
746           if (aShape->HasColor())
747           {
748             hascol = Standard_True;
749
750             // On recupere la couleur de aShape
751             aShape->Color (col);
752           }
753           else
754           {
755             hascol = Standard_False;
756           }
757
758           // On downcast aShape  de AIS_InteractiveObject a AIS_Trihedron
759           // pour lui appliquer la methode SetSize()
760           Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
761
762           // C'est bien un triedre,on chage sa valeur!
763           aTrihedron->SetSize(value);
764
765           // On donne la couleur au Trihedron
766           if(hascol)   aTrihedron->SetColor(col);
767           else         aTrihedron->UnsetColor();
768
769
770           // The trihedron hasn't be errased from the map
771           // so you just have to redisplay it
772           TheAISContext() ->Redisplay(aTrihedron,Standard_False);
773
774         }
775
776       }
777
778       it.Next();
779     }
780
781     TheAISContext() ->UpdateCurrentViewer();
782   }
783
784   //===============================================================
785   // Il n'y a pas d'arguments et aucuns objets selectionne Rien A Faire!
786   //===============================================================
787
788
789
790   //===============================================================
791   // Il y a un nom de triedre passe en argument
792   //===============================================================
793   if (ThereIsName) {
794     TCollection_AsciiString name=argv[1];
795
796     // on verifie que ce nom correspond bien a une shape
797     Handle(AIS_InteractiveObject) aShape;
798     if (GetMapOfAIS().Find2(name, aShape))
799     {
800       // On verifie que l'AIS InteraciveObject est bien
801       // un AIS_Trihedron
802       if (!aShape.IsNull() &&
803         aShape->Type()==AIS_KOI_Datum && aShape->Signature()==3)
804       {
805         if (aShape->HasColor())
806         {
807           hascol=Standard_True;
808
809           // On recupere la couleur de aShape
810           aShape->Color (col);
811         }
812         else
813         {
814           hascol = Standard_False;
815         }
816
817         // On downcast aShape de AIS_InteractiveObject a AIS_Trihedron
818         // pour lui appliquer la methode SetSize()
819         Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast (aShape);
820
821         // C'est bien un triedre,on chage sa valeur
822         aTrihedron->SetSize(value);
823
824         // On donne la couleur au Trihedron
825         if(hascol)   aTrihedron->SetColor(col);
826         else         aTrihedron->UnsetColor();
827
828         // The trihedron hasn't be errased from the map
829         // so you just have to redisplay it
830         TheAISContext() ->Redisplay(aTrihedron,Standard_False);
831
832         TheAISContext() ->UpdateCurrentViewer();
833       }
834     }
835   }
836   return 0;
837 }
838
839
840 //==============================================================================
841
842 //==============================================================================
843 //function : VPlaneTrihedron
844 //purpose  : Create a plane from a trihedron selection. If no arguments are set, the default
845 //Draw arg : vplanetri  name
846 //==============================================================================
847 #include <AIS_Plane.hxx>
848
849
850
851 static int VPlaneTrihedron (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
852
853 {
854   // Verification des arguments
855   if ( argc!=2) {di<<argv[0]<<" error\n"; return 1;}
856
857   if (TheAISContext()->NbSelected() != 1)
858   {
859     std::cerr << "Error: Wrong number of selected shapes.\n";
860     return 1;
861   }
862
863   TheAISContext()->InitSelected();
864   Handle(AIS_InteractiveObject) aTest = TheAISContext()->SelectedInteractive();
865   Handle(AIS_Plane) aPlane = Handle(AIS_Plane)::DownCast (aTest);
866   if (aPlane.IsNull())
867   {
868     std::cerr << "Error: Selected shape is not a plane.\n";
869     return 1;
870   }
871
872   VDisplayAISObject (argv[1], aPlane);
873
874   return 0;
875 }
876
877
878
879 //==============================================================================
880 // Fonction        First click      2de click
881 //
882 // vaxis           vertex           vertex
883 //                 edge             None
884 // vaxispara       edge             vertex
885 // vaxisortho      edge             Vertex
886 // vaxisinter      Face             Face
887 //==============================================================================
888
889 //==============================================================================
890 //function : VAxisBuilder
891 //purpose  :
892 //Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
893 //==============================================================================
894 #include <TopoDS_Edge.hxx>
895 #include <TopoDS_Vertex.hxx>
896 #include <TopExp.hxx>
897 #include <Geom_Line.hxx>
898
899 static int VAxisBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
900 {
901   // Declarations
902   Standard_Boolean HasArg;
903   TCollection_AsciiString name;
904
905   // Verification
906   if (argc<2 || argc>8 ) {di<<" Syntaxe error\n";return 1;}
907   if (argc==8) HasArg=Standard_True;
908   else HasArg=Standard_False;
909
910   name=argv[1];
911
912   TopTools_ListOfShape aShapes;
913   ViewerTest::GetSelectedShapes (aShapes);
914
915   // Cas ou il y a des arguments
916   // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
917   if (HasArg) {
918     Standard_Real coord[6];
919     for(Standard_Integer i=0;i<=5;i++){
920       coord[i]=Draw::Atof(argv[2+i]);
921     }
922     gp_Pnt p1(coord[0],coord[1],coord[2]), p2(coord[3],coord[4],coord[5]) ;
923
924     gp_Vec myVect (p1,p2);
925     Handle(Geom_Line) myLine=new Geom_Line (p1 ,myVect );
926     Handle(AIS_Axis) TheAxis=new AIS_Axis (myLine );
927     GetMapOfAIS().Bind (TheAxis,name);
928     TheAISContext()->Display(TheAxis, Standard_True);
929   }
930
931   // Pas d'arguments
932   else {
933     // fonction vaxis
934     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
935     if ( !strcasecmp(argv[0], "vaxis")) {
936       if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
937       {
938         std::cerr << "Error: Wrong number of selected shapes.\n";
939         return 1;
940       }
941
942       const TopoDS_Shape& aShapeA = aShapes.First();
943       if (aShapeA.ShapeType() == TopAbs_VERTEX)
944       {
945         if (aShapes.Extent() != 2)
946         {
947           std::cerr << "Error: Wron number of selected shapes.\n";
948           return 1;
949         }
950
951         const TopoDS_Shape& aShapeB = aShapes.Last();
952         if (aShapeB.ShapeType() != TopAbs_VERTEX)
953         {
954           std::cerr << "Syntax error: You should select two vertices or one edge.\n";
955           return 1;
956         }
957
958         // Construction de l'axe
959         gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
960         gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
961         gp_Vec V (A,B);
962         gp_Dir D (V);
963         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
964         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
965         GetMapOfAIS().Bind (TheAxis,name);
966         TheAISContext()->Display (TheAxis, Standard_True);
967       }
968       else
969       {
970         TopoDS_Edge    ed =TopoDS::Edge (aShapeA);
971         TopoDS_Vertex  Va,Vb;
972         TopExp::Vertices(ed,Va,Vb );
973         gp_Pnt A=BRep_Tool::Pnt(Va);
974         gp_Pnt B=BRep_Tool::Pnt(Vb);
975         gp_Vec  V (A,B);
976         gp_Dir   D (V);
977         Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (A,D);
978         Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
979         GetMapOfAIS().Bind (TheAxis,name);
980         TheAISContext()->Display (TheAxis, Standard_True);
981       }
982
983     }
984
985     // Fonction axispara
986     // Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis from AIS)
987     else if ( !strcasecmp(argv[0], "vaxispara"))
988     {
989       if (aShapes.Extent() != 2)
990       {
991         std::cerr << "Error: Wrong number of selected shapes.\n";
992         return 1;
993       }
994
995       const TopoDS_Shape& aShapeA = aShapes.First();
996       const TopoDS_Shape& aShapeB = aShapes.Last();
997       if (!(aShapeA.ShapeType() == TopAbs_EDGE
998          && aShapeB.ShapeType() == TopAbs_VERTEX))
999       {
1000         std::cerr << "Syntax error: You should select face and then vertex.\n";
1001         return 1;
1002       }
1003
1004       TopoDS_Edge    ed=TopoDS::Edge (aShapeA);
1005       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1006       TopoDS_Vertex  Va,Vc;
1007       TopExp::Vertices(ed,Va,Vc );
1008       gp_Pnt A=BRep_Tool::Pnt(Va);
1009       gp_Pnt C=BRep_Tool::Pnt(Vc);
1010       gp_Vec  V (A,C);
1011       gp_Dir   D (V);
1012       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
1013       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
1014       GetMapOfAIS().Bind (TheAxis,name);
1015       TheAISContext()->Display (TheAxis, Standard_True);
1016
1017     }
1018
1019     // Fonction axisortho
1020     else
1021     {
1022       if (aShapes.Extent() != 2)
1023       {
1024         std::cerr << "Error: Wrong number of selected shapes.\n";
1025         return 1;
1026       }
1027
1028       const TopoDS_Shape& aShapeA = aShapes.First();
1029       const TopoDS_Shape& aShapeB = aShapes.Last();
1030       if (!(aShapeA.ShapeType() == TopAbs_EDGE
1031          && aShapeB.ShapeType() == TopAbs_VERTEX))
1032       {
1033         std::cerr << "Syntax error: You should select face and then vertex.\n";
1034         return 1;
1035       }
1036
1037       // Construction de l'axe
1038       TopoDS_Edge    ed=TopoDS::Edge(aShapeA) ;
1039       gp_Pnt B=BRep_Tool::Pnt(TopoDS::Vertex(aShapeB) );
1040       TopoDS_Vertex  Va,Vc;
1041       TopExp::Vertices(ed,Va,Vc );
1042       gp_Pnt A=BRep_Tool::Pnt(Va);
1043       gp_Pnt C=BRep_Tool::Pnt(Vc);
1044       gp_Pnt E(A.Y()+A.Z()-C.Y()-C.Z()  ,C.X()-A.X() ,C.X()-A.X() );
1045       gp_Vec  V (A,E);
1046       gp_Dir   D (V);
1047       Handle(Geom_Axis1Placement) OrigineAndVect=new Geom_Axis1Placement (B,D);
1048       Handle(AIS_Axis) TheAxis=new AIS_Axis (OrigineAndVect);
1049       GetMapOfAIS().Bind (TheAxis,name);
1050       TheAISContext()->Display (TheAxis, Standard_True);
1051
1052     }
1053
1054   }
1055   return 0;
1056 }
1057
1058
1059 //==============================================================================
1060 // Fonction        First click      Result
1061 //
1062 // vpoint          vertex           AIS_Point=Vertex
1063 //                 edge             AIS_Point=Middle of the edge
1064 //==============================================================================
1065
1066 //==============================================================================
1067 //function : VPointBuilder
1068 //purpose  : Build an AIS_Point from coordinates or with a selected vertex or edge
1069 //Draw arg : vpoint PoinName [Xa] [Ya] [Za]
1070 //==============================================================================
1071 #include <TopoDS_Edge.hxx>
1072 #include <TopoDS_Vertex.hxx>
1073 #include <TopExp.hxx>
1074 #include <AIS_Point.hxx>
1075 #include <Geom_CartesianPoint.hxx>
1076
1077 static int VPointBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1078 {
1079   // Declarations
1080   Standard_Boolean HasArg;
1081   TCollection_AsciiString name;
1082
1083   // Verification
1084   if (argc<2 || argc>5 ) {di<<" Syntaxe error\n";return 1;}
1085   if (argc==5) HasArg=Standard_True;
1086   else HasArg=Standard_False;
1087
1088   name=argv[1];
1089
1090   // Il y a des arguments: teste l'unique constructeur AIS_Pnt::AIS_Pnt(Point from Geom)
1091   if (HasArg) {
1092     Standard_Real thecoord[3];
1093     for(Standard_Integer i=0;i<=2;i++)
1094       thecoord[i]=Draw::Atof(argv[2+i]);
1095     Handle(Geom_CartesianPoint )  myGeomPoint= new Geom_CartesianPoint (thecoord[0],thecoord[1],thecoord[2]);
1096     Handle(AIS_Point)  myAISPoint=new AIS_Point(myGeomPoint );
1097     GetMapOfAIS().Bind (myAISPoint,name);
1098     TheAISContext()->Display (myAISPoint, Standard_True);
1099   }
1100
1101   // Il n'a pas d'arguments
1102   else
1103   {
1104     TopTools_ListOfShape aShapes;
1105     ViewerTest::GetSelectedShapes (aShapes);
1106
1107     if (aShapes.Extent() != 1)
1108     {
1109       std::cerr << "Error: Wrong number of selected shapes.\n";
1110       std::cerr << "\tYou should select one edge or vertex.\n";
1111       return 1;
1112     }
1113
1114     const TopoDS_Shape& aShapeA = aShapes.First();
1115
1116     if (aShapeA.ShapeType()==TopAbs_VERTEX )
1117     {
1118       gp_Pnt A=BRep_Tool::Pnt(TopoDS::Vertex(aShapeA ) );
1119       Handle(Geom_CartesianPoint) myGeomPoint= new Geom_CartesianPoint (A );
1120       Handle(AIS_Point)  myAISPoint = new AIS_Point  (myGeomPoint );
1121       GetMapOfAIS().Bind(myAISPoint,name);
1122       TheAISContext()->Display (myAISPoint, Standard_True);
1123     }
1124     else
1125     {
1126       TopoDS_Edge myEdge=TopoDS::Edge(aShapeA);
1127       TopoDS_Vertex myVertexA,myVertexB;
1128       TopExp::Vertices (myEdge ,myVertexA ,myVertexB );
1129       gp_Pnt A=BRep_Tool::Pnt(myVertexA );
1130       gp_Pnt B=BRep_Tool::Pnt(myVertexB );
1131       // M est le milieu de [AB]
1132       Handle(Geom_CartesianPoint) myGeomPointM= new Geom_CartesianPoint ( (A.X()+B.X())/2  , (A.Y()+B.Y())/2  , (A.Z()+B.Z())/2  );
1133       Handle(AIS_Point)  myAISPointM = new AIS_Point  (myGeomPointM );
1134       GetMapOfAIS().Bind(myAISPointM,name);
1135       TheAISContext()->Display (myAISPointM, Standard_True);
1136     }
1137
1138   }
1139   return 0;
1140
1141 }
1142
1143 //==============================================================================
1144 // Function        1st click   2de click  3de click
1145 // vplane          Vertex      Vertex     Vertex
1146 //                 Vertex      Edge
1147 //                 Edge        Vertex
1148 //                 Face
1149 // vplanepara      Face        Vertex
1150 //                 Vertex      Face
1151 // vplaneortho     Face        Edge
1152 //                 Edge        Face
1153 //==============================================================================
1154
1155 //==============================================================================
1156 //function : VPlaneBuilder
1157 //purpose  : Build an AIS_Plane from selected entities or Named AIS components
1158 //Draw arg : vplane PlaneName [AxisName]  [PointName] [TypeOfSensitivity]
1159 //                            [PointName] [PointName] [PointName] [TypeOfSensitivity]
1160 //                            [PlaneName] [PointName] [TypeOfSensitivity]
1161 //==============================================================================
1162
1163 static Standard_Integer VPlaneBuilder (Draw_Interpretor& /*di*/,
1164                                        Standard_Integer argc,
1165                                        const char** argv)
1166 {
1167   // Declarations
1168   Standard_Boolean hasArg;
1169   TCollection_AsciiString aName;
1170
1171   // Verification
1172   if (argc<2 || argc>6 )
1173   {
1174     std::cout<<" Syntax error\n";
1175     return 1;
1176   }
1177   if (argc == 6 || argc==5 || argc==4)
1178     hasArg=Standard_True;
1179   else 
1180     hasArg=Standard_False;
1181
1182   aName=argv[1];
1183
1184   // There are some arguments
1185   if (hasArg)
1186   {
1187     Handle(AIS_InteractiveObject) aShapeA;
1188     if (!GetMapOfAIS().Find2 (argv[2], aShapeA))
1189     {
1190       std::cout<<"vplane: error 1st name doesn't exist in the GetMapOfAIS()\n";
1191       return 1;
1192     }
1193
1194     // The first argument is an AIS_Point
1195     if (!aShapeA.IsNull() &&
1196         aShapeA->Type()==AIS_KOI_Datum &&
1197         aShapeA->Signature()==1)
1198     {
1199         // The second argument must also be an AIS_Point
1200         Handle(AIS_InteractiveObject) aShapeB;
1201         if (argc<5 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
1202         {
1203           std::cout<<"vplane: error 2nd name doesn't exist in the GetMapOfAIS()\n";
1204           return 1;
1205         }
1206         // If B is not an AIS_Point
1207         if (aShapeB.IsNull() ||
1208           (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1209         {
1210           std::cout<<"vplane: error 2nd object is expected to be an AIS_Point.\n";
1211           return 1;
1212         }
1213         // The third object is an AIS_Point
1214         Handle(AIS_InteractiveObject) aShapeC;
1215         if (!GetMapOfAIS().Find2(argv[4], aShapeC)) 
1216         {
1217           std::cout<<"vplane: error 3d name doesn't exist in the GetMapOfAIS().\n";
1218           return 1; 
1219         }
1220         // If C is not an AIS_Point
1221         if (aShapeC.IsNull() ||
1222           (!(aShapeC->Type()==AIS_KOI_Datum && aShapeC->Signature()==1)))
1223         {
1224           std::cout<<"vplane: error 3d object is expected to be an AIS_Point.\n";
1225           return 1;
1226         }
1227
1228         // Treatment of objects A, B, C
1229         // Downcast an AIS_IO to AIS_Point
1230         Handle(AIS_Point) anAISPointA = Handle(AIS_Point)::DownCast( aShapeA);
1231         Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast( aShapeB);
1232         Handle(AIS_Point) anAISPointC = Handle(AIS_Point)::DownCast( aShapeC);
1233
1234         Handle(Geom_CartesianPoint ) aCartPointA = 
1235           Handle(Geom_CartesianPoint)::DownCast( anAISPointA->Component());
1236
1237         Handle(Geom_CartesianPoint ) aCartPointB = 
1238           Handle(Geom_CartesianPoint)::DownCast( anAISPointB->Component());
1239
1240         Handle(Geom_CartesianPoint ) aCartPointC = 
1241           Handle(Geom_CartesianPoint)::DownCast( anAISPointC->Component());
1242
1243         // Verification that the three points are different
1244         if(Abs(aCartPointB->X()-aCartPointA->X())<=Precision::Confusion() &&
1245            Abs(aCartPointB->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1246            Abs(aCartPointB->Z()-aCartPointA->Z())<=Precision::Confusion())
1247         {
1248           // B=A
1249           std::cout<<"vplane error: same points\n";return 1;
1250         }
1251         if(Abs(aCartPointC->X()-aCartPointA->X())<=Precision::Confusion() &&
1252            Abs(aCartPointC->Y()-aCartPointA->Y())<=Precision::Confusion() &&
1253            Abs(aCartPointC->Z()-aCartPointA->Z())<=Precision::Confusion())
1254         {
1255           // C=A
1256           std::cout<<"vplane error: same points\n";return 1;
1257         }
1258         if(Abs(aCartPointC->X()-aCartPointB->X())<=Precision::Confusion() &&
1259            Abs(aCartPointC->Y()-aCartPointB->Y())<=Precision::Confusion() &&
1260            Abs(aCartPointC->Z()-aCartPointB->Z())<=Precision::Confusion())
1261         {
1262           // C=B
1263           std::cout<<"vplane error: same points\n";return 1;
1264         }
1265
1266         gp_Pnt A = aCartPointA->Pnt();
1267         gp_Pnt B = aCartPointB->Pnt();
1268         gp_Pnt C = aCartPointC->Pnt();
1269
1270         // Construction of AIS_Plane
1271         GC_MakePlane MkPlane (A,B,C);
1272         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1273         Handle(AIS_Plane)  anAISPlane = new AIS_Plane(aGeomPlane );
1274         GetMapOfAIS().Bind (anAISPlane,aName );
1275         if (argc == 6)
1276         {
1277           Standard_Integer aType = Draw::Atoi (argv[5]);
1278           if (aType != 0 && aType != 1)
1279           {
1280             std::cout << "vplane error: wrong type of sensitivity!\n"
1281                       << "Should be one of the following values:\n"
1282                       << "0 - Interior\n"
1283                       << "1 - Boundary"
1284                       << std::endl;
1285             return 1;
1286           }
1287           else
1288           {
1289             anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1290           }
1291         }
1292         TheAISContext()->Display (anAISPlane, Standard_True);
1293       }
1294
1295       // The first argument is an AIS_Axis
1296       // Creation of a plane orthogonal to the axis through a point
1297     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==2 ) {
1298       // The second argument should be an AIS_Point
1299       Handle(AIS_InteractiveObject) aShapeB;
1300       if (argc!=4 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
1301       {
1302         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1303         return 1;
1304       }
1305       // If B is not an AIS_Point
1306       if (aShapeB.IsNull() ||
1307         (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1308       {
1309         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1310         return 1;
1311       }
1312
1313       // Treatment of objects A and B
1314       Handle(AIS_Axis) anAISAxisA = Handle(AIS_Axis)::DownCast(aShapeA);
1315       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1316
1317       Handle(Geom_Line ) aGeomLineA = anAISAxisA ->Component();
1318       Handle(Geom_Point) aGeomPointB = anAISPointB->Component()  ;
1319
1320       gp_Ax1 anAxis = aGeomLineA->Position();
1321       Handle(Geom_CartesianPoint) aCartPointB = 
1322         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1323
1324       gp_Dir D =anAxis.Direction();
1325       gp_Pnt B = aCartPointB->Pnt();
1326
1327       // Construction of AIS_Plane
1328       Handle(Geom_Plane) aGeomPlane = new Geom_Plane(B,D);
1329       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane,B );
1330       GetMapOfAIS().Bind (anAISPlane,aName );
1331       if (argc == 5)
1332       {
1333         Standard_Integer aType = Draw::Atoi (argv[4]);
1334         if (aType != 0 && aType != 1)
1335         {
1336           std::cout << "vplane error: wrong type of sensitivity!\n"
1337                     << "Should be one of the following values:\n"
1338                     << "0 - Interior\n"
1339                     << "1 - Boundary"
1340                     << std::endl;
1341           return 1;
1342         }
1343         else
1344         {
1345           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1346         }
1347       }
1348       TheAISContext()->Display (anAISPlane, Standard_True);
1349
1350     }
1351     // The first argumnet is an AIS_Plane
1352     // Creation of a plane parallel to the plane passing through the point
1353     else if (aShapeA->Type()==AIS_KOI_Datum && aShapeA->Signature()==7)
1354     {
1355       // The second argument should be an AIS_Point
1356       Handle(AIS_InteractiveObject) aShapeB;
1357       if (argc!=4 || !GetMapOfAIS().Find2 (argv[3], aShapeB))
1358       {
1359         std::cout<<"vplane: error 2d name doesn't exist in the GetMapOfAIS()\n";
1360         return 1;
1361       }
1362       // B should be an AIS_Point
1363       if (aShapeB.IsNull() ||
1364          (!(aShapeB->Type()==AIS_KOI_Datum && aShapeB->Signature()==1)))
1365       {
1366         std::cout<<"vplane: error 2d object is expected to be an AIS_Point\n";
1367         return 1;
1368       }
1369
1370       // Treatment of objects A and B
1371       Handle(AIS_Plane) anAISPlaneA = Handle(AIS_Plane)::DownCast(aShapeA);
1372       Handle(AIS_Point) anAISPointB = Handle(AIS_Point)::DownCast(aShapeB);
1373
1374       Handle(Geom_Plane) aNewGeomPlane= anAISPlaneA->Component();
1375       Handle(Geom_Point) aGeomPointB = anAISPointB->Component();
1376
1377       Handle(Geom_CartesianPoint) aCartPointB = 
1378         Handle(Geom_CartesianPoint)::DownCast(aGeomPointB);
1379       gp_Pnt B= aCartPointB->Pnt();
1380
1381       // Construction of an AIS_Plane
1382       Handle(AIS_Plane) anAISPlane = new AIS_Plane(aNewGeomPlane, B);
1383       GetMapOfAIS().Bind (anAISPlane, aName);
1384       if (argc == 5)
1385       {
1386         Standard_Integer aType = Draw::Atoi (argv[4]);
1387         if (aType != 0 && aType != 1)
1388         {
1389           std::cout << "vplane error: wrong type of sensitivity!\n"
1390                     << "Should be one of the following values:\n"
1391                     << "0 - Interior\n"
1392                     << "1 - Boundary"
1393                     << std::endl;
1394           return 1;
1395         }
1396         else
1397         {
1398           anAISPlane->SetTypeOfSensitivity (Select3D_TypeOfSensitivity (aType));
1399         }
1400       }
1401       TheAISContext()->Display (anAISPlane, Standard_True);
1402     }
1403     // Error
1404     else
1405     {
1406       std::cout<<"vplane: error 1st object is not an AIS\n";
1407       return 1;
1408     }
1409   }
1410   // There are no arguments
1411   else 
1412   {
1413     TopTools_ListOfShape aShapes;
1414     ViewerTest::GetSelectedShapes (aShapes);
1415
1416     // Function vplane
1417     // Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, Standard_Boolean )
1418     if (!strcasecmp(argv[0], "vplane"))
1419     {
1420       if (aShapes.Extent() < 1 || aShapes.Extent() > 3)
1421       {
1422         std::cerr << "Error: Wront number of selected shapes.\n";
1423         std::cerr << "\tYou should one of variant: face, edge and vertex or three vertices.\n";
1424         return 1;
1425       }
1426
1427       const TopoDS_Shape& aShapeA = aShapes.First();
1428       if (aShapeA.ShapeType() == TopAbs_VERTEX)
1429       {
1430         if (aShapes.Extent() == 2)
1431         {
1432           const TopoDS_Shape& aShapeB = aShapes.Last();
1433           if (aShapeB.ShapeType() != TopAbs_EDGE)
1434           {
1435             std::cerr << "Syntax error: Together with vertex should be edge.\n";
1436             return 1;
1437           }
1438
1439           // Verify that the vertex is not on the edge ShapeB
1440           TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
1441           TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
1442
1443           BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
1444           if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1445           {
1446             // The vertex is on the edge
1447             std::cout<<" vplane: error point is on the edge\n";
1448             return 1;
1449           }
1450           else
1451           {
1452             gp_Pnt A = BRep_Tool::Pnt(aVertA);
1453             TopoDS_Vertex aVBa, aVBb;
1454             TopExp::Vertices(anEdgeB ,aVBa ,aVBb);
1455             gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
1456             gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
1457             GC_MakePlane MkPlane (A, aBa, aBb);
1458             Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1459             Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1460             GetMapOfAIS().Bind (anAISPlane, aName);
1461             TheAISContext()->Display (anAISPlane, Standard_True);
1462           }
1463         }
1464         else if (aShapes.Extent() == 3)
1465         {
1466           TopTools_ListOfShape::Iterator anIter (aShapes);
1467
1468           anIter.Next();
1469           const TopoDS_Shape& aShapeB = anIter.Value();
1470
1471           anIter.Next();
1472           const TopoDS_Shape& aShapeC = anIter.Value();
1473
1474           if (!(aShapeB.ShapeType() == TopAbs_VERTEX
1475              && aShapeC.ShapeType() == TopAbs_VERTEX))
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           gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
1482           gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
1483           gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
1484           GC_MakePlane MkPlane(A, B, C);
1485           Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1486           Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1487           GetMapOfAIS().Bind (anAISPlane, aName);
1488           TheAISContext()->Display (anAISPlane, Standard_True);
1489         }
1490         else
1491         {
1492           std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
1493           return 1;
1494         }
1495       }
1496       else if (aShapeA.ShapeType() == TopAbs_EDGE)
1497       {
1498         if (aShapes.Extent() != 2)
1499         {
1500           std::cerr << "Error: wrong number of selected shapes.\n";
1501           return 1;
1502         }
1503
1504         const TopoDS_Shape& aShapeB = aShapes.Last();
1505         if (aShapeB.ShapeType() != TopAbs_VERTEX)
1506         {
1507           std::cerr << "Syntax error: Together with edge should be vertex.\n";
1508           return 1;
1509         }
1510
1511         // Check that the vertex aShapeB is not on the edge
1512         TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
1513         TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
1514
1515         BRepExtrema_ExtPC OrthoProj (aVertB, anEdgeA);
1516         if (OrthoProj.SquareDistance(1)<Precision::Approximation())
1517         {
1518           // The vertex is on the edge
1519           std::cout<<" vplane: error point is on the edge\n";
1520           return 1;
1521         }
1522
1523         gp_Pnt B = BRep_Tool::Pnt(aVertB);
1524         TopoDS_Vertex aVAa, aVAb;
1525         TopExp::Vertices(anEdgeA, aVAa, aVAb);
1526         gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1527         gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1528         GC_MakePlane MkPlane (B,Aa,Ab);
1529         Handle(Geom_Plane) aGeomPlane = MkPlane.Value();
1530         Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane);
1531         GetMapOfAIS().Bind (anAISPlane ,aName);
1532         TheAISContext()->Display (anAISPlane, Standard_True);
1533       }
1534       else if (aShapeA.ShapeType() == TopAbs_FACE)
1535       {
1536         TopoDS_Face aFace = TopoDS::Face(aShapeA);
1537         BRepAdaptor_Surface aSurface (aFace, Standard_False);
1538         if (aSurface.GetType()==GeomAbs_Plane)
1539         {
1540           gp_Pln aPlane = aSurface.Plane();
1541           Handle(Geom_Plane) aGeomPlane = new Geom_Plane(aPlane);
1542           Handle(AIS_Plane) anAISPlane = new AIS_Plane(aGeomPlane);
1543           GetMapOfAIS().Bind (anAISPlane, aName);
1544           TheAISContext()->Display (anAISPlane, Standard_True);
1545         }
1546         else
1547         {
1548           std::cout<<" vplane: error\n";
1549           return 1;
1550         }
1551       }
1552       else
1553       {
1554         std::cerr << "Syntax error: You should one of variant: face, edge and vertex or three vertices.\n";
1555         return 1;
1556       }
1557     }
1558
1559     // Function vPlanePara
1560     // ===================
1561     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
1562     else if (!strcasecmp(argv[0], "vplanepara"))
1563     {
1564       if (aShapes.Extent() != 2)
1565       {
1566         std::cerr << "Error: Wrong number of selected shapes.\n";
1567         return 1;
1568       }
1569
1570       const TopoDS_Shape* aShapeA = &aShapes.First();
1571       const TopoDS_Shape* aShapeB = &aShapes.Last();
1572       if (aShapeA->ShapeType() != TopAbs_VERTEX)
1573       {
1574         std::swap (aShapeA, aShapeB);
1575       }
1576
1577       if (!(aShapeA->ShapeType() == TopAbs_VERTEX
1578          && aShapeB->ShapeType() == TopAbs_FACE))
1579       {
1580         std::cerr << "Syntax error: you should select face and vertex.\n";
1581         return 1;
1582       }
1583
1584       gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(*aShapeA));
1585
1586       TopoDS_Face aFace = TopoDS::Face(*aShapeB);
1587       BRepAdaptor_Surface aSurface (aFace, Standard_False);
1588       if (aSurface.GetType() == GeomAbs_Plane)
1589       {
1590         gp_Pln aPlane = aSurface.Plane();
1591         // Construct a plane parallel to aGeomPlane through A
1592         aPlane.SetLocation(A);
1593         Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1594         Handle(AIS_Plane) aAISPlane = new AIS_Plane (aGeomPlane, A);
1595         GetMapOfAIS().Bind (aAISPlane ,aName);
1596         TheAISContext()->Display (aAISPlane, Standard_True);
1597       }
1598       else
1599       {
1600         std::cerr << "Error: Builded surface is not a plane.\n";
1601         return 1;
1602       }
1603     }
1604
1605     // Function vplaneortho
1606     // ====================
1607     // test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
1608     else
1609     {
1610       if (aShapes.Extent() != 2)
1611       {
1612         std::cerr << "Error: wrong number of selected shapes.\n";
1613         return 1;
1614       }
1615
1616       const TopoDS_Shape* aShapeA = &aShapes.First();
1617       const TopoDS_Shape* aShapeB = &aShapes.Last();
1618
1619       if (aShapeA->ShapeType() != TopAbs_EDGE)
1620       {
1621         std::swap (aShapeA, aShapeB);
1622       }
1623
1624       if (!(aShapeA->ShapeType() == TopAbs_EDGE
1625          && aShapeB->ShapeType() == TopAbs_FACE))
1626       {
1627         std::cerr << "Error: you should select edge and face.\n";
1628         return 1;
1629       }
1630
1631       // Construction of plane
1632       TopoDS_Edge anEdgeA = TopoDS::Edge(*aShapeA);
1633       TopoDS_Vertex aVAa, aVAb;
1634       TopExp::Vertices(anEdgeA, aVAa, aVAb);
1635       gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
1636       gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
1637       gp_Vec ab (Aa,Ab);
1638
1639       gp_Dir Dab (ab);
1640       // Creation of rotation axis
1641       gp_Ax1 aRotAxis (Aa,Dab);
1642
1643       TopoDS_Face aFace = TopoDS::Face(*aShapeB);
1644       // The edge must be parallel to the face
1645       BRepExtrema_ExtPF aHeightA (aVAa, aFace);
1646       BRepExtrema_ExtPF aHeightB (aVAb, aFace);
1647       // Compare to heights
1648       if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
1649           >Precision::Confusion())
1650       {
1651         // the edge is not parallel to the face
1652         std::cout<<" vplaneortho error: the edge is not parallel to the face\n";
1653         return 1;
1654       }
1655       // the edge is OK
1656       BRepAdaptor_Surface aSurface (aFace, Standard_False);
1657       if (aSurface.GetType()==GeomAbs_Plane)
1658       {
1659         gp_Pln aPlane = aSurface.Plane();
1660         // It rotates a half turn round the axis of rotation
1661         aPlane.Rotate(aRotAxis , M_PI/2);
1662
1663         Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
1664         // constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
1665         gp_Pnt aMiddle ((Aa.X()+Ab.X() )/2 ,(Aa.Y()+Ab.Y() )/2 ,(Aa.Z()+Ab.Z() )/2 );
1666         Handle(AIS_Plane) anAISPlane = new AIS_Plane (aGeomPlane, aMiddle);
1667         GetMapOfAIS().Bind (anAISPlane, aName);
1668         TheAISContext()->Display (anAISPlane, Standard_True);
1669       }
1670       else
1671       {
1672         std::cout<<" vplaneortho: error\n";
1673         return 1;
1674       }
1675     }
1676   }
1677   return 0;
1678 }
1679
1680 //===============================================================================================
1681 //function : VChangePlane
1682 //purpose  :
1683 //===============================================================================================
1684 static int VChangePlane (Draw_Interpretor& /*theDi*/, Standard_Integer theArgsNb, const char** theArgVec)
1685 {
1686   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
1687   if (aContextAIS.IsNull())
1688   {
1689     std::cout << theArgVec[0] << "AIS context is not available.\n";
1690     return 1;
1691   }
1692
1693   if (theArgsNb < 3 || theArgsNb > 11)
1694   {
1695     std::cerr << theArgVec[0] 
1696               << ": incorrect number of command arguments.\n"
1697               << "Type help for more information.\n";
1698     return 1;
1699   }
1700
1701   TCollection_AsciiString aName (theArgVec[1]);
1702
1703   Handle(AIS_Plane) aPlane = GetMapOfAIS().IsBound2(aName)
1704     ? Handle(AIS_Plane)::DownCast (GetMapOfAIS().Find2 (aName))
1705     : NULL;
1706
1707   if ( aPlane.IsNull() )
1708   {
1709     std::cout << theArgVec[0] 
1710               << ": there is no interactive plane with the given name."
1711               << "Type help for more information.\n";
1712     return 1;
1713   }
1714
1715   Standard_Real aCenterX = aPlane->Center().X();
1716   Standard_Real aCenterY = aPlane->Center().Y();
1717   Standard_Real aCenterZ = aPlane->Center().Z();
1718
1719   Standard_Real aDirX = aPlane->Component()->Axis().Direction().X();
1720   Standard_Real aDirY = aPlane->Component()->Axis().Direction().Y();
1721   Standard_Real aDirZ = aPlane->Component()->Axis().Direction().Z();
1722
1723   Standard_Real aSizeX = 0.0;
1724   Standard_Real aSizeY = 0.0;
1725   aPlane->Size (aSizeX, aSizeY);
1726   Standard_Boolean isUpdate = Standard_True;
1727
1728   TCollection_AsciiString aPName, aPValue;
1729   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
1730   {
1731     const TCollection_AsciiString anArg = theArgVec[anArgIt];
1732     TCollection_AsciiString anArgCase = anArg;
1733     anArgCase.UpperCase();
1734     if (ViewerTest::SplitParameter (anArg, aPName, aPValue))
1735     {
1736       aPName.UpperCase();
1737       if (aPName.IsEqual ("X"))
1738       {
1739         aCenterX = aPValue.RealValue();
1740       }
1741       else if (aPName.IsEqual ("Y"))
1742       {
1743         aCenterY = aPValue.RealValue();
1744       }
1745       else if (aPName.IsEqual ("Z"))
1746       {
1747         aCenterZ = aPValue.RealValue();
1748       }
1749       else if (aPName.IsEqual ("DX"))
1750       {
1751         aDirX = aPValue.RealValue();
1752       }
1753       else if (aPName.IsEqual ("DY"))
1754       {
1755         aDirY = aPValue.RealValue();
1756       }
1757       else if (aPName.IsEqual ("DZ"))
1758       {
1759         aDirZ = aPValue.RealValue();
1760       }
1761       else if (aPName.IsEqual ("SX"))
1762       {
1763         aSizeX = aPValue.RealValue();
1764       }
1765       else if (aPName.IsEqual ("SY"))
1766       {
1767         aSizeY = aPValue.RealValue();
1768       }
1769     }
1770     else if (anArg.IsEqual ("NOUPDATE"))
1771     {
1772       isUpdate = Standard_False;
1773     }
1774   }
1775
1776   gp_Dir aDirection (aDirX, aDirY, aDirZ);
1777   gp_Pnt aCenterPnt (aCenterX, aCenterY, aCenterZ);
1778   aPlane->SetCenter (aCenterPnt);
1779   aPlane->SetComponent (new Geom_Plane (aCenterPnt, aDirection));
1780   aPlane->SetSize (aSizeX, aSizeY);
1781
1782   aContextAIS->Update (aPlane, isUpdate);
1783
1784   return 0;
1785 }
1786
1787 //==============================================================================
1788 // Fonction  vline
1789 // ---------------  Uniquement par parametre. Pas de selection dans le viewer.
1790 //==============================================================================
1791
1792 //==============================================================================
1793 //function : VLineBuilder
1794 //purpose  : Build an AIS_Line
1795 //Draw arg : vline LineName  [AIS_PointName] [AIS_PointName]
1796 //                           [Xa] [Ya] [Za]   [Xb] [Yb] [Zb]
1797 //==============================================================================
1798 #include <Geom_CartesianPoint.hxx>
1799 #include <AIS_Line.hxx>
1800
1801
1802 static int VLineBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1803 {
1804   // Verifications
1805   if (argc!=4 && argc!=8 && argc!=2 )  {di<<"vline error: number of arguments not correct \n";return 1; }
1806
1807   // On recupere les parametres
1808   Handle(AIS_InteractiveObject) theShapeA;
1809   Handle(AIS_InteractiveObject) theShapeB;
1810
1811   // Parametres: AIS_Point AIS_Point
1812   // ===============================
1813   if (argc==4) {
1814     GetMapOfAIS().Find2 (argv[2], theShapeA);
1815     // On verifie que c'est bien une AIS_Point
1816     if (!theShapeA.IsNull() &&
1817       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1) {
1818         // on recupere le deuxieme AIS_Point
1819         GetMapOfAIS().Find2 (argv[3], theShapeB);
1820         if (theShapeB.IsNull() ||
1821           (!(theShapeB->Type()==AIS_KOI_Datum && theShapeB->Signature()==1)))
1822         {
1823           di <<"vline error: wrong type of 2de argument.\n";
1824           return 1;
1825         }
1826       }
1827     else {di <<"vline error: wrong type of 1st argument.\n";return 1; }
1828     // Les deux parametres sont du bon type. On verifie que les points ne sont pas confondus
1829     Handle(AIS_Point) theAISPointA= Handle(AIS_Point)::DownCast (theShapeA);
1830     Handle(AIS_Point) theAISPointB= Handle(AIS_Point)::DownCast (theShapeB);
1831
1832     Handle(Geom_Point ) myGeomPointBA=  theAISPointA->Component();
1833     Handle(Geom_CartesianPoint ) myCartPointA= Handle(Geom_CartesianPoint)::DownCast (myGeomPointBA);
1834     //    Handle(Geom_CartesianPoint ) myCartPointA= *(Handle(Geom_CartesianPoint)*)& (theAISPointA->Component() ) ;
1835
1836     Handle(Geom_Point ) myGeomPointB=  theAISPointB->Component();
1837     Handle(Geom_CartesianPoint ) myCartPointB= Handle(Geom_CartesianPoint)::DownCast (myGeomPointB);
1838     //    Handle(Geom_CartesianPoint ) myCartPointB= *(Handle(Geom_CartesianPoint)*)& (theAISPointB->Component() ) ;
1839
1840     if (myCartPointB->X()==myCartPointA->X() && myCartPointB->Y()==myCartPointA->Y() && myCartPointB->Z()==myCartPointA->Z() ) {
1841       // B=A
1842       di<<"vline error: same points\n";return 1;
1843     }
1844     // Les deux points sont OK...Construction de l'AIS_Line (en faite, le segment AB)
1845     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1846     GetMapOfAIS().Bind(theAISLine,argv[1] );
1847     TheAISContext()->Display (theAISLine, Standard_True);
1848
1849   }
1850
1851   // Parametres 6 Reals
1852   // ==================
1853
1854   else if (argc==8) {
1855     // On verifie que les deux points ne sont pas confondus
1856
1857     Standard_Real coord[6];
1858     for(Standard_Integer i=0;i<=2;i++){
1859       coord[i]=Draw::Atof(argv[2+i]);
1860       coord[i+3]=Draw::Atof(argv[5+i]);
1861     }
1862
1863     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint (coord[0],coord[1],coord[2] );
1864     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint (coord[3],coord[4],coord[5] );
1865
1866     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1867     GetMapOfAIS().Bind(theAISLine,argv[1] );
1868     TheAISContext()->Display (theAISLine, Standard_True);
1869
1870   }
1871
1872   // Pas de parametres: Selection dans le viewer.
1873   // ============================================
1874
1875   else
1876   {
1877     TopTools_ListOfShape aShapes;
1878     ViewerTest::GetSelectedShapes (aShapes);
1879     if (aShapes.Extent() != 2)
1880     {
1881       std::cerr << "Error: wrong number of selected shapes.\n";
1882       return 1;
1883     }
1884
1885     const TopoDS_Shape& aShapeA = aShapes.First();
1886     const TopoDS_Shape& aShapeB = aShapes.Last();
1887
1888     if (!(aShapeA.ShapeType() == TopAbs_VERTEX
1889        && aShapeB.ShapeType() == TopAbs_VERTEX))
1890     {
1891       std::cerr << "Error: you should select two different vertex.\n";
1892       return 1;
1893     }
1894
1895     // Construction de la line
1896     gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
1897     gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
1898
1899     Handle(Geom_CartesianPoint ) myCartPointA=new Geom_CartesianPoint(A);
1900     Handle(Geom_CartesianPoint ) myCartPointB=new Geom_CartesianPoint(B);
1901
1902     Handle(AIS_Line) theAISLine= new AIS_Line(myCartPointA,myCartPointB );
1903     GetMapOfAIS().Bind(theAISLine,argv[1] );
1904     TheAISContext()->Display (theAISLine, Standard_True);
1905   }
1906
1907   return 0;
1908 }
1909
1910 //==============================================================================
1911 // class   : FilledCircle
1912 // purpose : creates filled circle based on AIS_InteractiveObject 
1913 //           and Geom_Circle.
1914 //           This class is used to check method Matches() of class 
1915 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True, 
1916 //           because none of AIS classes provides creation of 
1917 //           Select3D_SensitiveCircle with member myFillStatus = Standard_True 
1918 //           (look method ComputeSelection() )
1919 //============================================================================== 
1920
1921 Handle(Geom_Circle) CreateCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1922 {
1923   gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.))); 
1924   gp_Circ aCirc(anAxes, theRadius);
1925   Handle(Geom_Circle) aCircle = new Geom_Circle(aCirc);
1926   return aCircle;
1927 }
1928
1929 class FilledCircle : public AIS_InteractiveObject 
1930 {
1931 public:
1932     // CASCADE RTTI
1933     DEFINE_STANDARD_RTTI_INLINE(FilledCircle,AIS_InteractiveObject); 
1934
1935     FilledCircle(gp_Pnt theCenter, Standard_Real theRadius);
1936     FilledCircle(Handle(Geom_Circle) theCircle);
1937
1938 private:
1939     TopoDS_Face ComputeFace();
1940
1941     // Virtual methods implementation
1942     void Compute (  const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
1943                   const Handle(Prs3d_Presentation)& thePresentation,
1944                   const Standard_Integer theMode) Standard_OVERRIDE;
1945
1946     void ComputeSelection (  const Handle(SelectMgr_Selection)& theSelection, 
1947                            const Standard_Integer theMode) Standard_OVERRIDE;
1948
1949 protected:
1950     Handle(Geom_Circle) myCircle;
1951     Standard_Boolean myFilledStatus;
1952
1953 }; 
1954
1955
1956 FilledCircle::FilledCircle(gp_Pnt theCenter, Standard_Real theRadius) 
1957 {
1958   myCircle = CreateCircle(theCenter, theRadius);
1959   myFilledStatus = Standard_True;
1960 }
1961
1962 FilledCircle::FilledCircle(Handle(Geom_Circle) theCircle) 
1963 {
1964   myCircle = theCircle;
1965   myFilledStatus = Standard_True;
1966 }
1967
1968 TopoDS_Face FilledCircle::ComputeFace() 
1969 {
1970   // Create edge from myCircle 
1971   BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ());
1972   TopoDS_Edge anEdge = anEdgeMaker.Edge(); 
1973
1974   // Create wire from anEdge 
1975   BRepBuilderAPI_MakeWire aWireMaker(anEdge);
1976   TopoDS_Wire aWire = aWireMaker.Wire();
1977
1978   // Create face from aWire
1979   BRepBuilderAPI_MakeFace aFaceMaker(aWire);
1980   TopoDS_Face aFace = aFaceMaker.Face();
1981
1982   return aFace;
1983 }
1984
1985 void FilledCircle::Compute(const Handle(PrsMgr_PresentationManager3d) &/*thePresentationManager*/, 
1986                            const Handle(Prs3d_Presentation) &thePresentation, 
1987                            const Standard_Integer theMode) 
1988 {
1989   thePresentation->Clear();
1990
1991   TopoDS_Face aFace = ComputeFace();
1992
1993   if (aFace.IsNull()) return;
1994   if (theMode != 0) return;
1995
1996   StdPrs_ShadedShape::Add(thePresentation, aFace, myDrawer);
1997 }
1998
1999 void FilledCircle::ComputeSelection(const Handle(SelectMgr_Selection) &theSelection, 
2000                                     const Standard_Integer /*theMode*/)
2001 {
2002   Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner(this);
2003   Handle(Select3D_SensitiveCircle) aSensitiveCircle = new Select3D_SensitiveCircle(anEntityOwner, 
2004       myCircle, myFilledStatus);
2005   theSelection->Add(aSensitiveCircle);
2006 }
2007
2008 //==============================================================================
2009 // Fonction  vcircle
2010 // -----------------  Uniquement par parametre. Pas de selection dans le viewer.
2011 //==============================================================================
2012
2013 //==============================================================================
2014 //function : VCircleBuilder
2015 //purpose  : Build an AIS_Circle
2016 //Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled
2017 //                              PointName PointName PointName IsFilled
2018 //==============================================================================
2019
2020 void DisplayCircle (Handle (Geom_Circle) theGeomCircle,
2021                     TCollection_AsciiString theName, 
2022                     Standard_Boolean isFilled) 
2023 {
2024   Handle(AIS_InteractiveObject) aCircle;
2025   if (isFilled) 
2026   {
2027     aCircle = new FilledCircle(theGeomCircle);
2028   }
2029   else
2030   {
2031     aCircle = new AIS_Circle(theGeomCircle);
2032     Handle(AIS_Circle)::DownCast (aCircle)->SetFilledCircleSens (Standard_False);
2033   }
2034
2035   // Check if there is an object with given name
2036   // and remove it from context
2037   if (GetMapOfAIS().IsBound2(theName)) 
2038   {
2039     Handle(AIS_InteractiveObject) anInterObj = GetMapOfAIS().Find2(theName);
2040     TheAISContext()->Remove(anInterObj, Standard_False);
2041     GetMapOfAIS().UnBind2(theName);
2042    }
2043
2044    // Bind the circle to its name
2045    GetMapOfAIS().Bind(aCircle, theName);
2046
2047    // Display the circle
2048    TheAISContext()->Display (aCircle, Standard_True);
2049   
2050 }
2051
2052 static int VCircleBuilder(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2053 {
2054   // Verification of the arguments
2055   if (argc>6 || argc<2) 
2056   { 
2057     std::cout << "vcircle error: expect 4 arguments.\n"; 
2058     return 1; // TCL_ERROR 
2059   }
2060
2061   // There are all arguments
2062   if (argc == 6) 
2063   {
2064     // Get arguments
2065     TCollection_AsciiString aName(argv[1]);
2066     Standard_Boolean isFilled = Draw::Atoi(argv[5]) != 0;
2067
2068     Handle(AIS_InteractiveObject) theShapeA, theShapeB;
2069     GetMapOfAIS().Find2 (argv[2], theShapeA);
2070     GetMapOfAIS().Find2 (argv[3], theShapeB);
2071
2072     // Arguments: AIS_Point AIS_Point AIS_Point
2073     // ========================================
2074     if (!theShapeA.IsNull() && !theShapeB.IsNull() &&
2075       theShapeA->Type()==AIS_KOI_Datum && theShapeA->Signature()==1)
2076     {
2077       if (theShapeB->Type()!=AIS_KOI_Datum || theShapeB->Signature()!=1 ) 
2078       {
2079         std::cout << "vcircle error: 2d argument is unexpected to be a point.\n";
2080         return 1; // TCL_ERROR 
2081       }
2082       // The third object must be a point
2083       Handle(AIS_InteractiveObject) theShapeC;
2084       GetMapOfAIS().Find2 (argv[4], theShapeC);
2085       if (theShapeC.IsNull() ||
2086         theShapeC->Type()!=AIS_KOI_Datum || theShapeC->Signature()!=1 ) 
2087       {
2088         std::cout << "vcircle error: 3d argument is unexpected to be a point.\n";
2089         return 1; // TCL_ERROR 
2090       }
2091         // tag
2092         // Verify that the three points are different
2093         Handle(AIS_Point) theAISPointA = Handle(AIS_Point)::DownCast(theShapeA);
2094         Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB);
2095         Handle(AIS_Point) theAISPointC = Handle(AIS_Point)::DownCast(theShapeC);
2096         
2097         Handle(Geom_Point) myGeomPointA = theAISPointA->Component();
2098         Handle(Geom_CartesianPoint) myCartPointA = 
2099           Handle(Geom_CartesianPoint)::DownCast(myGeomPointA);
2100
2101         Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2102         Handle(Geom_CartesianPoint) myCartPointB =
2103           Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2104
2105         Handle(Geom_Point) myGeomPointC = theAISPointC->Component();
2106         Handle(Geom_CartesianPoint) myCartPointC =
2107           Handle(Geom_CartesianPoint)::DownCast(myGeomPointC);
2108
2109         // Test A=B
2110         if (Abs(myCartPointA->X()-myCartPointB->X()) <= Precision::Confusion() && 
2111             Abs(myCartPointA->Y()-myCartPointB->Y()) <= Precision::Confusion() && 
2112             Abs(myCartPointA->Z()-myCartPointB->Z()) <= Precision::Confusion() ) 
2113         {
2114           std::cout << "vcircle error: Same points.\n"; 
2115           return 1; // TCL_ERROR 
2116         }
2117         // Test A=C
2118         if (Abs(myCartPointA->X()-myCartPointC->X()) <= Precision::Confusion() &&
2119             Abs(myCartPointA->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2120             Abs(myCartPointA->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2121         {
2122           std::cout << "vcircle error: Same points.\n"; 
2123           return 1; // TCL_ERROR 
2124         }
2125         // Test B=C
2126         if (Abs(myCartPointB->X()-myCartPointC->X()) <= Precision::Confusion() && 
2127             Abs(myCartPointB->Y()-myCartPointC->Y()) <= Precision::Confusion() && 
2128             Abs(myCartPointB->Z()-myCartPointC->Z()) <= Precision::Confusion() ) 
2129         {
2130           std::cout << "vcircle error: Same points.\n"; 
2131           return 1;// TCL_ERROR 
2132         }
2133         // Construction of the circle
2134         GC_MakeCircle Cir = GC_MakeCircle (myCartPointA->Pnt(), 
2135           myCartPointB->Pnt(), myCartPointC->Pnt() );
2136         Handle (Geom_Circle) theGeomCircle;
2137         try 
2138         {
2139           theGeomCircle = Cir.Value();
2140         }
2141         catch (StdFail_NotDone const&)
2142         {
2143           std::cout << "vcircle error: can't create circle\n";
2144           return -1; // TCL_ERROR
2145         }
2146         
2147         DisplayCircle(theGeomCircle, aName, isFilled);
2148     }
2149
2150     // Arguments: AIS_Plane AIS_Point Real
2151     // ===================================
2152     else if (theShapeA->Type() == AIS_KOI_Datum && 
2153       theShapeA->Signature() == 7 ) 
2154     {
2155       if (theShapeB->Type() != AIS_KOI_Datum || 
2156         theShapeB->Signature() != 1 ) 
2157       {
2158         std::cout << "vcircle error: 2d element is a unexpected to be a point.\n"; 
2159         return 1; // TCL_ERROR 
2160       }
2161       // Check that the radius is >= 0
2162       if (Draw::Atof(argv[4]) <= 0 ) 
2163       {
2164         std::cout << "vcircle error: the radius must be >=0.\n"; 
2165         return 1; // TCL_ERROR 
2166       }
2167
2168       // Recover the normal to the plane
2169       Handle(AIS_Plane) theAISPlane = Handle(AIS_Plane)::DownCast(theShapeA);
2170       Handle(AIS_Point) theAISPointB = Handle(AIS_Point)::DownCast(theShapeB); 
2171
2172       Handle(Geom_Plane) myGeomPlane = theAISPlane->Component();
2173       Handle(Geom_Point) myGeomPointB = theAISPointB->Component();
2174       Handle(Geom_CartesianPoint) myCartPointB = 
2175         Handle(Geom_CartesianPoint)::DownCast(myGeomPointB);
2176
2177       gp_Pln mygpPlane = myGeomPlane->Pln();
2178       gp_Ax1 thegpAxe = mygpPlane.Axis();
2179       gp_Dir theDir = thegpAxe.Direction();
2180       gp_Pnt theCenter = myCartPointB->Pnt();
2181       Standard_Real TheR = Draw::Atof(argv[4]);
2182       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,TheR);
2183       Handle (Geom_Circle) theGeomCircle;
2184       try 
2185       {
2186         theGeomCircle = Cir.Value();
2187       }
2188       catch (StdFail_NotDone const&)
2189       {
2190         std::cout << "vcircle error: can't create circle\n";
2191         return -1; // TCL_ERROR
2192       }
2193
2194       DisplayCircle(theGeomCircle, aName, isFilled);
2195
2196     }
2197
2198     // Error
2199     else
2200     {
2201       std::cout << "vcircle error: 1st argument is a unexpected type.\n"; 
2202       return 1; // TCL_ERROR 
2203     }
2204
2205   }
2206   // No arguments: selection in the viewer
2207   // =========================================
2208   else 
2209   {
2210     // Get the name of the circle 
2211     TCollection_AsciiString aName(argv[1]);
2212
2213     TopTools_ListOfShape aShapes;
2214     ViewerTest::GetSelectedShapes (aShapes);
2215     if (aShapes.Extent() != 3 && aShapes.Extent() != 2)
2216     {
2217       std::cerr << "Error: Wrong number of selected shapes.\n";
2218       return 1;
2219     }
2220
2221     const TopoDS_Shape& aShapeA = aShapes.First();
2222     if (aShapeA.ShapeType() == TopAbs_VERTEX ) 
2223     {
2224       if (aShapes.Extent() != 3)
2225       {
2226         std::cerr << "Error: wrong number of selected shapes.\n";
2227         return 1;
2228       }
2229
2230       TopTools_ListOfShape::Iterator anIter (aShapes);
2231
2232       anIter.Next();
2233       const TopoDS_Shape& aShapeB = anIter.Value();
2234
2235       anIter.Next();
2236       const TopoDS_Shape& aShapeC = anIter.Value();
2237       
2238       // Get isFilled
2239       Standard_Boolean isFilled;
2240       std::cout << "Enter filled status (0 or 1)\n";
2241       cin >> isFilled;
2242
2243       // Construction of the circle
2244       gp_Pnt A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
2245       gp_Pnt B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
2246       gp_Pnt C = BRep_Tool::Pnt (TopoDS::Vertex (aShapeC));
2247
2248       GC_MakeCircle Cir = GC_MakeCircle (A, B, C);
2249       Handle (Geom_Circle) theGeomCircle;
2250       try 
2251       {
2252         theGeomCircle = Cir.Value();
2253       }
2254       catch (StdFail_NotDone const&)
2255       {
2256         std::cout << "vcircle error: can't create circle\n";
2257         return -1; // TCL_ERROR
2258       }
2259
2260       DisplayCircle(theGeomCircle, aName, isFilled);
2261
2262     }
2263     else if (aShapeA.ShapeType() == TopAbs_FACE)
2264     {
2265       const TopoDS_Shape& aShapeB = aShapes.Last();
2266
2267       // Recover the radius 
2268       Standard_Real theRad;
2269       do 
2270       {
2271         std::cout << " Enter the value of the radius:\n";
2272         cin >> theRad;
2273       } while (theRad <= 0);
2274       
2275       // Get filled status
2276       Standard_Boolean isFilled;
2277       std::cout << "Enter filled status (0 or 1)\n";
2278       cin >> isFilled;
2279
2280       // Recover the normal to the plane. tag
2281       TopoDS_Face myFace = TopoDS::Face(aShapeA);
2282       BRepAdaptor_Surface mySurface (myFace, Standard_False);
2283       gp_Pln myPlane = mySurface.Plane();
2284       Handle(Geom_Plane) theGeomPlane = new Geom_Plane (myPlane);
2285       gp_Pln mygpPlane = theGeomPlane->Pln();
2286       gp_Ax1 thegpAxe = mygpPlane.Axis();
2287       gp_Dir theDir = thegpAxe.Direction();
2288
2289       // Recover the center
2290       gp_Pnt theCenter = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
2291
2292       // Construct the circle
2293       GC_MakeCircle Cir = GC_MakeCircle (theCenter, theDir ,theRad);
2294       Handle (Geom_Circle) theGeomCircle;
2295       try 
2296       {
2297         theGeomCircle = Cir.Value();
2298       }
2299       catch (StdFail_NotDone const&)
2300       {
2301         std::cout << "vcircle error: can't create circle\n";
2302         return -1; // TCL_ERROR
2303       }
2304
2305       DisplayCircle(theGeomCircle, aName, isFilled);
2306     }
2307     else
2308     {
2309       std::cerr << "Error: You should select face and vertex or three vertices.\n";
2310       return 1;
2311     }
2312   }
2313
2314   return 0;
2315 }
2316
2317 //=======================================================================
2318 //function : VDrawText
2319 //purpose  :
2320 //=======================================================================
2321 static int VDrawText (Draw_Interpretor& theDI,
2322                       Standard_Integer  theArgsNb,
2323                       const char**      theArgVec)
2324 {
2325   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
2326   if (theArgsNb < 3)
2327   {
2328     std::cout << "Error: wrong number of arguments! See usage:\n";
2329     theDI.PrintHelp (theArgVec[0]);
2330     return 1;
2331   }
2332   else if (aContext.IsNull())
2333   {
2334     std::cout << "Error: no active view!\n";
2335     return 1;
2336   }
2337
2338   Standard_Integer           anArgIt = 1;
2339   TCollection_ExtendedString aName (theArgVec[anArgIt++], Standard_True);
2340   TCollection_ExtendedString aText (theArgVec[anArgIt++], Standard_True);
2341   Handle(AIS_TextLabel)      aTextPrs;
2342   ViewerTest_AutoUpdater     anAutoUpdater (aContext, ViewerTest::CurrentView());
2343
2344   Standard_Boolean isNewPrs = Standard_False;
2345   if (GetMapOfAIS().IsBound2 (aName))
2346   {
2347     aTextPrs = Handle(AIS_TextLabel)::DownCast (GetMapOfAIS().Find2 (aName));
2348   }
2349
2350   if (aTextPrs.IsNull())
2351   {
2352     isNewPrs = Standard_True;
2353     aTextPrs = new AIS_TextLabel();
2354     aTextPrs->SetFont ("Courier");
2355   }
2356
2357   aTextPrs->SetText (aText);
2358
2359   Handle(Graphic3d_TransformPers) aTrsfPers;
2360   Aspect_TypeOfDisplayText aDisplayType = Aspect_TODT_NORMAL;
2361
2362   Standard_Boolean aHasPlane = Standard_False;
2363   gp_Dir           aNormal;
2364   gp_Dir           aDirection;
2365   gp_Pnt           aPos;
2366
2367   for (; anArgIt < theArgsNb; ++anArgIt)
2368   {
2369     TCollection_AsciiString aParam (theArgVec[anArgIt]);
2370     aParam.LowerCase();
2371
2372     if (anAutoUpdater.parseRedrawMode (aParam))
2373     {
2374       continue;
2375     }
2376     else if (aParam == "-pos"
2377           || aParam == "-position")
2378     {
2379       if (anArgIt + 3 >= theArgsNb)
2380       {
2381         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2382         return 1;
2383       }
2384
2385       aPos.SetX (Draw::Atof (theArgVec[++anArgIt]));
2386       aPos.SetY (Draw::Atof (theArgVec[++anArgIt]));
2387       aPos.SetZ (Draw::Atof (theArgVec[++anArgIt]));
2388       aTextPrs->SetPosition (aPos);
2389     }
2390     else if (aParam == "-color")
2391     {
2392       if (anArgIt + 1 >= theArgsNb)
2393       {
2394         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2395         return 1;
2396       }
2397
2398       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2399       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2400       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2401       {
2402         anArgIt += 1;
2403         aTextPrs->SetColor (aNameOfColor);
2404         continue;
2405       }
2406       else if (anArgIt + 3 >= theArgsNb)
2407       {
2408         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2409         return 1;
2410       }
2411
2412       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2413       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2414       if (!aColor.IsRealValue()
2415        || !aGreen.IsRealValue()
2416        || !aBlue.IsRealValue())
2417       {
2418         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2419         return 1;
2420       }
2421
2422       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2423                                    aGreen.RealValue(),
2424                                    aBlue.RealValue());
2425
2426       aTextPrs->SetColor (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2427       anArgIt += 3;
2428     }
2429     else if (aParam == "-halign")
2430     {
2431       if (++anArgIt >= theArgsNb)
2432       {
2433         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2434         return 1;
2435       }
2436
2437       TCollection_AsciiString aType (theArgVec[anArgIt]);
2438       aType.LowerCase();
2439       if (aType == "left")
2440       {
2441         aTextPrs->SetHJustification (Graphic3d_HTA_LEFT);
2442       }
2443       else if (aType == "center")
2444       {
2445         aTextPrs->SetHJustification (Graphic3d_HTA_CENTER);
2446       }
2447       else if (aType == "right")
2448       {
2449         aTextPrs->SetHJustification (Graphic3d_HTA_RIGHT);
2450       }
2451       else
2452       {
2453         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2454         return 1;
2455       }
2456     }
2457     else if (aParam == "-valign")
2458     {
2459       if (++anArgIt >= theArgsNb)
2460       {
2461         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2462         return 1;
2463       }
2464
2465       TCollection_AsciiString aType (theArgVec[anArgIt]);
2466       aType.LowerCase();
2467       if (aType == "top")
2468       {
2469         aTextPrs->SetVJustification (Graphic3d_VTA_TOP);
2470       }
2471       else if (aType == "center")
2472       {
2473         aTextPrs->SetVJustification (Graphic3d_VTA_CENTER);
2474       }
2475       else if (aType == "bottom")
2476       {
2477         aTextPrs->SetVJustification (Graphic3d_VTA_BOTTOM);
2478       }
2479       else if (aType == "topfirstline")
2480       {
2481         aTextPrs->SetVJustification (Graphic3d_VTA_TOPFIRSTLINE);
2482       }
2483       else
2484       {
2485         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2486         return 1;
2487       }
2488     }
2489     else if (aParam == "-angle")
2490     {
2491       if (++anArgIt >= theArgsNb)
2492       {
2493         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2494         return 1;
2495       }
2496
2497       aTextPrs->SetAngle (Draw::Atof (theArgVec[anArgIt]) * (M_PI / 180.0));
2498     }
2499     else if (aParam == "-zoom")
2500     {
2501       if (++anArgIt >= theArgsNb)
2502       {
2503         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2504         return 1;
2505       }
2506
2507       aTextPrs->SetZoomable (Draw::Atoi (theArgVec[anArgIt]) == 1);
2508     }
2509     else if (aParam == "-height")
2510     {
2511       if (++anArgIt >= theArgsNb)
2512       {
2513         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2514         return 1;
2515       }
2516
2517       aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
2518     }
2519     else if (aParam == "-aspect")
2520     {
2521       if (++anArgIt >= theArgsNb)
2522       {
2523         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2524         return 1;
2525       }
2526
2527       TCollection_AsciiString anOption (theArgVec[anArgIt]);
2528       anOption.LowerCase();
2529       Font_FontAspect aFontAspect = Font_FA_Undefined;
2530       if (!parseFontStyle (anOption, aFontAspect))
2531       {
2532         std::cout << "Error: unknown font aspect '" << anOption << "'.\n";
2533         return 1;
2534       }
2535       aTextPrs->SetFontAspect (aFontAspect);
2536     }
2537     else if (aParam == "-font")
2538     {
2539       if (++anArgIt >= theArgsNb)
2540       {
2541         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2542         return 1;
2543       }
2544
2545       aTextPrs->SetFont (theArgVec[anArgIt]);
2546     }
2547     else if (aParam == "-plane")
2548     {
2549       if (anArgIt + 6 >= theArgsNb)
2550       {
2551         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2552         return 1;
2553       }
2554
2555       Standard_Real aX = Draw::Atof (theArgVec[++anArgIt]);
2556       Standard_Real aY = Draw::Atof (theArgVec[++anArgIt]);
2557       Standard_Real aZ = Draw::Atof (theArgVec[++anArgIt]);
2558       aNormal.SetCoord (aX, aY, aZ);
2559
2560       aX = Draw::Atof (theArgVec[++anArgIt]);
2561       aY = Draw::Atof (theArgVec[++anArgIt]);
2562       aZ = Draw::Atof (theArgVec[++anArgIt]);
2563       aDirection.SetCoord (aX, aY, aZ);
2564
2565       aHasPlane = Standard_True;
2566     }
2567     else if (aParam == "-flipping")
2568     {
2569       aTextPrs->SetFlipping (Standard_True);
2570     }
2571     else if (aParam == "-disptype"
2572           || aParam == "-displaytype")
2573     {
2574       if (++anArgIt >= theArgsNb)
2575       {
2576         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2577         return 1;
2578       }
2579       TCollection_AsciiString aType (theArgVec[anArgIt]);
2580       aType.LowerCase();
2581       if (aType == "subtitle")
2582         aDisplayType = Aspect_TODT_SUBTITLE;
2583       else if (aType == "decal")
2584         aDisplayType = Aspect_TODT_DEKALE;
2585       else if (aType == "blend")
2586         aDisplayType = Aspect_TODT_BLEND;
2587       else if (aType == "dimension")
2588         aDisplayType = Aspect_TODT_DIMENSION;
2589       else if (aType == "normal")
2590         aDisplayType = Aspect_TODT_NORMAL;
2591       else if (aType == "shadow")
2592         aDisplayType = Aspect_TODT_SHADOW;
2593       else
2594       {
2595         std::cout << "Error: wrong display type '" << aType << "'.\n";
2596         return 1;
2597       }
2598     }
2599     else if (aParam == "-subcolor"
2600           || aParam == "-subtitlecolor")
2601     {
2602       if (anArgIt + 1 >= theArgsNb)
2603       {
2604         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2605         return 1;
2606       }
2607
2608       TCollection_AsciiString aColor (theArgVec[anArgIt + 1]);
2609       Quantity_NameOfColor aNameOfColor = Quantity_NOC_BLACK;
2610       if (Quantity_Color::ColorFromName (aColor.ToCString(), aNameOfColor))
2611       {
2612         anArgIt += 1;
2613         aTextPrs->SetColorSubTitle (aNameOfColor);
2614         continue;
2615       }
2616       else if (anArgIt + 3 >= theArgsNb)
2617       {
2618         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2619         return 1;
2620       }
2621
2622       TCollection_AsciiString aGreen (theArgVec[anArgIt + 2]);
2623       TCollection_AsciiString aBlue  (theArgVec[anArgIt + 3]);
2624       if (!aColor.IsRealValue()
2625        || !aGreen.IsRealValue()
2626        || !aBlue.IsRealValue())
2627       {
2628         std::cout << "Error: wrong syntax at '" << aParam.ToCString() << "'.\n";
2629         return 1;
2630       }
2631
2632       const Graphic3d_Vec3d anRGB (aColor.RealValue(),
2633                                    aGreen.RealValue(),
2634                                    aBlue.RealValue());
2635
2636       aTextPrs->SetColorSubTitle (Quantity_Color (anRGB.r(), anRGB.g(), anRGB.b(), Quantity_TOC_RGB));
2637       anArgIt += 3;
2638     }
2639     else if (aParam == "-2d")
2640     {
2641       aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_2d);
2642     }
2643     else if (aParam == "-trsfperspos"
2644           || aParam == "-perspos")
2645     {
2646       if (anArgIt + 2 >= theArgsNb)
2647       {
2648         std::cerr << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
2649         return 1;
2650       }
2651
2652       TCollection_AsciiString aX (theArgVec[++anArgIt]);
2653       TCollection_AsciiString aY (theArgVec[++anArgIt]);
2654       TCollection_AsciiString aZ = "0";
2655       if (!aX.IsIntegerValue()
2656        || !aY.IsIntegerValue())
2657       {
2658         std::cerr << "Error: wrong syntax at '" << aParam << "'.\n";
2659         return 1;
2660       }
2661       if (anArgIt + 1 < theArgsNb)
2662       {
2663         TCollection_AsciiString aTemp = theArgVec[anArgIt + 1];
2664         if (aTemp.IsIntegerValue())
2665         {
2666           aZ = aTemp;
2667           ++anArgIt;
2668         }
2669       }
2670
2671       aTrsfPers = Graphic3d_TransformPers::FromDeprecatedParams (Graphic3d_TMF_2d, gp_Pnt (aX.IntegerValue(), aY.IntegerValue(), aZ.IntegerValue()));
2672     }
2673     else
2674     {
2675       std::cout << "Error: unknown argument '" << aParam << "'\n";
2676       return 1;
2677     }
2678   }
2679
2680   if (aHasPlane)
2681   {
2682     aTextPrs->SetOrientation3D (gp_Ax2 (aPos, aNormal, aDirection));
2683   }
2684
2685   aTextPrs->SetDisplayType (aDisplayType);
2686
2687   if (!aTrsfPers.IsNull())
2688   {
2689     aContext->SetTransformPersistence (aTextPrs, aTrsfPers);
2690     aTextPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
2691     if (aTextPrs->Position().Z() != 0)
2692     {
2693       aTextPrs->SetPosition (gp_Pnt(aTextPrs->Position().X(), aTextPrs->Position().Y(), 0));
2694     }
2695   }
2696   else if (!aTextPrs->TransformPersistence().IsNull())
2697   {
2698     aContext->SetTransformPersistence (aTextPrs, Handle(Graphic3d_TransformPers)());
2699   }
2700
2701   if (isNewPrs)
2702   {
2703     ViewerTest::Display (aName, aTextPrs, Standard_False);
2704   }
2705   else
2706   {
2707     aContext->Redisplay (aTextPrs, Standard_False, Standard_True);
2708   }
2709   return 0;
2710 }
2711
2712 #include <math.h>
2713 #include <gp_Pnt.hxx>
2714 #include <Graphic3d_ArrayOfPoints.hxx>
2715 #include <Graphic3d_ArrayOfPrimitives.hxx>
2716 #include <Graphic3d_ArrayOfTriangles.hxx>
2717 #include <Poly_Array1OfTriangle.hxx>
2718 #include <Poly_Triangle.hxx>
2719 #include <Poly_Triangulation.hxx>
2720 #include <TColgp_Array1OfPnt.hxx>
2721 #include <TShort_Array1OfShortReal.hxx>
2722 #include <TShort_HArray1OfShortReal.hxx>
2723
2724 #include <AIS_Triangulation.hxx>
2725 #include <StdPrs_ToolTriangulatedShape.hxx>
2726 #include <Poly_Connect.hxx>
2727 #include <TColgp_Array1OfDir.hxx>
2728 #include <Graphic3d_GraphicDriver.hxx>
2729
2730 #include <TColStd_Array1OfInteger.hxx>
2731 #include <TColStd_HArray1OfInteger.hxx>
2732 #include <Prs3d_ShadingAspect.hxx>
2733 #include <Graphic3d_MaterialAspect.hxx>
2734 #include <Graphic3d_AspectFillArea3d.hxx>
2735
2736 #include <BRepPrimAPI_MakeCylinder.hxx>
2737 #include <TopoDS_Shape.hxx>
2738 #include <TopExp_Explorer.hxx>
2739 #include <TopAbs.hxx>
2740 #include <StdSelect_ShapeTypeFilter.hxx>
2741 #include <AIS_InteractiveObject.hxx>
2742
2743
2744 //===============================================================================================
2745 //function : CalculationOfSphere
2746 //author   : psn
2747 //purpose  : Create a Sphere
2748 //===============================================================================================
2749
2750 Handle( Poly_Triangulation ) CalculationOfSphere( double X , double Y , double Z ,
2751                                                   int res ,
2752                                                   double Radius ){
2753   double mRadius = Radius;
2754   double mCenter[3] = {X,Y,Z};
2755   int mThetaResolution;
2756   int mPhiResolution;
2757   double mStartTheta = 0;//StartTheta;
2758   double mEndTheta = 360;//EndTheta;
2759   double mStartPhi = 0;//StartPhi;
2760   double mEndPhi = 180;//EndPhi;
2761   res = res < 4 ? 4 : res;
2762
2763   mThetaResolution = res;
2764   mPhiResolution = res;
2765
2766   int i, j;
2767   int jStart, jEnd, numOffset;
2768   double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
2769   double startTheta, endTheta, startPhi, endPhi;
2770   int base, numPoles=0, thetaResolution, phiResolution;
2771
2772   int pts[3];
2773   int piece = -1;
2774   int numPieces = 1;
2775   if ( numPieces > mThetaResolution ) {
2776     numPieces = mThetaResolution;
2777   }
2778
2779   int localThetaResolution =  mThetaResolution;
2780   double localStartTheta =  mStartTheta;
2781   double localEndTheta =  mEndTheta;
2782
2783   while ( localEndTheta < localStartTheta ) {
2784     localEndTheta += 360.0;
2785   }
2786
2787   deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
2788
2789   // Change the ivars based on pieces.
2790   int start, end;
2791   start = piece * localThetaResolution / numPieces;
2792   end = (piece+1) * localThetaResolution / numPieces;
2793   localEndTheta = localStartTheta + (double)(end) * deltaTheta;
2794   localStartTheta = localStartTheta + (double)(start) * deltaTheta;
2795   localThetaResolution = end - start;
2796
2797   // Create north pole if needed
2798   int number_point = 0;
2799   int number_pointArray = 0;
2800
2801   if ( mStartPhi <= 0.0 ) {
2802     number_pointArray++;
2803     numPoles++;
2804   }
2805   if ( mEndPhi >= 180.0 ) {
2806     number_pointArray++;
2807     numPoles++;
2808   }
2809
2810   // Check data, determine increments, and convert to radians
2811   startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
2812   startTheta *= M_PI  / 180.0;
2813   endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
2814   endTheta *= M_PI  / 180.0;
2815
2816
2817   startPhi = ( mStartPhi <  mEndPhi ?  mStartPhi :  mEndPhi);
2818   startPhi *= M_PI  / 180.0;
2819   endPhi = ( mEndPhi >  mStartPhi ?  mEndPhi :  mStartPhi);
2820   endPhi *= M_PI  / 180.0;
2821
2822   phiResolution =  mPhiResolution - numPoles;
2823   deltaPhi = (endPhi - startPhi) / ( mPhiResolution - 1);
2824   thetaResolution = localThetaResolution;
2825   if ( fabs(localStartTheta - localEndTheta) < 360.0 ) {
2826     ++localThetaResolution;
2827   }
2828   deltaTheta = (endTheta - startTheta) / thetaResolution;
2829
2830   jStart = ( mStartPhi <= 0.0 ? 1 : 0);
2831   jEnd = ( mEndPhi >= 180.0 ?  mPhiResolution - 1 :  mPhiResolution);
2832
2833   // Create intermediate points
2834   for ( i = 0; i < localThetaResolution; i++ ) {
2835     for ( j = jStart; j < jEnd; j++ ) {
2836         number_pointArray++;
2837     }
2838   }
2839
2840   //Generate mesh connectivity
2841   base = phiResolution * localThetaResolution;
2842
2843   int number_triangle = 0 ;
2844   if ( mStartPhi <= 0.0 ) { // around north pole
2845     number_triangle += localThetaResolution;
2846   }
2847
2848   if ( mEndPhi >= 180.0 ) { // around south pole
2849     number_triangle += localThetaResolution;
2850   }
2851
2852   // bands in-between poles
2853   for ( i=0; i < localThetaResolution; i++){
2854     for ( j=0; j < (phiResolution-1); j++){
2855        number_triangle +=2;
2856     }
2857   }
2858
2859   Handle( Poly_Triangulation ) polyTriangulation = new Poly_Triangulation(number_pointArray, number_triangle, false);
2860   TColgp_Array1OfPnt& PointsOfArray = polyTriangulation->ChangeNodes();
2861   Poly_Array1OfTriangle& pArrayTriangle = polyTriangulation->ChangeTriangles();
2862
2863   if (  mStartPhi <= 0.0 ){
2864       x[0] =  mCenter[0];
2865       x[1] =  mCenter[1];
2866       x[2] =  mCenter[2] +  mRadius;
2867       PointsOfArray.SetValue(1,gp_Pnt(x[0],x[1],x[2]));
2868   }
2869
2870   // Create south pole if needed
2871   if (  mEndPhi >= 180.0 ){
2872       x[0] =  mCenter[0];
2873       x[1] =  mCenter[1];
2874       x[2] =  mCenter[2] -  mRadius;
2875       PointsOfArray.SetValue(2,gp_Pnt(x[0],x[1],x[2]));
2876   }
2877
2878   number_point = 3;
2879   for ( i=0; i < localThetaResolution; i++){
2880     theta = localStartTheta * M_PI / 180.0 + i*deltaTheta;
2881     for ( j = jStart; j < jEnd; j++){
2882         phi = startPhi + j*deltaPhi;
2883         radius =  mRadius * sin((double)phi);
2884         n[0] = radius * cos((double)theta);
2885         n[1] = radius * sin((double)theta);
2886         n[2] =  mRadius * cos((double)phi);
2887         x[0] = n[0] +  mCenter[0];
2888         x[1] = n[1] +  mCenter[1];
2889         x[2] = n[2] +  mCenter[2];
2890         PointsOfArray.SetValue(number_point,gp_Pnt(x[0],x[1],x[2]));
2891         number_point++;
2892       }
2893     }
2894
2895   numPoles = 3;
2896   number_triangle = 1;
2897   if ( mStartPhi <= 0.0 ){// around north pole
2898     for (i=0; i < localThetaResolution; i++){
2899         pts[0] = phiResolution*i + numPoles;
2900         pts[1] = (phiResolution*(i+1) % base) + numPoles;
2901         pts[2] = 1;
2902         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2903         number_triangle++;
2904       }
2905     }
2906
2907   if (  mEndPhi >= 180.0 ){ // around south pole
2908     numOffset = phiResolution - 1 + numPoles;
2909     for (i=0; i < localThetaResolution; i++){
2910         pts[0] = phiResolution*i + numOffset;
2911         pts[2] = ((phiResolution*(i+1)) % base) + numOffset;
2912         pts[1] = numPoles - 1;
2913         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2914         number_triangle++;
2915       }
2916     }
2917
2918   // bands in-between poles
2919
2920   for (i=0; i < localThetaResolution; i++){
2921     for (j=0; j < (phiResolution-1); j++){
2922         pts[0] = phiResolution*i + j + numPoles;
2923         pts[1] = pts[0] + 1;
2924         pts[2] = ((phiResolution*(i+1)+j) % base) + numPoles + 1;
2925         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2926         number_triangle++;
2927         pts[1] = pts[2];
2928         pts[2] = pts[1] - 1;
2929         pArrayTriangle.SetValue(number_triangle,Poly_Triangle(pts[0],pts[1],pts[2]));
2930         number_triangle++;
2931       }
2932     }
2933
2934   Poly_Connect* pc = new Poly_Connect(polyTriangulation);
2935
2936   Handle(TShort_HArray1OfShortReal) Normals = new TShort_HArray1OfShortReal(1, polyTriangulation->NbNodes() * 3);
2937
2938   Standard_Integer index[3];
2939   Standard_Real Tol = Precision::Confusion();
2940
2941   gp_Dir Nor;
2942   for (i = PointsOfArray.Lower(); i <= PointsOfArray.Upper(); i++) {
2943       gp_XYZ eqPlan(0, 0, 0);
2944       for ( pc->Initialize(i); pc->More(); pc->Next()) {
2945         pArrayTriangle(pc->Value()).Get(index[0], index[1], index[2]);
2946         gp_XYZ v1(PointsOfArray(index[1]).Coord()-PointsOfArray(index[0]).Coord());
2947         gp_XYZ v2(PointsOfArray(index[2]).Coord()-PointsOfArray(index[1]).Coord());
2948         gp_XYZ vv = v1^v2;
2949         Standard_Real mod = vv.Modulus();
2950         if(mod < Tol) continue;
2951         eqPlan += vv/mod;
2952       }
2953
2954       Standard_Real modmax = eqPlan.Modulus();
2955
2956       if(modmax > Tol)
2957         Nor = gp_Dir(eqPlan);
2958       else
2959         Nor = gp_Dir(0., 0., 1.);
2960       
2961       Standard_Integer k = (i - PointsOfArray.Lower()) * 3;
2962       Normals->SetValue(k + 1, (Standard_ShortReal)Nor.X());
2963       Normals->SetValue(k + 2, (Standard_ShortReal)Nor.Y());
2964       Normals->SetValue(k + 3, (Standard_ShortReal)Nor.Z());
2965   }
2966
2967   delete pc;
2968   polyTriangulation->SetNormals(Normals);
2969
2970   return polyTriangulation;
2971 }
2972
2973 //===============================================================================================
2974 //function : VDrawSphere
2975 //author   : psn
2976 //purpose  : Create an AIS shape.
2977 //===============================================================================================
2978 static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
2979 {
2980   // check for errors
2981   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
2982   if (aContextAIS.IsNull())
2983   {
2984     std::cout << "Call vinit before!\n";
2985     return 1;
2986   }
2987   else if (argc < 3)
2988   {
2989     std::cout << "Use: " << argv[0]
2990               << " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n";
2991     return 1;
2992   }
2993
2994   // read the arguments
2995   TCollection_AsciiString aShapeName (argv[1]);
2996   Standard_Integer aResolution = Draw::Atoi (argv[2]);
2997   Standard_Real aCenterX = (argc > 5) ? Draw::Atof (argv[3]) : 0.0;
2998   Standard_Real aCenterY = (argc > 5) ? Draw::Atof (argv[4]) : 0.0;
2999   Standard_Real aCenterZ = (argc > 5) ? Draw::Atof (argv[5]) : 0.0;
3000   Standard_Real aRadius =  (argc > 6) ? Draw::Atof (argv[6]) : 100.0;
3001   Standard_Boolean toShowEdges = (argc > 7) ? Draw::Atoi (argv[7]) == 1 : Standard_False;
3002   Standard_Boolean toPrintInfo = (argc > 8) ? Draw::Atoi (argv[8]) == 1 : Standard_True;
3003
3004   // remove AIS object with given name from map
3005   VDisplayAISObject (aShapeName, Handle(AIS_InteractiveObject)());
3006
3007   if (toPrintInfo)
3008     std::cout << "Compute Triangulation...\n";
3009   Handle(AIS_Triangulation) aShape
3010     = new AIS_Triangulation (CalculationOfSphere (aCenterX, aCenterY, aCenterZ,
3011                                                   aResolution,
3012                                                   aRadius));
3013   Standard_Integer aNumberPoints    = aShape->GetTriangulation()->Nodes().Length();
3014   Standard_Integer aNumberTriangles = aShape->GetTriangulation()->Triangles().Length();
3015
3016   // stupid initialization of Green color in RGBA space as integer
3017   // probably wrong for big-endian CPUs
3018   const Graphic3d_Vec4ub aColor (0, 255, 0, 0);
3019
3020   // setup colors array per vertex
3021   Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, aNumberPoints);
3022   for (Standard_Integer aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
3023   {
3024     aColorArray->SetValue (aNodeId, *reinterpret_cast<const Standard_Integer*> (aColor.GetData()));
3025   }
3026   aShape->SetColors (aColorArray);
3027
3028   // show statistics
3029   Standard_Integer aPointsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
3030   Standard_Integer aNormalsSize     = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat
3031   Standard_Integer aColorsSize      = aNumberPoints * 3 * sizeof(float);  // 3x GLfloat without alpha
3032   Standard_Integer aTrianglesSize   = aNumberTriangles * 3 * sizeof(int); // 3x GLint
3033   Standard_Integer aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
3034   Standard_Integer aTotalSize       = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
3035   aTotalSize >>= 20; //MB
3036   aNormalsSize >>= 20;
3037   aColorsSize >>= 20;
3038   aTrianglesSize >>= 20;
3039   aPolyConnectSize >>= 20;
3040   if (toPrintInfo)
3041   {
3042     std::cout << "NumberOfPoints:    " << aNumberPoints << "\n"
3043       << "NumberOfTriangles: " << aNumberTriangles << "\n"
3044       << "Amount of memory required for PolyTriangulation without Normals: " << (aTotalSize - aNormalsSize) << " Mb\n"
3045       << "Amount of memory for colors: " << aColorsSize << " Mb\n"
3046       << "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
3047       << "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
3048   }
3049
3050   // Setting material properties, very important for desirable visual result!
3051   Graphic3d_MaterialAspect aMat (Graphic3d_NOM_PLASTIC);
3052   aMat.SetAmbient  (0.2f);
3053   aMat.SetSpecular (0.5f);
3054   Handle(Graphic3d_AspectFillArea3d) anAspect
3055     = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID,
3056                                       Quantity_NOC_RED,
3057                                       Quantity_NOC_YELLOW,
3058                                       Aspect_TOL_SOLID,
3059                                       1.0,
3060                                       aMat,
3061                                       aMat);
3062   Handle(Prs3d_ShadingAspect) aShAsp = new Prs3d_ShadingAspect();
3063   anAspect->SetDrawEdges (toShowEdges);
3064   aShAsp->SetAspect (anAspect);
3065   aShape->Attributes()->SetShadingAspect (aShAsp);
3066
3067   VDisplayAISObject (aShapeName, aShape);
3068   return 0;
3069 }
3070
3071 //=============================================================================
3072 //function : VComputeHLR
3073 //purpose  :
3074 //=============================================================================
3075
3076 static int VComputeHLR (Draw_Interpretor& ,
3077                         Standard_Integer theArgNb,
3078                         const char** theArgVec)
3079 {
3080   TCollection_AsciiString aShapeName, aHlrName;
3081   TopoDS_Shape aSh;
3082   gp_Pnt anEye;
3083   gp_Dir aDir;
3084   gp_Ax2 aProjAx;
3085   bool hasViewDirArg = false;
3086   Prs3d_TypeOfHLR anAlgoType = Prs3d_TOH_PolyAlgo;
3087   bool toShowTangentEdges = false, toShowHiddenEdges = false;
3088   int aNbIsolines = 0;
3089   if (Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext())
3090   {
3091     gp_Dir aRight;
3092     Handle(V3d_View) aView = ViewerTest::CurrentView();
3093     Standard_Integer aWidth, aHeight;
3094     Standard_Real aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
3095     Standard_Real aRightX, aRightY, aRightZ;
3096     aView->Window()->Size (aWidth, aHeight);
3097
3098     aView->ConvertWithProj (aWidth, aHeight/2, 
3099                             aRightX, aRightY, aRightZ,
3100                             aDirX, aDirY, aDirZ);
3101     aView->ConvertWithProj (aWidth/2, aHeight/2, 
3102                             aCentX, aCentY, aCentZ,
3103                             aDirX, aDirY, aDirZ);
3104
3105     anEye.SetCoord (-aCentX, -aCentY, -aCentZ);
3106     aDir.SetCoord (-aDirX, -aDirY, -aDirZ);
3107     aRight.SetCoord (aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
3108     aProjAx.SetLocation (anEye);
3109     aProjAx.SetDirection (aDir);
3110     aProjAx.SetXDirection (aRight);
3111   }
3112   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3113   {
3114     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
3115     anArgCase.LowerCase();
3116     if (anArgIter + 1 < theArgNb
3117      && (anArgCase == "-algotype"
3118       || anArgCase == "-algo"
3119       || anArgCase == "-type"))
3120     {
3121       TCollection_AsciiString anArgNext (theArgVec[++anArgIter]);
3122       anArgNext.LowerCase();
3123       if (anArgNext == "polyalgo")
3124       {
3125         anAlgoType = Prs3d_TOH_PolyAlgo;
3126       }
3127       else if (anArgNext == "algo")
3128       {
3129         anAlgoType = Prs3d_TOH_Algo;
3130       }
3131       else
3132       {
3133         std::cout << "Syntax error: unknown algo type '" << anArgNext << "'\n";
3134         return 1;
3135       }
3136     }
3137     else if (anArgCase == "-showhiddenedges"
3138           || anArgCase == "-hiddenedges"
3139           || anArgCase == "-hidden")
3140     {
3141       toShowHiddenEdges = true;
3142       if (anArgIter + 1 < theArgNb
3143        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toShowHiddenEdges))
3144       {
3145         ++anArgIter;
3146       }
3147     }
3148     else if (anArgCase == "-showtangentedges"
3149           || anArgCase == "-tangentedges"
3150           || anArgCase == "-tangent")
3151     {
3152       toShowTangentEdges = true;
3153       if (anArgIter + 1 < theArgNb
3154        && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toShowTangentEdges))
3155       {
3156         ++anArgIter;
3157       }
3158     }
3159     else if (anArgIter + 1 < theArgNb
3160           && (anArgCase == "-nbiso"
3161            || anArgCase == "-nbisolines"))
3162     {
3163       aNbIsolines = Draw::Atoi (theArgVec[++anArgIter]);
3164     }
3165     else if (aSh.IsNull())
3166     {
3167       aSh = DBRep::Get (theArgVec[anArgIter]);
3168       aShapeName = theArgVec[anArgIter];
3169       if (aSh.IsNull())
3170       {
3171         BRep_Builder aBrepBuilder;
3172         BRepTools::Read (aSh, theArgVec[anArgIter], aBrepBuilder);
3173         if (aSh.IsNull())
3174         {
3175           std::cout << "Syntax error: no shape with name " << theArgVec[anArgIter] << " found\n";
3176           return 1;
3177         }
3178       }
3179     }
3180     else if (aHlrName.IsEmpty())
3181     {
3182       aHlrName = theArgVec[anArgIter];
3183     }
3184     else if (!hasViewDirArg
3185           && anArgIter + 8 < theArgNb)
3186     {
3187       hasViewDirArg = true;
3188       gp_Dir anUp;
3189       anEye.SetCoord (Draw::Atof (theArgVec[anArgIter + 0]), Draw::Atof (theArgVec[anArgIter + 1]), Draw::Atof (theArgVec[anArgIter + 2]));
3190       aDir .SetCoord (Draw::Atof (theArgVec[anArgIter + 3]), Draw::Atof (theArgVec[anArgIter + 4]), Draw::Atof (theArgVec[anArgIter + 5]));
3191       anUp .SetCoord (Draw::Atof (theArgVec[anArgIter + 6]), Draw::Atof (theArgVec[anArgIter + 7]), Draw::Atof (theArgVec[anArgIter + 8]));
3192       aProjAx.SetLocation (anEye);
3193       aProjAx.SetDirection (aDir);
3194       aProjAx.SetYDirection (anUp);
3195       anArgIter += 8;
3196     }
3197     else
3198     {
3199       std::cout << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'\n";
3200       return 1;
3201     }
3202   }
3203
3204   if (aHlrName.IsEmpty() || aSh.IsNull()
3205    || (ViewerTest::GetAISContext().IsNull() && hasViewDirArg))
3206   {
3207     std::cout << "Syntax error: wrong number of arguments\n";
3208     return 1;
3209   }
3210
3211   HLRAlgo_Projector aProjector (aProjAx);
3212   TopoDS_Shape aVisible[6];
3213   TopoDS_Shape aHidden[6];
3214   if (anAlgoType == Prs3d_TOH_PolyAlgo)
3215   {
3216     Handle(HLRBRep_PolyAlgo) aPolyAlgo = new HLRBRep_PolyAlgo();
3217     aPolyAlgo->Projector (aProjector);
3218     aPolyAlgo->Load (aSh);
3219     aPolyAlgo->Update();
3220
3221     HLRBRep_PolyHLRToShape aHLRToShape;
3222     aHLRToShape.Update (aPolyAlgo);
3223
3224     aVisible[HLRBRep_Sharp]   = aHLRToShape.VCompound();
3225     aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound(); // extract visible outlines
3226     aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
3227     if (toShowTangentEdges)
3228     {
3229       aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
3230     }
3231     if (toShowHiddenEdges)
3232     {
3233       aHidden[HLRBRep_Sharp]   = aHLRToShape.HCompound();
3234       aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
3235       aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
3236       if (toShowTangentEdges)
3237       {
3238         aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
3239       }
3240     }
3241   }
3242   else
3243   {
3244     Handle(HLRBRep_Algo) aHlrAlgo = new HLRBRep_Algo();
3245     aHlrAlgo->Add (aSh, aNbIsolines);
3246     aHlrAlgo->Projector (aProjector);
3247     aHlrAlgo->Update();
3248     aHlrAlgo->Hide();
3249
3250     HLRBRep_HLRToShape aHLRToShape (aHlrAlgo);
3251     aVisible[HLRBRep_Sharp]   = aHLRToShape.VCompound();
3252     aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound();
3253     aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
3254     if (toShowTangentEdges)
3255     {
3256       aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
3257     }
3258     aVisible[HLRBRep_IsoLine] = aHLRToShape.IsoLineVCompound();
3259
3260     if (toShowHiddenEdges)
3261     {
3262       aHidden[HLRBRep_Sharp]   = aHLRToShape.HCompound();
3263       aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
3264       aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
3265       if (toShowTangentEdges)
3266       {
3267         aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
3268       }
3269       aHidden[HLRBRep_IsoLine] = aHLRToShape.IsoLineHCompound();
3270     }
3271     // extract 3d
3272     //aVisible[HLRBRep_Sharp]   = aHLRToShape.CompoundOfEdges (HLRBRep_Sharp, Standard_True, Standard_True);
3273     //aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound3d();
3274   }
3275
3276   TopoDS_Compound aCompRes, aCompVis, aCompHid;
3277   BRep_Builder aBuilder;
3278   aBuilder.MakeCompound (aCompVis);
3279   aBuilder.MakeCompound (aCompHid);
3280   aBuilder.MakeCompound (aCompRes);
3281   for (int aTypeIter = 0; aTypeIter < 6; ++aTypeIter)
3282   {
3283     if (!aVisible[aTypeIter].IsNull())
3284     {
3285       aBuilder.Add (aCompVis, aVisible[aTypeIter]);
3286     }
3287     if (!aHidden[aTypeIter].IsNull())
3288     {
3289       aBuilder.Add (aCompHid, aHidden[aTypeIter]);
3290     }
3291   }
3292   aBuilder.Add (aCompRes, aCompVis);
3293   aBuilder.Add (aCompRes, aCompHid);
3294
3295   // create an AIS shape and display it
3296   if (!ViewerTest::GetAISContext().IsNull())
3297   {
3298     Handle(AIS_ColoredShape) anObject = new AIS_ColoredShape (aCompRes);
3299     if (toShowHiddenEdges)
3300     {
3301       Handle(Prs3d_LineAspect) aLineAspect = new Prs3d_LineAspect (Quantity_Color (Quantity_NOC_RED), Aspect_TOL_DASH, 1.0f);
3302       for (int aTypeIter = 0; aTypeIter < 6; ++aTypeIter)
3303       {
3304         if (!aHidden[aTypeIter].IsNull())
3305         {
3306           Handle(AIS_ColoredDrawer) aDrawer = anObject->CustomAspects (aHidden[aTypeIter]);
3307           aDrawer->SetLineAspect (aLineAspect);
3308           aDrawer->SetWireAspect (aLineAspect);
3309           aDrawer->SetFreeBoundaryAspect (aLineAspect);
3310           aDrawer->SetUnFreeBoundaryAspect (aLineAspect);
3311         }
3312       }
3313     }
3314     ViewerTest::Display (aHlrName, anObject, true);
3315   }
3316
3317   DBRep::Set (aHlrName.ToCString(), aCompRes);
3318   return 0;
3319 }
3320
3321 // This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
3322 // manipulating and displaying such an array with AIS context
3323
3324 class MyPArrayObject : public AIS_InteractiveObject
3325 {
3326
3327 public:
3328
3329   MyPArrayObject (const Handle(Graphic3d_ArrayOfPrimitives)& thePArray) : myPArray (thePArray) {}
3330
3331   MyPArrayObject (Graphic3d_TypeOfPrimitiveArray thePrimType,
3332                   const Handle(TColStd_HArray1OfAsciiString)& theDesc,
3333                   const Handle(Graphic3d_AspectMarker3d)& theMarkerAspect)
3334   {
3335     Init (thePrimType, theDesc, theMarkerAspect, Standard_False);
3336   }
3337
3338   //! Initialize the array from specified description.
3339   Standard_Boolean Init (Graphic3d_TypeOfPrimitiveArray thePrimType,
3340                          const Handle(TColStd_HArray1OfAsciiString)& theDesc,
3341                          const Handle(Graphic3d_AspectMarker3d)& theMarkerAspect,
3342                          Standard_Boolean theToPatch);
3343
3344   DEFINE_STANDARD_RTTI_INLINE(MyPArrayObject,AIS_InteractiveObject);
3345
3346   virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
3347
3348 private:
3349
3350   void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3351                 const Handle(Prs3d_Presentation)& aPresentation,
3352                 const Standard_Integer aMode) Standard_OVERRIDE;
3353
3354   void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3355                          const Standard_Integer /*theMode*/) Standard_OVERRIDE;
3356
3357   bool CheckInputCommand (const TCollection_AsciiString theCommand,
3358                           const Handle(TColStd_HArray1OfAsciiString)& theArgsArray,
3359                           Standard_Integer &theArgIndex,
3360                           Standard_Integer theArgCount,
3361                           Standard_Integer theMaxArgs);
3362
3363 protected:
3364
3365   Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
3366   Handle(Graphic3d_ArrayOfPrimitives) myPArray;
3367
3368 };
3369
3370 void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
3371                               const Handle(Prs3d_Presentation)& thePrs,
3372                               const Standard_Integer theMode)
3373 {
3374   if (myPArray.IsNull() || theMode != 0)
3375   {
3376     return;
3377   }
3378
3379   Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
3380   if (!myMarkerAspect.IsNull())
3381   {
3382     aGroup->SetGroupPrimitivesAspect (myMarkerAspect);
3383   }
3384   else
3385   {
3386     aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
3387   }
3388   aGroup->AddPrimitiveArray (myPArray);
3389 }
3390
3391 Standard_Boolean MyPArrayObject::Init (Graphic3d_TypeOfPrimitiveArray thePrimType,
3392                                        const Handle(TColStd_HArray1OfAsciiString)& theDesc,
3393                                        const Handle(Graphic3d_AspectMarker3d)& theMarkerAspect,
3394                                        Standard_Boolean theToPatch)
3395 {
3396   myMarkerAspect = theMarkerAspect;
3397   if (!theToPatch)
3398   {
3399     myPArray.Nullify();
3400   }
3401
3402   // Parsing array description
3403   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
3404   Graphic3d_ArrayFlags anArrayFlags = Graphic3d_ArrayFlags_None;
3405
3406   const Standard_Integer anArgsCount = theDesc->Length();
3407   TCollection_AsciiString aCommand;
3408   for (Standard_Integer anArgIndex = theDesc->Lower(); anArgIndex <= theDesc->Upper(); )
3409   {
3410     aCommand = theDesc->Value (anArgIndex);
3411     aCommand.LowerCase();
3412
3413     if (CheckInputCommand ("-deinterleaved", theDesc, anArgIndex, 0, anArgsCount))
3414     {
3415       anArrayFlags |= Graphic3d_ArrayFlags_AttribsDeinterleaved;
3416     }
3417     else if (CheckInputCommand ("-mutable", theDesc, anArgIndex, 0, anArgsCount))
3418     {
3419       anArrayFlags |= Graphic3d_ArrayFlags_AttribsMutable;
3420       anArrayFlags |= Graphic3d_ArrayFlags_IndexesMutable;
3421     }
3422     // vertex command
3423     else if (CheckInputCommand ("v", theDesc, anArgIndex, 3, anArgsCount))
3424     {
3425       // vertex has a normal or normal with color or texel
3426       if (CheckInputCommand ("n", theDesc, anArgIndex, 3, anArgsCount))
3427       {
3428         anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexNormal;
3429       }
3430
3431       // vertex has a color
3432       if (CheckInputCommand ("c", theDesc, anArgIndex, 3, anArgsCount))
3433       {
3434         anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexColor;
3435       }
3436
3437       // vertex has a texel
3438       if (CheckInputCommand ("t", theDesc, anArgIndex, 2, anArgsCount))
3439       {
3440         anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexTexel;
3441       }
3442
3443       aVertexNum++;
3444     }
3445     // bound command
3446     else if (CheckInputCommand ("b", theDesc, anArgIndex, 1, anArgsCount))
3447     {
3448       // bound has color
3449       if (CheckInputCommand ("c", theDesc, anArgIndex, 3, anArgsCount))
3450       {
3451         anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_BoundColor;
3452       }
3453
3454       aBoundNum++;
3455     }
3456     // edge command
3457     else if (CheckInputCommand ("e", theDesc, anArgIndex, 1, anArgsCount))
3458     {
3459       aEdgeNum++;
3460     }
3461     // unknown command
3462     else
3463       anArgIndex++;
3464   }
3465
3466   if (myPArray.IsNull())
3467   {
3468     myPArray = Graphic3d_ArrayOfPrimitives::CreateArray (thePrimType, aVertexNum, aBoundNum, aEdgeNum, anArrayFlags);
3469   }
3470   else
3471   {
3472     if (myPArray->Type() != thePrimType
3473     ||  aVertexNum > myPArray->VertexNumberAllocated()
3474     ||  aEdgeNum   > myPArray->EdgeNumberAllocated()
3475     ||  aBoundNum  > myPArray->BoundNumberAllocated()
3476     || !myPArray->Attributes()->IsMutable()
3477     || (!myPArray->Indices().IsNull() && !myPArray->Indices()->IsMutable()))
3478     {
3479       std::cout << "Syntax error: array cannot be patched\n";
3480       return Standard_False;
3481     }
3482
3483     myPArray->Attributes()->NbElements = aVertexNum;
3484     if (Handle(Graphic3d_AttribBuffer) anAttribs = Handle(Graphic3d_AttribBuffer)::DownCast (myPArray->Attributes()))
3485     {
3486       anAttribs->Invalidate (0, aVertexNum - 1);
3487     }
3488     if (!myPArray->Indices().IsNull())
3489     {
3490       myPArray->Indices()->NbElements = aEdgeNum;
3491     }
3492     if (!myPArray->Bounds().IsNull())
3493     {
3494       myPArray->Bounds()->NbBounds = aBoundNum;
3495     }
3496   }
3497
3498   Standard_Integer aVertIndex = 0;
3499   for (Standard_Integer anArgIndex = theDesc->Lower(); anArgIndex <= theDesc->Upper(); )
3500   {
3501     aCommand = theDesc->Value (anArgIndex);
3502     aCommand.LowerCase();
3503     if (!aCommand.IsAscii()
3504       || aCommand.IsEmpty())
3505     {
3506       break;
3507     }
3508
3509     // skip beautifiers (syntax is not actually validated)
3510     if (aCommand == "-deinterleaved"
3511      || aCommand == "-mutable"
3512      || aCommand.Value (1) == '('
3513      || aCommand.Value (1) == ')'
3514      || aCommand.Value (1) == ',')
3515     {
3516       ++anArgIndex;
3517     }
3518     // vertex command
3519     else if (CheckInputCommand ("v", theDesc, anArgIndex, 3, anArgsCount))
3520     {
3521       const Graphic3d_Vec3 aVert ((float )theDesc->Value (anArgIndex - 3).RealValue(),
3522                                   (float )theDesc->Value (anArgIndex - 2).RealValue(),
3523                                   (float )theDesc->Value (anArgIndex - 1).RealValue());
3524       if ((anArrayFlags & Graphic3d_ArrayFlags_AttribsDeinterleaved) != 0
3525        || (anArrayFlags & Graphic3d_ArrayFlags_AttribsMutable) != 0)
3526       {
3527         ++aVertIndex;
3528         myPArray->SetVertice (aVertIndex, aVert.x(), aVert.y(), aVert.z());
3529       }
3530       else
3531       {
3532         aVertIndex = myPArray->AddVertex (aVert);
3533       }
3534
3535       // vertex has a normal or normal with color or texel
3536       if (CheckInputCommand ("n", theDesc, anArgIndex, 3, anArgsCount))
3537       {
3538         const Graphic3d_Vec3 aNorm ((float )theDesc->Value (anArgIndex - 3).RealValue(),
3539                                     (float )theDesc->Value (anArgIndex - 2).RealValue(),
3540                                     (float )theDesc->Value (anArgIndex - 1).RealValue());
3541         myPArray->SetVertexNormal (aVertIndex, aNorm.x(), aNorm.y(), aNorm.z());
3542       }
3543       
3544       if (CheckInputCommand ("c", theDesc, anArgIndex, 3, anArgsCount))
3545       {
3546         const Graphic3d_Vec3d aCol (theDesc->Value (anArgIndex - 3).RealValue(),
3547                                     theDesc->Value (anArgIndex - 2).RealValue(),
3548                                     theDesc->Value (anArgIndex - 1).RealValue());
3549         myPArray->SetVertexColor (aVertIndex, aCol.r(), aCol.g(), aCol.b());
3550       }
3551       if (CheckInputCommand ("t", theDesc, anArgIndex, 2, anArgsCount))
3552       {
3553         const Graphic3d_Vec2 aTex ((float )theDesc->Value (anArgIndex - 2).RealValue(),
3554                                    (float )theDesc->Value (anArgIndex - 1).RealValue());
3555         myPArray->SetVertexTexel (aVertIndex, aTex.x(), aTex.y());
3556       }
3557     }
3558     // bounds command
3559     else if (CheckInputCommand ("b", theDesc, anArgIndex, 1, anArgsCount))
3560     {
3561       Standard_Integer aVertCount = theDesc->Value (anArgIndex - 1).IntegerValue();
3562
3563       if (CheckInputCommand ("c", theDesc, anArgIndex, 3, anArgsCount))
3564         myPArray->AddBound (aVertCount,
3565                             theDesc->Value (anArgIndex - 3).RealValue(),
3566                             theDesc->Value (anArgIndex - 2).RealValue(),
3567                             theDesc->Value (anArgIndex - 1).RealValue());
3568
3569       else
3570         myPArray->AddBound (aVertCount);
3571     }
3572     // edge command
3573     else if (CheckInputCommand ("e", theDesc, anArgIndex, 1, anArgsCount))
3574     {
3575       const Standard_Integer anEdge = theDesc->Value (anArgIndex - 1).IntegerValue();
3576       myPArray->AddEdge (anEdge);
3577     }
3578     // unknown command
3579     else
3580     {
3581       std::cout << "Syntax error: unknown argument '" << theDesc->Value(anArgIndex) << "'\n";
3582       return Standard_False;
3583     }
3584   }
3585   return Standard_True;
3586 }
3587
3588 void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
3589                                        const Standard_Integer theMode)
3590 {
3591   if (theMode != 0
3592    || myPArray.IsNull())
3593   {
3594     return;
3595   }
3596
3597   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
3598   if (Handle(Graphic3d_ArrayOfTriangles) aTris = Handle(Graphic3d_ArrayOfTriangles)::DownCast (myPArray))
3599   {
3600     Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
3601     aSensitive->InitTriangulation (myPArray->Attributes(), myPArray->Indices(), TopLoc_Location(), true);
3602     theSelection->Add (aSensitive);
3603   }
3604   else if (Handle(Graphic3d_ArrayOfSegments) aSegs = Handle(Graphic3d_ArrayOfSegments)::DownCast (myPArray))
3605   {
3606     if (aSegs->EdgeNumber() > 0)
3607     {
3608       for (Standard_Integer aPntIter = 1; aPntIter <= aSegs->EdgeNumber(); aPntIter += 2)
3609       {
3610         Handle(Select3D_SensitiveSegment) aSeg = new Select3D_SensitiveSegment (anOwner, aSegs->Vertice (aSegs->Edge (aPntIter)), aSegs->Vertice (aSegs->Edge (aPntIter + 1)));
3611         aSeg->SetSensitivityFactor (4);
3612         theSelection->Add (aSeg);
3613       }
3614     }
3615     else
3616     {
3617       for (Standard_Integer aPntIter = 1; aPntIter <= aSegs->VertexNumber(); aPntIter += 2)
3618       {
3619         Handle(Select3D_SensitiveSegment) aSeg = new Select3D_SensitiveSegment (anOwner, aSegs->Vertice (aPntIter), aSegs->Vertice (aPntIter + 1));
3620         aSeg->SetSensitivityFactor (4);
3621         theSelection->Add (aSeg);
3622       }
3623     }
3624   }
3625   else
3626   {
3627     Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
3628     aSensitive->SetSensitivityFactor (8);
3629     aSensitive->InitPoints (myPArray->Attributes(), myPArray->Indices(), TopLoc_Location(), true);
3630     theSelection->Add (aSensitive);
3631   }
3632 }
3633
3634 bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand,
3635                                        const Handle(TColStd_HArray1OfAsciiString)& theArgsArray,
3636                                        Standard_Integer &theArgIndex,
3637                                        Standard_Integer theArgCount,
3638                                        Standard_Integer theMaxArgs)
3639 {
3640   // check if there is more elements than expected
3641   if (theArgIndex >= theMaxArgs)
3642     return false;
3643
3644   TCollection_AsciiString aStrCommand = theArgsArray->Value (theArgIndex);
3645   aStrCommand.LowerCase();
3646   if (aStrCommand.Search(theCommand) != 1 ||
3647       theArgIndex + (theArgCount - 1) >= theMaxArgs)
3648     return false;
3649
3650   // go to the first data element
3651   theArgIndex++;
3652
3653   // check data if it can be converted to numeric
3654   for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
3655   {
3656     aStrCommand = theArgsArray->Value (theArgIndex);
3657     if (!aStrCommand.IsRealValue())
3658       return false;
3659   }
3660
3661   return true;
3662 }
3663
3664 //=============================================================================
3665 //function : VDrawPArray
3666 //purpose  : Draws primitives array from list of vertexes, bounds, edges
3667 //=============================================================================
3668
3669 static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
3670 {
3671   Handle(AIS_InteractiveContext) aContextAIS = ViewerTest::GetAISContext();
3672   if (aContextAIS.IsNull())
3673   {
3674     std::cout << "Error: no active Viewer\n";
3675     return 1;
3676   }
3677   else if (argc < 3)
3678   {
3679     std::cout << "Syntax error: wrong number of arguments\n";
3680     return 1;
3681   }
3682
3683   // read the arguments
3684   Standard_Integer anArgIndex = 1;
3685   TCollection_AsciiString aName (argv[anArgIndex++]);
3686   TCollection_AsciiString anArrayType (argv[anArgIndex++]);
3687   anArrayType.LowerCase();
3688   Handle(MyPArrayObject) aPObject;
3689   if (anArrayType == "-shape")
3690   {
3691     Standard_CString aShapeName = argv[anArgIndex++];
3692     TopoDS_Shape aShape = DBRep::Get (aShapeName);
3693     Handle(Graphic3d_ArrayOfPrimitives) aTris = StdPrs_ShadedShape::FillTriangles (aShape);
3694     if (aShape.IsNull())
3695     {
3696       std::cout << "Syntax error: shape '" << aShapeName << "' is not found\n";
3697       return 1;
3698     }
3699     else if (aTris.IsNull())
3700     {
3701       std::cout << "Syntax error: shape '" << aShapeName << "' is not triangulated\n";
3702       return 1;
3703     }
3704
3705     aPObject = new MyPArrayObject (aTris);
3706     ViewerTest::Display (aName, aPObject);
3707     return 0;
3708   }
3709   else if (anArrayType == "-patch"
3710         || anArrayType == "-modify"
3711         || anArrayType == "-edit")
3712   {
3713     if (argc >= 3)
3714     {
3715       anArrayType = argv[anArgIndex++];
3716       anArrayType.LowerCase();
3717     }
3718
3719     if (GetMapOfAIS().IsBound2 (aName))
3720     {
3721       aPObject = Handle(MyPArrayObject)::DownCast (GetMapOfAIS().Find2 (aName));
3722     }
3723     if (aPObject.IsNull())
3724     {
3725       std::cout << "Syntax error: object '" << aName << "' cannot be found\n";
3726       return 1;
3727     }
3728   }
3729
3730   Standard_Boolean hasVertex = Standard_False;
3731
3732   Graphic3d_TypeOfPrimitiveArray aPrimType = Graphic3d_TOPA_UNDEFINED;
3733   if (anArrayType == "points")
3734   {
3735     aPrimType = Graphic3d_TOPA_POINTS;
3736   }
3737   else if (anArrayType == "segments")
3738   {
3739     aPrimType = Graphic3d_TOPA_SEGMENTS;
3740   }
3741   else if (anArrayType == "polylines")
3742   {
3743     aPrimType = Graphic3d_TOPA_POLYLINES;
3744   }
3745   else if (anArrayType == "triangles")
3746   {
3747     aPrimType = Graphic3d_TOPA_TRIANGLES;
3748   }
3749   else if (anArrayType == "trianglefans")
3750   {
3751     aPrimType = Graphic3d_TOPA_TRIANGLEFANS;
3752   }
3753   else if (anArrayType == "trianglestrips")
3754   {
3755     aPrimType = Graphic3d_TOPA_TRIANGLESTRIPS;
3756   }
3757   else if (anArrayType == "quads")
3758   {
3759     aPrimType = Graphic3d_TOPA_QUADRANGLES;
3760   }
3761   else if (anArrayType == "quadstrips")
3762   {
3763     aPrimType = Graphic3d_TOPA_QUADRANGLESTRIPS;
3764   }
3765   else if (anArrayType == "polygons")
3766   {
3767     aPrimType = Graphic3d_TOPA_POLYGONS;
3768   }
3769   if (aPrimType == Graphic3d_TOPA_UNDEFINED)
3770   {
3771     std::cout << "Syntax error: unexpected type of primitives array\n";
3772     return 1;
3773   }
3774
3775   Standard_Integer aLowerArg = anArgIndex;
3776   Handle(TColStd_HArray1OfAsciiString) anArgsArray = new TColStd_HArray1OfAsciiString (0, argc - 3);
3777   for (; anArgIndex < argc; ++anArgIndex)
3778   {
3779     TCollection_AsciiString aCommand (argv[anArgIndex]);
3780     aCommand.LowerCase();
3781     if (!aCommand.IsAscii())
3782     {
3783       di << "Unexpected argument: #" << anArgIndex - 1 << " , "
3784          << "should be an array element: 'v', 'b', 'e' \n";
3785       break;
3786     }
3787
3788     if (aCommand == "v")
3789     {
3790       hasVertex = Standard_True;
3791     }
3792
3793     anArgsArray->SetValue (anArgIndex - aLowerArg, aCommand);
3794   }
3795
3796   if (!hasVertex)
3797   {
3798     di << "You should pass any verticies in the list of array elements\n";
3799     return 1;
3800   }
3801
3802   Handle(Graphic3d_AspectMarker3d)    anAspPoints;
3803   if (aPrimType == Graphic3d_TOPA_POINTS)
3804   {
3805     anAspPoints = new Graphic3d_AspectMarker3d (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
3806   }
3807
3808   // create primitives array object
3809   if (aPObject.IsNull())
3810   {
3811     // register the object in map
3812     aPObject = new MyPArrayObject (aPrimType, anArgsArray, anAspPoints);
3813     VDisplayAISObject (aName, aPObject);
3814   }
3815   else
3816   {
3817     aPObject->Init (aPrimType, anArgsArray, anAspPoints, Standard_True);
3818     ViewerTest::CurrentView()->Redraw();
3819   }
3820   return 0;
3821 }
3822
3823 namespace
3824 {
3825   //! Auxiliary function for parsing translation vector - either 2D or 3D.
3826   static Standard_Integer parseTranslationVec (Standard_Integer theArgNb,
3827                                                const char**     theArgVec,
3828                                                gp_Vec&          theVec)
3829   {
3830     if (theArgNb < 2)
3831     {
3832       return 0;
3833     }
3834
3835     TCollection_AsciiString anX (theArgVec[0]);
3836     TCollection_AsciiString anY (theArgVec[1]);
3837     if (!anX.IsRealValue()
3838      || !anY.IsRealValue())
3839     {
3840       return 0;
3841     }
3842
3843     theVec.SetX (anX.RealValue());
3844     theVec.SetY (anY.RealValue());
3845     if (theArgNb >= 3)
3846     {
3847       TCollection_AsciiString anZ (theArgVec[2]);
3848       if (anZ.IsRealValue())
3849       {
3850         theVec.SetZ (anZ.RealValue());
3851         return 3;
3852       }
3853     }
3854     return 2;
3855   }
3856 }
3857
3858 //=======================================================================
3859 //function : VSetLocation
3860 //purpose  : Change location of AIS interactive object
3861 //=======================================================================
3862
3863 static Standard_Integer VSetLocation (Draw_Interpretor& theDI,
3864                                       Standard_Integer  theArgNb,
3865                                       const char**      theArgVec)
3866 {
3867   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
3868   ViewerTest_AutoUpdater anUpdateTool (aContext, ViewerTest::CurrentView());
3869   if (aContext.IsNull())
3870   {
3871     std::cout << "Error: no active view!\n";
3872     return 1;
3873   }
3874
3875   Standard_Boolean toPrintInfo = Standard_True;
3876   Handle(AIS_InteractiveObject) anObj;
3877   TCollection_AsciiString aCmdName (theArgVec[0]);
3878   aCmdName.LowerCase();
3879   for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
3880   {
3881     TCollection_AsciiString anArg = theArgVec[anArgIter];
3882     anArg.LowerCase();
3883     if (anUpdateTool.parseRedrawMode (anArg))
3884     {
3885       continue;
3886     }
3887     else if (anObj.IsNull())
3888     {
3889       const TCollection_AsciiString aName (theArgVec[anArgIter]);
3890       GetMapOfAIS().Find2 (aName, anObj);
3891       if (anObj.IsNull())
3892       {
3893         std::cout << "Error: object '" << aName << "' is not displayed!\n";
3894         return 1;
3895       }
3896     }
3897     else if (anArg == "-reset")
3898     {
3899       toPrintInfo = Standard_False;
3900       aContext->SetLocation (anObj, gp_Trsf());
3901     }
3902     else if (anArg == "-copyfrom"
3903           || anArg == "-copy")
3904     {
3905       if (anArgIter + 1 >= theArgNb)
3906       {
3907         std::cout << "Syntax error at '" << anArg << "'\n";
3908         return 1;
3909       }
3910
3911       const TCollection_AsciiString aName2 (theArgVec[anArgIter + 1]);
3912       Handle(AIS_InteractiveObject) anObj2;
3913       GetMapOfAIS().Find2 (aName2, anObj2);
3914       if (anObj2.IsNull())
3915       {
3916         std::cout << "Error: object '" << aName2 << "' is not displayed!\n";
3917         return 1;
3918       }
3919
3920       ++anArgIter;
3921       aContext->SetLocation (anObj, anObj2->LocalTransformation());
3922     }
3923     else if (anArg == "-rotate")
3924     {
3925       toPrintInfo = Standard_False;
3926       if (anArgIter + 7 >= theArgNb)
3927       {
3928         std::cout << "Syntax error at '" << anArg << "'\n";
3929         return 1;
3930       }
3931
3932       gp_Trsf aTrsf;
3933       aTrsf.SetRotation (gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[anArgIter + 1]),
3934                                          Draw::Atof (theArgVec[anArgIter + 2]),
3935                                          Draw::Atof (theArgVec[anArgIter + 3])),
3936                                  gp_Vec (Draw::Atof (theArgVec[anArgIter + 4]),
3937                                          Draw::Atof (theArgVec[anArgIter + 5]),
3938                                          Draw::Atof (theArgVec[anArgIter + 6]))),
3939                                          Draw::Atof (theArgVec[anArgIter + 7]) * (M_PI / 180.0));
3940       anArgIter += 7;
3941
3942       aTrsf = anObj->LocalTransformation() * aTrsf;
3943       aContext->SetLocation (anObj, aTrsf);
3944     }
3945     else if (anArg == "-translate")
3946     {
3947       toPrintInfo = Standard_False;
3948       gp_Vec aLocVec;
3949       Standard_Integer aNbParsed = parseTranslationVec (theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
3950       anArgIter += aNbParsed;
3951       if (aNbParsed == 0)
3952       {
3953         std::cout << "Syntax error at '" << anArg << "'\n";
3954         return 1;
3955       }
3956
3957       gp_Trsf aTrsf;
3958       aTrsf.SetTranslationPart (aLocVec);
3959       aTrsf = anObj->LocalTransformation() * aTrsf;
3960       aContext->SetLocation (anObj, aTrsf);
3961     }
3962     else if (anArg == "-scale"
3963           || anArg == "-setscale")
3964     {
3965       toPrintInfo = Standard_False;
3966       gp_XYZ aScaleLoc;
3967       Standard_Real aScale = 1.0;
3968       Standard_Boolean toPrintScale = Standard_True;
3969       Standard_Boolean hasScaleLoc  = Standard_False;
3970       if (anArgIter + 4 < theArgNb)
3971       {
3972         TCollection_AsciiString aScaleArgs[4] =
3973         {
3974           TCollection_AsciiString (theArgVec[anArgIter + 1]),
3975           TCollection_AsciiString (theArgVec[anArgIter + 2]),
3976           TCollection_AsciiString (theArgVec[anArgIter + 3]),
3977           TCollection_AsciiString (theArgVec[anArgIter + 4])
3978         };
3979         Standard_Integer aScaleArgIter = 0;
3980         for (; aScaleArgIter < 4; ++aScaleArgIter)
3981         {
3982           if (!aScaleArgs[aScaleArgIter].IsRealValue())
3983           {
3984             break;
3985           }
3986         }
3987         if (aScaleArgIter == 4)
3988         {
3989           aScaleLoc.SetCoord (aScaleArgs[0].RealValue(), aScaleArgs[1].RealValue(), aScaleArgs[2].RealValue());
3990           aScale = aScaleArgs[3].RealValue();
3991           anArgIter += 4;