0026056: AIS_LengthDimension can not build dimension for face-edge or edge-face
[occt.git] / src / ViewerTest / ViewerTest_RelationCommands.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_AngleDimension.hxx>
20 #include <AIS_Circle.hxx>
21 #include <AIS_ConcentricRelation.hxx>
22 #include <AIS_DiameterDimension.hxx>
23 #include <AIS_DisplayMode.hxx>
24 #include <AIS_EqualDistanceRelation.hxx>
25 #include <AIS_EqualRadiusRelation.hxx>
26 #include <AIS_FixRelation.hxx>
27 #include <AIS_IdenticRelation.hxx>
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_LengthDimension.hxx>
30 #include <AIS_ListIteratorOfListOfInteractive.hxx>
31 #include <AIS_ListOfInteractive.hxx>
32 #include <AIS_MapOfInteractive.hxx>
33 #include <AIS_OffsetDimension.hxx>
34 #include <AIS_ParallelRelation.hxx>
35 #include <AIS_PerpendicularRelation.hxx>
36 #include <AIS_Point.hxx>
37 #include <AIS_RadiusDimension.hxx>
38 #include <AIS_Relation.hxx>
39 #include <AIS_Shape.hxx>
40 #include <AIS_SymmetricRelation.hxx>
41 #include <AIS_TangentRelation.hxx>
42 #include <BRep_Builder.hxx>
43 #include <BRep_Tool.hxx>
44 #include <BRepAdaptor_Curve.hxx>
45 #include <BRepBuilderAPI_MakeVertex.hxx>
46 #include <BRepExtrema_ExtCC.hxx>
47 #include <BRepExtrema_ExtPC.hxx>
48 #include <BRepExtrema_ExtCF.hxx>
49 #include <BRepExtrema_ExtPF.hxx>
50 #include <BRepExtrema_ExtFF.hxx>
51 #include <BRepTools.hxx>
52 #include <Draw_Interpretor.hxx>
53 #include <Draw.hxx>
54 #include <Draw_Appli.hxx>
55 #include <Draw_Window.hxx>
56 #include <DBRep.hxx>
57 #include <ElSLib.hxx>
58 #include <Font_FontMgr.hxx>
59 #include <GC_MakePlane.hxx>
60 #include <Geom_CartesianPoint.hxx>
61 #include <Geom_Circle.hxx>
62 #include <Geom_Line.hxx>
63 #include <Geom_Plane.hxx>
64 #include <GeomAPI_IntCS.hxx>
65 #include <gce_MakeLin.hxx>
66 #include <gce_MakePln.hxx>
67 #include <gp_Circ.hxx>
68 #include <gp_Pln.hxx>
69 #include <IntAna_IntConicQuad.hxx>
70 #include <IntAna_Quadric.hxx>
71 #include <Precision.hxx>
72 #include <StdSelect.hxx>
73 #include <TCollection_AsciiString.hxx>
74 #include <TCollection_ExtendedString.hxx>
75 #include <TColStd_MapOfInteger.hxx>
76 #include <TopAbs.hxx>
77 #include <TopAbs_ShapeEnum.hxx>
78 #include <TopExp.hxx>
79 #include <TopExp_Explorer.hxx>
80 #include <TopoDS.hxx>
81 #include <TopoDS_Face.hxx>
82 #include <TopoDS_Solid.hxx>
83 #include <TopoDS_Vertex.hxx>
84 #include <V3d_Viewer.hxx>
85 #include <V3d_View.hxx>
86 #include <V3d.hxx>
87 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
88 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
89 #include <ViewerTest_EventManager.hxx>
90
91 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
92                                            const Handle(AIS_InteractiveObject)& theAISObj,
93                                            Standard_Boolean theReplaceIfExists = Standard_True);
94 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
95 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
96 extern Handle(AIS_InteractiveContext)& TheAISContext ();
97
98 #define VertexMask 0x01
99 #define EdgeMask 0x02
100 #define FaceMask 0x04
101
102 //=======================================================================
103 //function : Get3DPointAtMousePosition
104 //purpose  : Calculates the 3D points corresponding to the mouse position
105 //           in the plane of the view
106 //=======================================================================
107 static gp_Pnt Get3DPointAtMousePosition()
108 {
109   Handle(V3d_View) aView = ViewerTest::CurrentView();
110
111   Standard_Real xv,yv,zv;
112   aView->Proj (xv,yv,zv);
113   Standard_Real xat,yat,zat;
114   aView->At(xat,yat,zat);
115   gp_Pln aPlane (gp_Pnt(xat,yat,zat), gp_Dir(xv,yv,zv));
116   
117   Standard_Integer aPixX, aPixY;
118   Standard_Real aX, aY, aZ, aDX, aDY, aDZ;
119
120   ViewerTest::GetMousePosition (aPixX, aPixY);
121   aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDX, aDY, aDZ);
122   gp_Lin aLine( gp_Pnt(aX, aY, aZ), gp_Dir(aDX, aDY, aDZ) );
123
124   // Compute intersection
125   Handle(Geom_Line) aGeomLine = new Geom_Line (aLine);
126   Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
127   GeomAPI_IntCS anIntersector (aGeomLine, aGeomPlane);
128   if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
129   {
130     return gp::Origin();
131   }
132   return anIntersector.Point (1);
133 }
134
135 //=======================================================================
136 //function : Get3DPointAtMousePosition
137 //purpose  : Calculates the 3D points corresponding to the mouse position
138 //           in the plane of the view
139 //=======================================================================
140 static Standard_Boolean Get3DPointAtMousePosition (const gp_Pnt& theFirstPoint,
141                                                    const gp_Pnt& theSecondPoint,
142                                                    gp_Pnt& theOutputPoint)
143 {
144   theOutputPoint = gp::Origin();
145
146   Handle(V3d_View) aView = ViewerTest::CurrentView();
147
148   Standard_Integer aPixX, aPixY;
149   Standard_Real aX, aY, aZ, aDx, aDy, aDz, aUx, aUy, aUz;
150
151   // Get 3D point in view coordinates and projection vector from the pixel point.
152   ViewerTest::GetMousePosition (aPixX, aPixY);
153   aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDx, aDy, aDz);
154   gp_Lin aProjLin (gp_Pnt(aX, aY, aZ), gp_Dir(aDx, aDy, aDz));
155
156   // Get plane
157   gp_Vec aDimVec (theFirstPoint, theSecondPoint);
158   aView->Up (aUx, aUy, aUz);
159   gp_Vec aViewUp (aUx, aUy, aUz);
160
161   if (aDimVec.IsParallel (aViewUp, Precision::Angular()))
162   {
163     theOutputPoint = Get3DPointAtMousePosition();
164     return Standard_True;
165   }
166
167   gp_Vec aDimNormal = aDimVec ^ aViewUp;
168   gp_Pln aViewPlane= gce_MakePln (theFirstPoint, aDimNormal);
169
170   // Get intersection of view plane and projection line
171   Handle(Geom_Plane) aPlane = new Geom_Plane (aViewPlane);
172   Handle(Geom_Line) aProjLine = new Geom_Line (aProjLin);
173   GeomAPI_IntCS anIntersector (aProjLine, aPlane);
174   if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
175   {
176     return Standard_False;
177   }
178
179   theOutputPoint = anIntersector.Point (1);
180   return Standard_True;
181 }
182
183 //=======================================================================
184 //function : ParseDimensionParams
185 //purpose  : Auxilliary function: sets aspect parameters for
186 //           length, angle, radius and diameter dimension.
187 //
188 //draw args: -text [3d|2d] [wf|sh|wireframe|shading] [Size]
189 //           -label [left|right|hcenter|hfit] [top|bottom|vcenter|vfit]
190 //           -arrow [external|internal|fit] [Length(int)]
191 //           -arrowangle ArrowAngle(degrees)
192 //           -plane xoy|yoz|zox
193 //           -flyout FloatValue -extension FloatValue
194 //           -value CustomNumberValue
195 //           -dispunits DisplayUnitsString
196 //           -modelunits ModelUnitsString
197 //           -showunits
198 //           -hideunits
199 //
200 // Warning! flyout is not an aspect value, it is for dimension parameter
201 // likewise text position, but text position override other paramaters.
202 // For text position changing use 'vmovedim'.
203 //=======================================================================
204 static int ParseDimensionParams (Standard_Integer  theArgNum,
205                                  const char**      theArgVec,
206                                  Standard_Integer  theStartIndex,
207                                  const Handle(Prs3d_DimensionAspect)& theAspect,
208                                  Standard_Boolean& theIsCustomPlane, gp_Pln& thePlane,
209                                  NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
210                                  NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
211                                  NCollection_List<Handle(AIS_InteractiveObject)>* theShapeList = NULL)
212 {
213   theRealParams.Clear();
214   theStringParams.Clear();
215
216   theIsCustomPlane  = Standard_False;
217
218   // Begin from the second parameter: the first one is dimension name
219   for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
220   {
221     TCollection_AsciiString aParam (theArgVec[anIt]);
222     aParam.LowerCase();
223
224     if (aParam.Search ("-") == -1)
225     {
226       continue;
227     }
228
229     // Boolean flags
230     if (aParam.IsEqual ("-showunits"))
231     {
232       theAspect->MakeUnitsDisplayed (Standard_True);
233       continue;
234     }
235     else if (aParam.IsEqual ("-hideunits"))
236     {
237       theAspect->MakeUnitsDisplayed (Standard_False);
238       continue;
239     }
240
241     // Before all non-boolean flags parsing check if a flag have at least one value.
242     if (anIt + 1 >= theArgNum)
243     {
244       std::cerr << "Error: "<< aParam <<" flag should have value.\n";
245       return 1;
246     }
247
248     // Non-boolean flags
249     if (aParam.IsEqual ("-shape")
250      || aParam.IsEqual ("-shapes"))
251     {
252       if (!theShapeList)
253       {
254         std::cerr << "Error: unknown parameter '" << aParam << "'\n";
255         return 1;
256       }
257
258       do
259       {
260         anIt++;
261         TCollection_AsciiString anArgString = theArgVec[anIt];
262         Handle(AIS_InteractiveObject) anAISObject;
263         Standard_CString aStr   = anArgString.ToCString();
264         TopoDS_Shape     aShape =  DBRep::Get (aStr);
265         if (!aShape.IsNull())
266         {
267           anAISObject = new AIS_Shape (aShape);
268         }
269         else
270         {
271           if (!GetMapOfAIS().IsBound2 (anArgString))
272           {
273             std::cerr << "Error: shape with name '" << aStr << "' is not found.\n";
274             return 1;
275           }
276
277           anAISObject = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anArgString));
278           if (anAISObject.IsNull())
279           {
280             std::cerr << "Error: " << aStr <<" is not a shape.\n";
281             return 1;
282           }
283         }
284         theShapeList->Append (anAISObject);
285       }
286       while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
287     }
288     else if (aParam.IsEqual ("-text"))
289     {
290       do
291       {
292         anIt++;
293         TCollection_AsciiString aValue (theArgVec[anIt]);
294         aValue.LowerCase();
295         if (aValue.IsEqual ("3d"))
296         {
297           theAspect->MakeText3d (Standard_True);
298         }
299         else if (aValue.IsEqual ("2d"))
300         {
301           theAspect->MakeText3d (Standard_False);
302         }
303         else if (aValue.IsEqual ("wf") || aValue.IsEqual ("wireframe"))
304         {
305            theAspect->MakeTextShaded (Standard_False);
306         }
307         else if ( aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
308         {
309           theAspect->MakeTextShaded (Standard_True);
310         }
311         else if (aValue.IsIntegerValue()) // text size
312         {
313           theAspect->TextAspect()->SetHeight (Draw::Atoi (aValue.ToCString()));
314         }
315       }
316       while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
317     }
318     else if (aParam.IsEqual ("-font"))
319     {
320       if (anIt + 1 >= theArgNum)
321       {
322         std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
323         return 1;
324       }
325
326       theAspect->TextAspect()->SetFont (theArgVec[++anIt]);
327     }
328     else if (aParam.IsEqual ("-label"))
329     {
330       do
331       {
332         anIt++;
333         TCollection_AsciiString aParamValue (theArgVec[anIt]);
334         aParamValue.LowerCase();
335
336         if (aParamValue == "left")         { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left);  }
337         else if (aParamValue == "right")   { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right); }
338         else if (aParamValue == "hcenter") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);}
339         else if (aParamValue == "hfit")    { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit);   }
340         else if (aParamValue == "above")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Above); }
341         else if (aParamValue == "below")   { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Below); }
342         else if (aParamValue == "vcenter") { theAspect->SetTextVerticalPosition   (Prs3d_DTVP_Center);}
343         else
344         {
345           std::cerr << "Error: invalid label position: '" << aParamValue << "'.\n";
346           return 1;
347         }
348       }
349       while (anIt + 1 < theArgNum && theArgVec[anIt+1][0] != '-');
350     }
351     else if (aParam.IsEqual ("-arrow"))
352     {
353       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
354       aLocalParam.LowerCase();
355
356       if (aLocalParam == "external") { theAspect->SetArrowOrientation (Prs3d_DAO_External); }
357       if (aLocalParam == "internal") { theAspect->SetArrowOrientation (Prs3d_DAO_Internal); }
358       if (aLocalParam == "fit")      { theAspect->SetArrowOrientation (Prs3d_DAO_Fit); }
359     }
360     else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
361     {
362       TCollection_AsciiString aValue (theArgVec[++anIt]);
363       if (!aValue.IsRealValue())
364       {
365         std::cerr << "Error: arrow lenght should be float degree value.\n";
366         return 1;
367       }
368       theAspect->ArrowAspect()->SetLength (Draw::Atof (aValue.ToCString()));
369     }
370     else if (aParam.IsEqual ("-arrowangle") || aParam.IsEqual ("-arangle"))
371     {
372       TCollection_AsciiString aValue (theArgVec[++anIt]);
373       if (!aValue.IsRealValue())
374       {
375         std::cerr << "Error: arrow angle should be float degree value.\n";
376         return 1;
377       }
378       theAspect->ArrowAspect()->SetAngle (Draw::Atof (aValue.ToCString()));
379     }
380     else if (aParam.IsEqual ("-color"))
381     {
382       theAspect->SetCommonColor (Quantity_Color (ViewerTest::GetColorFromName (theArgVec[++anIt])));
383     }
384     else if (aParam.IsEqual ("-extension"))
385     {
386       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
387       if (!aLocalParam.IsRealValue())
388       {
389         std::cerr << "Error: extension size for dimension should be real value.\n";
390         return 1;
391       }
392       theAspect->SetExtensionSize (Draw::Atof (aLocalParam.ToCString()));
393     }
394     else if (aParam.IsEqual ("-plane"))
395     {
396       TCollection_AsciiString aValue (theArgVec[++anIt]);
397       aValue.LowerCase();
398       if (aValue == "xoy")
399       {
400         theIsCustomPlane = Standard_True;
401         thePlane = gp_Pln (gp_Ax3 (gp::XOY()));
402       }
403       else if (aValue == "zox")
404       {
405         theIsCustomPlane = Standard_True;
406         thePlane = gp_Pln (gp_Ax3 (gp::ZOX()));
407       }
408       else if (aValue == "yoz")
409       {
410         theIsCustomPlane = Standard_True;
411         thePlane = gp_Pln (gp_Ax3 (gp::YOZ()));
412       }
413       else
414       {
415         std::cerr << "Error: wrong plane '" << aValue << "'.\n";
416         return 1;
417       }
418     }
419     else if (aParam.IsEqual ("-flyout"))
420     {
421       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
422       if (!aLocalParam.IsRealValue())
423       {
424         std::cerr << "Error: flyout for dimension should be real value.\n";
425         return 1;
426       }
427
428       theRealParams.Bind ("flyout", Draw::Atof (aLocalParam.ToCString()));
429     }
430     else if (aParam.IsEqual ("-value"))
431     {
432       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
433       if (!aLocalParam.IsRealValue())
434       {
435         std::cerr << "Error: dimension value for dimension should be real value.\n";
436         return 1;
437       }
438
439       theRealParams.Bind ("value", Draw::Atof (aLocalParam.ToCString()));
440     }
441     else if (aParam.IsEqual ("-modelunits"))
442     {
443       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
444
445       theStringParams.Bind ("modelunits", aLocalParam);
446     }
447     else if (aParam.IsEqual ("-dispunits"))
448     {
449       TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
450
451       theStringParams.Bind ("dispunits", aLocalParam);
452     }
453     else
454     {
455       std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
456       return 1;
457     }
458   }
459
460   return 0;
461 }
462
463 //=======================================================================
464 //function : SetDimensionParams
465 //purpose  : Sets parameters for dimension
466 //=======================================================================
467 static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
468                                 const NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
469                                 const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
470 {
471   if (theRealParams.IsBound ("flyout"))
472   {
473     theDim->SetFlyout (theRealParams.Find ("flyout"));
474   }
475
476   if (theRealParams.IsBound ("value"))
477   {
478     theDim->SetCustomValue (theRealParams.Find ("value"));
479   }
480
481   if (theStringParams.IsBound ("modelunits"))
482   {
483     theDim->SetModelUnits (theStringParams.Find ("modelunits"));
484   }
485
486   if (theStringParams.IsBound ("dispunits"))
487   {
488     theDim->SetDisplayUnits (theStringParams.Find ("dispunits"));
489   }
490 }
491
492 //=======================================================================
493 //function : VDimBuilder
494 //purpose  : Command for building dimension presentations: angle,
495 //           length, radius, diameter
496 //=======================================================================
497 static int VDimBuilder (Draw_Interpretor& /*theDi*/,
498                         Standard_Integer  theArgsNb,
499                         const char**      theArgs)
500 {
501   if (theArgsNb < 2)
502   {
503     std::cerr << "Error: wrong number of arguments.\n";
504     return 1;
505   }
506
507   // Parse parameters
508   TCollection_AsciiString aName (theArgs[1]);
509
510   NCollection_List<Handle(AIS_InteractiveObject)> aShapes;
511   Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
512   Standard_Boolean isPlaneCustom = Standard_False;
513   gp_Pln aWorkingPlane;
514
515   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
516   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
517
518   TCollection_AsciiString aDimType(theArgs[2]);
519   aDimType.LowerCase();
520   AIS_KindOfDimension aKindOfDimension;
521   if (aDimType == "-length")
522   {
523     aKindOfDimension = AIS_KOD_LENGTH;
524   }
525   else if (aDimType == "-angle")
526   {
527     aKindOfDimension = AIS_KOD_PLANEANGLE;
528   }
529   else if (aDimType == "-radius")
530   {
531     aKindOfDimension = AIS_KOD_RADIUS;
532   }
533   else if (aDimType == "-diameter" || aDimType == "-diam")
534   {
535     aKindOfDimension = AIS_KOD_DIAMETER;
536   }
537   else
538   {
539     std::cerr << "Error: wrong type of dimension.\n";
540     return 1;
541   }
542
543
544   if (ParseDimensionParams (theArgsNb, theArgs, 3,
545                             anAspect,isPlaneCustom,aWorkingPlane,
546                             aRealParams, aStringParams, &aShapes))
547   {
548     return 1;
549   }
550
551   // Build dimension
552   Handle(AIS_Dimension) aDim;
553   switch (aKindOfDimension)
554   {
555     case AIS_KOD_LENGTH:
556     {
557       if (aShapes.Extent() == 1)
558       {
559         if (aShapes.First()->Type() == AIS_KOI_Shape
560           && (Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape().ShapeType() != TopAbs_EDGE)
561         {
562           std::cerr << theArgs[0] << ": wrong shape type.\n";
563           return 1;
564         }
565         if (!isPlaneCustom)
566         {
567           std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
568           return 1;
569         }
570
571         // Adjust working plane
572         TopoDS_Edge anEdge = TopoDS::Edge ((Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape());
573         TopoDS_Vertex aFirst, aSecond;
574         TopExp::Vertices (anEdge, aFirst, aSecond);
575         aDim = new AIS_LengthDimension (anEdge, aWorkingPlane);
576
577         // Move standard plane (XOY, YOZ or ZOX) to the first point to make it working for dimension
578         aWorkingPlane.SetLocation (Handle(AIS_LengthDimension)::DownCast (aDim)->FirstPoint());
579       }
580       else if (aShapes.Extent() == 2)
581       {
582         TopoDS_Shape aShape1, aShape2;
583
584         // Getting shapes
585         if (aShapes.First()->DynamicType() == STANDARD_TYPE (AIS_Point))
586         {
587           aShape1 = Handle(AIS_Point)::DownCast (aShapes.First ())->Vertex();
588         }
589         else if (aShapes.First()->Type() == AIS_KOI_Shape)
590         {
591           aShape1 = (Handle(AIS_Shape)::DownCast (aShapes.First()))->Shape();
592         }
593
594         if (aShapes.Last()->DynamicType() == STANDARD_TYPE (AIS_Point))
595         {
596           aShape2 = Handle(AIS_Point)::DownCast (aShapes.Last ())->Vertex();
597         }
598         else if (aShapes.Last()->Type() == AIS_KOI_Shape)
599         {
600           aShape2 = (Handle(AIS_Shape)::DownCast (aShapes.Last()))->Shape();
601         }
602
603         if (aShape1.IsNull() || aShape2.IsNull())
604         {
605           std::cerr << theArgs[0] << ": wrong shape type.\n";
606           return 1;
607         }
608
609         // Face-Face case
610         if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_FACE)
611         {
612           aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Face (aShape2));
613         }
614         else if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_EDGE)
615         {
616           aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Edge (aShape2));
617         }
618         else if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_FACE)
619         {
620           aDim = new AIS_LengthDimension (TopoDS::Face (aShape2), TopoDS::Edge (aShape1));
621         }
622         else
623         {
624           if (!isPlaneCustom)
625           {
626             std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
627             return 1;
628           }
629           // Vertex-Vertex case
630           if (aShape1.ShapeType() == TopAbs_VERTEX)
631           {
632             aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1)));
633           }
634           else if (aShape2.ShapeType() == TopAbs_VERTEX)
635           {
636             aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2)));
637           }
638
639           aDim = new AIS_LengthDimension (aShape1, aShape2, aWorkingPlane);
640         }
641       }
642       else
643       {
644         std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
645         return 1;
646       }
647
648       break;
649     }
650     case AIS_KOD_PLANEANGLE:
651     {
652       if (aShapes.Extent() == 1 && aShapes.First()->Type()==AIS_KOI_Shape)
653       {
654         Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First());
655         if (aShape->Shape().ShapeType() == TopAbs_FACE)
656           aDim = new AIS_AngleDimension (TopoDS::Face(aShape->Shape()));
657       }
658       if (aShapes.Extent() == 2)
659       {
660         Handle(AIS_Shape) aShape1 = Handle(AIS_Shape)::DownCast(aShapes.First());
661         Handle(AIS_Shape) aShape2 = Handle(AIS_Shape)::DownCast(aShapes.Last());
662         if (!aShape1.IsNull() && !aShape2.IsNull()
663           && aShape1->Shape().ShapeType() == TopAbs_EDGE
664           && aShape2->Shape().ShapeType() == TopAbs_EDGE)
665           aDim = new AIS_AngleDimension (TopoDS::Edge(aShape1->Shape()),TopoDS::Edge(aShape2->Shape()));
666         else
667         {
668           std::cerr << theArgs[0] << ": wrong shapes for angle dimension.\n";
669           return 1;
670         }
671       }
672       else if (aShapes.Extent() == 3)
673       {
674         gp_Pnt aP1, aP2, aP3;
675         Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
676         if (aPoint.IsNull())
677           return 1;
678         aP1 = aPoint->Component()->Pnt();
679         aShapes.RemoveFirst();
680         aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
681         if (aPoint.IsNull())
682           return 1;
683         aP2 = aPoint->Component()->Pnt();
684         aShapes.RemoveFirst();
685         aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
686         if (aPoint.IsNull())
687           return 1;
688         aP3 = aPoint->Component()->Pnt();
689         aDim = new AIS_AngleDimension (aP1, aP2, aP3);
690       }
691       else
692       {
693         std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
694         return 1;
695       }
696
697       break;
698     }
699     case AIS_KOD_RADIUS: // radius of the circle
700     {
701       if (aShapes.Extent() == 1)
702       {
703         if (aShapes.First()->DynamicType() == STANDARD_TYPE(AIS_Circle))
704         {
705           Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
706           gp_Circ aCircle = aShape->Circle()->Circ();
707           aDim = new AIS_RadiusDimension (aCircle);
708         }
709         else
710         {
711           Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aShapes.First());
712           if (aShape.IsNull())
713           {
714             std::cerr << "Error: shape for radius is of wrong type.\n";
715             return 1;
716           }
717           aDim = new AIS_RadiusDimension (aShape->Shape());
718         }
719       }
720       else
721       {
722         std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
723         return 1;
724       }
725
726       break;
727     }
728     case AIS_KOD_DIAMETER:
729     {
730       if (aShapes.Extent() == 1)
731       {
732         if (aShapes.First()->DynamicType() == STANDARD_TYPE(AIS_Circle))
733         {
734           Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
735           gp_Circ aCircle = aShape->Circle()->Circ();
736           aDim = new AIS_DiameterDimension (aCircle);
737         }
738         else
739         {
740           Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aShapes.First());
741           if (aShape.IsNull())
742           {
743             std::cerr << "Error: shape for radius is of wrong type.\n";
744             return 1;
745           }
746           aDim = new AIS_DiameterDimension (aShape->Shape());
747         }
748       }
749       else
750       {
751         std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
752         return 1;
753       }
754
755       break;
756     }
757     default:
758     {
759       std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
760       return 1;
761     }
762   }
763
764   // Check dimension geometry
765   if (!aDim->IsValid())
766   {
767     std::cerr << theArgs[0] << ":dimension geometry is invalid, " << aDimType.ToCString()
768       << " dimension can't be built on input shapes.\n";
769     return 1;
770   }
771
772   aDim->SetDimensionAspect (anAspect);
773
774   SetDimensionParams (aDim, aRealParams, aStringParams);
775
776   VDisplayAISObject (aName,aDim);
777
778   return 0;
779 }
780
781 //=======================================================================
782 //function : VAngleDimBuilder
783 //purpose  : 
784 //=======================================================================
785
786 static int VAngleDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
787 {
788   Standard_Integer aCurrentIndex;
789   if (argc!=2)
790   {
791     di << argv[0] << " error : wrong number of parameters.\n";
792     return 1;
793   }
794
795   TheAISContext()->CloseAllContexts();
796   aCurrentIndex =  TheAISContext()->OpenLocalContext();
797   // Set selection mode for edges.
798   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
799   di << "Select two edges coplanar or not.\n";
800
801   Standard_Integer anArgsNum = 5;
802   const char *aBuffer[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
803   const char **anArgsVec = (const char **) aBuffer;
804   while (ViewerMainLoop (anArgsNum, anArgsVec)) { }
805
806   TopoDS_Shape aFirstShape;
807   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
808   {
809     aFirstShape = TheAISContext()->SelectedShape();
810   }
811
812   if (aFirstShape.IsNull())
813   {
814     di << argv[0] << " error : no picked shape.\n";
815     return 1;
816   }
817
818   if (aFirstShape.ShapeType()== TopAbs_EDGE)
819   {
820     while (ViewerMainLoop (anArgsNum, anArgsVec)) { }
821
822     TopoDS_Shape aSecondShape;
823     for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
824     {
825       aSecondShape = TheAISContext()->SelectedShape();
826     }
827
828     if (aSecondShape.IsNull())
829     {
830       di << argv[0] << " error : no picked shape.\n";
831       return 1;
832     }
833
834     if (aSecondShape.ShapeType() != TopAbs_EDGE)
835     {
836       di << argv[0] <<" error: you should have selected an edge.\n"; return 1;
837     }
838
839     // Close local context to draw dimension in the neutral point.
840     TheAISContext()->CloseLocalContext (aCurrentIndex);
841
842     // Construct the dimension.
843     Handle (AIS_AngleDimension) aDim= new AIS_AngleDimension (TopoDS::Edge(aFirstShape) ,TopoDS::Edge(aSecondShape));
844     VDisplayAISObject (argv[1], aDim);
845   }
846   else
847   {
848     di << argv[0] << " error: you must select 2 edges.\n";
849     return 1;
850   }
851
852   return 0;
853 }
854
855 //==============================================================================
856 //function : VDiameterDim
857 //purpose  : Display the diameter dimension of a face or an edge.
858 //Draw arg : vdiameterdim Name 
859 //==============================================================================
860
861 static int VDiameterDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
862 {
863   // Declarations
864   Standard_Integer aCurrentIndex;
865
866   // Verification
867   if (argc != 2)
868   {
869     di<<" vdiameterdim error"<<"\n";
870     return 1;
871   }
872
873   // Close all local contexts
874   TheAISContext()->CloseAllContexts();
875   // Open local context and get its index for recovery
876   TheAISContext()->OpenLocalContext();
877   aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
878   
879   // Activate 'edge' selection mode
880   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
881   di<<" Select an circled edge."<<"\n";
882   
883   // Loop that will handle the picking.
884   Standard_Integer argcc = 5;
885   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
886   const char **argvv = (const char **) buff;
887   while (ViewerMainLoop( argcc, argvv) ) { }
888   // end of the loop.
889   
890   TopoDS_Shape aShape;
891   for(TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
892   {
893     aShape = TheAISContext()->SelectedShape();
894   }
895
896   if (aShape.IsNull())
897   {
898     di << argv[0] << ": no shape is selected." << "\n";
899     return 1;
900   }
901
902   if (aShape.ShapeType() != TopAbs_EDGE)
903   {
904     di << " vdiameterdim error: the selection of a face or an edge was expected." << "\n";
905     return 1;
906   }
907
908   // Compute the radius
909   BRepAdaptor_Curve aCurve (TopoDS::Edge (aShape));
910
911   if (aCurve.GetType() != GeomAbs_Circle)
912   {
913     di << "vdiameterdim error: the edge is not a circular one." << "\n";
914     return 1;
915   }
916
917   // Construction of the diameter dimension.
918   TheAISContext()->CloseLocalContext (aCurrentIndex);
919   Handle (AIS_DiameterDimension) aDiamDim= new AIS_DiameterDimension (aShape);
920   VDisplayAISObject (argv[1], aDiamDim);
921
922   return 0;
923 }
924
925
926 //==============================================================================
927 // Fonction  vconcentric
928 // -----------------  Uniquement par selection dans le viewer.
929 //==============================================================================
930
931 //==============================================================================
932 //function : VConcentric
933 //purpose  : Display the concentric relation between two surfaces.
934 //Draw arg : vconcentric Name
935 //==============================================================================
936 static int VConcentricBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
937 {
938   // Declarations
939   Standard_Integer myCurrentIndex;
940   
941   // Verification
942   if (argc!=2) {di<<"vconcentric  error."<<"\n";return 1;}
943   // Fermeture des contextes locaux
944   TheAISContext()->CloseAllContexts();
945   // Ouverture d'un contexte local et recuperation de son index.
946   TheAISContext()->OpenLocalContext();
947   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
948   
949   // On active les modes de selections Edges et Faces.
950   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
951   di<<" Select a circled edge."<<"\n";
952   
953   // Boucle d'attente waitpick.
954   Standard_Integer argcc = 5;
955   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
956   const char **argvv = (const char **) buff;
957   while (ViewerMainLoop( argcc, argvv) ) { }
958   // fin de la boucle
959   
960   TopoDS_Shape ShapeA;
961   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
962     ShapeA = TheAISContext()->SelectedShape();
963   }
964   // ShapeA est un edge
965   // ==================
966   if (ShapeA.ShapeType()==TopAbs_EDGE  ) {
967     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
968     di<<" Select an edge."<<"\n";
969     
970     // Boucle d'attente waitpick.
971     Standard_Integer argccc = 5;
972     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
973     const char **argvvv = (const char **) bufff;
974     while (ViewerMainLoop( argccc, argvvv) ) { }
975     // fin de la boucle
976     
977     TopoDS_Shape ShapeB;
978     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
979       ShapeB = TheAISContext()->SelectedShape();
980     }
981     if (ShapeB.ShapeType()!=TopAbs_EDGE  ) {
982       di<<" vconcentric error: select an edge."<<"\n";return 1;
983     }
984      
985     // Construction du plane.
986     // On recupere le centre du cercle A.
987     BRepAdaptor_Curve theCurveA(TopoDS::Edge(ShapeA) );
988     gp_Circ theCircleA=theCurveA.Circle();
989     gp_Pnt theCenterA=theCircleA.Location();
990     // On recupere deux points sur le cercle A
991     gp_Pnt B= theCurveA.Value(0.25);
992     gp_Pnt C= theCurveA.Value(0.75);
993     // Construction du plane.
994     GC_MakePlane MkPlane(theCenterA ,B ,C );
995     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
996     
997     // Fermeture du context local
998     TheAISContext()->CloseLocalContext(myCurrentIndex);
999     
1000     Handle (AIS_ConcentricRelation) myConcentry= new AIS_ConcentricRelation(ShapeA, ShapeB, theGeomPlane );
1001     TheAISContext()->Display(myConcentry );
1002     GetMapOfAIS().Bind (myConcentry,argv[1]);
1003   }
1004   
1005   
1006   else {
1007     di<<" vconcentric  error: the selection of a face or an edge was expected."<<"\n";return 1;
1008   }
1009   
1010   return 0;
1011   
1012   
1013   
1014   
1015 }
1016
1017 //==============================================================================
1018 //function : VEqualDistRelation
1019 //purpose  : 
1020 //Draw arg : vdiameterdim Name DiameterValue
1021 //==============================================================================
1022 static int VEqualDistRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1023 {
1024   // Declarations
1025   Standard_Integer myCurrentIndex;
1026   
1027   // Verification
1028   if (argc!=2) {di<<" vequaldistrelation error: no arguments allowed."<<"\n";return 1;}
1029   
1030   // Fermeture des contextes locaux
1031   TheAISContext()->CloseAllContexts();
1032   
1033   // Ouverture d'un contexte local et recuperation de son index.
1034   TheAISContext()->OpenLocalContext();
1035   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1036   
1037   // On active les modes de selections Edges et Vertexes.
1038   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
1039   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1040   di<<" Select an edge or a vertex"<<"\n";
1041   
1042   // Boucle d'attente waitpick.
1043   Standard_Integer argc1 = 5;
1044   const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1045   const char **argv1 = (const char **) buf1;
1046   while (ViewerMainLoop( argc1, argv1) ) { }
1047   // fin de la boucle
1048   
1049   TopoDS_Shape ShapeA;
1050   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1051     ShapeA = TheAISContext()->SelectedShape();
1052   }
1053   
1054   di<<" Select an edge or a vertex"<<"\n";
1055   // Boucle d'attente waitpick.
1056   Standard_Integer argc2 = 5;
1057   const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1058   const char **argv2 = (const char **) buf2;
1059   while (ViewerMainLoop( argc2, argv2) ) { }
1060   // fin de la boucle
1061   
1062   TopoDS_Shape ShapeB;
1063   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1064     ShapeB = TheAISContext()->SelectedShape();
1065   }
1066   
1067   // Verification des resultats.
1068   if (ShapeA.ShapeType()==TopAbs_EDGE && ShapeB.ShapeType()==TopAbs_EDGE  ) {
1069     // A et B sont des edges ils doivent etre paralleles
1070     BRepExtrema_ExtCC myDeltaEdge (TopoDS::Edge(ShapeA) ,TopoDS::Edge(ShapeB)  );
1071     // on verifie qu'ils sont pas paralleles.
1072     if (!myDeltaEdge.IsParallel() ) {di<<"vequaldist error: non parallel edges."<<"\n";return 1; }
1073     
1074   }
1075   
1076   
1077   di<<" Select an edge or a vertex"<<"\n";
1078   // Boucle d'attente waitpick.
1079   Standard_Integer argc3 = 5;
1080   const char *buf3[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1081   const char **argv3 = (const char **) buf3;
1082   while (ViewerMainLoop( argc3, argv3) ) { }
1083   // fin de la boucle
1084   
1085   TopoDS_Shape ShapeC;
1086   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1087     ShapeC = TheAISContext()->SelectedShape();
1088   }
1089   
1090   di<<" Select an edge or a vertex"<<"\n";
1091   // Boucle d'attente waitpick.
1092   Standard_Integer argc4 = 5;
1093   const char *buf4[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1094   const char **argv4 = (const char **) buf4;
1095   while (ViewerMainLoop( argc4, argv4) ) { }
1096   // fin de la boucle
1097   
1098   TopoDS_Shape ShapeD;
1099   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1100     ShapeD = TheAISContext()->SelectedShape();
1101   }
1102   // Verification des resultats.
1103   if (ShapeC.ShapeType()==TopAbs_EDGE && ShapeD.ShapeType()==TopAbs_EDGE  ) {
1104     // C et D sont des edges ils doivent etre paralleles
1105     BRepExtrema_ExtCC myDeltaEdge2 (TopoDS::Edge(ShapeC) ,TopoDS::Edge(ShapeD)  );
1106     // on verifie qu'ils sont pas paralleles.
1107     if (!myDeltaEdge2.IsParallel() ) {di<<"vequaldist error: non parallel edges."<<"\n";return 1; }
1108     
1109   }
1110   
1111   // Creation du plan porteur de la contrainte.Methode lourde!
1112   gp_Pnt A,B,C;
1113   if (ShapeA.ShapeType()==TopAbs_EDGE) {
1114     // A est un edge
1115     TopoDS_Vertex Va,Vb;
1116     TopExp::Vertices (TopoDS::Edge(ShapeA) ,Va ,Vb );
1117     A=BRep_Tool::Pnt(Va);
1118     B=BRep_Tool::Pnt(Vb);
1119     
1120     if (ShapeB.ShapeType()==TopAbs_EDGE) {
1121       // B est un edge aussi
1122       TopoDS_Vertex Vc,Vd;
1123       TopExp::Vertices (TopoDS::Edge(ShapeB) ,Vc ,Vd );
1124       // besoin que de 1 point.
1125       C=BRep_Tool::Pnt(Vc);
1126       
1127     }
1128     else {
1129       // B est un vertex
1130       C=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
1131     }
1132   }
1133   else {
1134     // A est un vertex
1135     A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) );
1136     
1137     if (ShapeB.ShapeType()==TopAbs_EDGE ) {
1138       // B est un edge 
1139       TopoDS_Vertex Vb,Vc;
1140       TopExp::Vertices (TopoDS::Edge(ShapeB) ,Vb ,Vc );
1141       // besoin que de 2 points.
1142       B=BRep_Tool::Pnt(Vb);
1143       C=BRep_Tool::Pnt(Vc);
1144       
1145     }
1146     else {
1147       // B est un vertex
1148       B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
1149       C.SetX(B.X()+5.);
1150       C.SetY(B.Y()+5.);
1151       C.SetZ(B.Z()+5.);
1152       
1153     }
1154   }
1155   
1156   // Fermeture du context local.
1157   TheAISContext()->CloseLocalContext(myCurrentIndex);
1158   
1159   // construction du plane 
1160   GC_MakePlane MkPlane(A ,B ,C );
1161   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
1162   
1163   // Construction de l'AIS_EqualDistanceRelation
1164   Handle (AIS_EqualDistanceRelation ) myRelation= new AIS_EqualDistanceRelation (ShapeA, ShapeB, ShapeC ,ShapeD , theGeomPlane );
1165   TheAISContext()->Display(myRelation );
1166   GetMapOfAIS().Bind (myRelation,argv[1]);
1167   
1168
1169   
1170   return 0;
1171   
1172 }
1173
1174 //==============================================================================
1175 //function : VEqualRadiusRelation
1176 //purpose  : 
1177 //Draw arg : vdiameterdim Name DiameterValue
1178 //==============================================================================
1179 static int VEqualRadiusRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1180 {
1181   // Declarations
1182   Standard_Integer myCurrentIndex;
1183   
1184   // Verification
1185   if (argc!=2) {di<<" vequalrad error: no arguments allowed."<<"\n";return 1;}
1186   
1187   // Fermeture des contextes locaux
1188   TheAISContext()->CloseAllContexts();
1189   
1190   // Ouverture d'un contexte local et recuperation de son index.
1191   TheAISContext()->OpenLocalContext();
1192   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1193   
1194   // On active les modes de selections Edges.
1195   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
1196   di<<" Select an circled edge "<<"\n";
1197   
1198   // Boucle d'attente waitpick.
1199   Standard_Integer argc1 = 5;
1200   const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1201   const char **argv1 = (const char **) buf1;
1202   while (ViewerMainLoop( argc1, argv1) ) { }
1203   // fin de la boucle
1204   
1205   TopoDS_Shape ShapeA;
1206   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1207     ShapeA = TheAISContext()->SelectedShape();
1208   }
1209   
1210   di<<" Select the last circled edge."<<"\n";
1211   // Boucle d'attente waitpick.
1212   Standard_Integer argc2 = 5;
1213   const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1214   const char **argv2 = (const char **) buf2;
1215   while (ViewerMainLoop( argc2, argv2) ) { }
1216   // fin de la boucle
1217   
1218   TopoDS_Shape ShapeB;
1219   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1220     ShapeB = TheAISContext()->SelectedShape();
1221   }
1222   // creation du plan qui contient la contrainte.
1223   TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
1224   TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB);
1225   BRepAdaptor_Curve theCurveA(EdgeA);
1226   // On recupere 3 points A,B,C de la curve.
1227   gp_Pnt A=theCurveA.Value(0.1);
1228   gp_Pnt B=theCurveA.Value(0.5);
1229   gp_Pnt C=theCurveA.Value(0.9);
1230   
1231   // fermeture du contexte local.
1232   TheAISContext()->CloseLocalContext(myCurrentIndex);
1233   
1234   // Creation du plane.
1235   GC_MakePlane MkPlane (A ,B ,C );
1236   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
1237   // Construction de l'AIS_EqualRadiusRelation
1238   Handle (AIS_EqualRadiusRelation ) myRelation= new AIS_EqualRadiusRelation (EdgeA,EdgeB, theGeomPlane );
1239   TheAISContext()->Display(myRelation );
1240   GetMapOfAIS().Bind (myRelation,argv[1]);
1241   
1242   return 0;
1243   
1244 }
1245
1246
1247 //==============================================================================
1248 //function : VFixRelation
1249 //purpose  : 
1250 //Draw arg : vdiameterdim Name DiameterValue
1251 //==============================================================================
1252 static int VFixRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1253 {
1254   // Declarations
1255   Standard_Integer myCurrentIndex;
1256   
1257   // Verification
1258   if (argc!=2) {di<<" vfix  error: no arguments allowed."<<"\n";return 1;}
1259   
1260   // Fermeture des contextes locaux
1261   TheAISContext()->CloseAllContexts();
1262   
1263   // Ouverture d'un contexte local et recuperation de son index.
1264   TheAISContext()->OpenLocalContext();
1265   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1266   
1267   // On active les modes de selections edge.
1268   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
1269   di<<" Select an edge. "<<"\n";
1270   
1271   // Boucle d'attente waitpick.
1272   Standard_Integer argc1 = 5;
1273   const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1274   const char **argv1 = (const char **) buf1;
1275   while (ViewerMainLoop( argc1, argv1) ) { }
1276   // fin de la boucle
1277   
1278   TopoDS_Shape ShapeA;
1279   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1280     ShapeA = TheAISContext()->SelectedShape();
1281   }
1282   
1283   // creation du plan qui contient la contrainte.
1284   TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
1285   BRepAdaptor_Curve theCurveA(EdgeA);
1286   // On recupere 3 points A,B,C de la curve.
1287   gp_Pnt A=theCurveA.Value(0.1);
1288   gp_Pnt B=theCurveA.Value(0.5);
1289   gp_Pnt D=theCurveA.Value(0.9);
1290   gp_Pnt C(B.X()+5,B.Y()+5,B.Z()+5);
1291   
1292   // fermeture du contexte local.
1293   TheAISContext()->CloseLocalContext(myCurrentIndex);
1294   
1295   // Creation du plane.
1296   GC_MakePlane MkPlane (A ,D ,C );
1297   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
1298   // Construction de l'AIS_EqualRadiusRelation
1299   Handle (AIS_FixRelation) myRelation= new AIS_FixRelation (EdgeA,theGeomPlane );
1300   TheAISContext()->Display(myRelation );
1301   GetMapOfAIS().Bind (myRelation,argv[1]);
1302   
1303   
1304   return 0;
1305   
1306 }
1307
1308 //==============================================================================
1309 //function : VIdenticRelation
1310 //purpose  : 
1311 //Draw arg : vdiameterdim Name DiameterValue
1312 //==============================================================================
1313 static int VIdenticRelation(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1314 {
1315   // Declarations
1316   Standard_Integer myCurrentIndex;
1317   
1318   // Verification
1319   if (argc!=2) {di<<" videntity error: no arguments allowed."<<"\n";return 1;}
1320   
1321   // Fermeture des contextes locaux
1322   TheAISContext()->CloseAllContexts();
1323   
1324   // Ouverture d'un contexte local et recuperation de son index.
1325   TheAISContext()->OpenLocalContext();
1326   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1327   
1328   // On active les modes de selections  vertex et face.
1329   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
1330   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
1331   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
1332   di<<" Select an edge, a face or a vertex. "<<"\n";
1333   
1334   // Boucle d'attente waitpick.
1335   Standard_Integer argc1 = 5;
1336   const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1337   const char **argv1 = (const char **) buf1;
1338   while (ViewerMainLoop( argc1, argv1) ) { }
1339   // fin de la boucle
1340   
1341   TopoDS_Shape ShapeA;
1342   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1343     ShapeA = TheAISContext()->SelectedShape();
1344   }
1345   
1346   di<<" Select an edge, a face or a vertex. "<<"\n";
1347   // Boucle d'attente waitpick.
1348   Standard_Integer argc2 = 5;
1349   const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1350   const char **argv2 = (const char **) buf2;
1351   while (ViewerMainLoop( argc2, argv2) ) { }
1352   // fin de la boucle
1353   
1354   TopoDS_Shape ShapeB;
1355   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1356     ShapeB = TheAISContext()->SelectedShape();
1357   }
1358   
1359   // Recuperation de points pour construir le Geom_Plnae.
1360   gp_Pnt A,B,C;
1361   if (ShapeA.ShapeType()==TopAbs_EDGE) {
1362     // A est un edge; on peut supposer qu'il sera element d'une face ou possesseur d'un vertex ou identic a un autre edge.
1363     // on recupere deux points sur l'edge (il peut etre rectiligne)
1364     TopoDS_Edge EdgeA=TopoDS::Edge(ShapeA);
1365     BRepAdaptor_Curve theCurveA(EdgeA);
1366     // Creation des 3 points.
1367     A=theCurveA.Value(0.1);
1368     B=theCurveA.Value(0.9);
1369     C.SetX(B.X()+5.);
1370     C.SetY(B.Y()+5.);
1371     C.SetZ(B.Z()+5.);
1372   }
1373   else if (ShapeA.ShapeType()==TopAbs_VERTEX ) {
1374     // SahpeA est un Vertex
1375     // On va utiliser ShapeB
1376     if (ShapeB.ShapeType()==TopAbs_EDGE) {
1377       // B est un edge 
1378       TopoDS_Edge EdgeB=TopoDS::Edge(ShapeB);
1379       BRepAdaptor_Curve theCurveB(EdgeB);
1380       // Creation des 3 points.
1381       A=theCurveB.Value(0.1);
1382       B=theCurveB.Value(0.9);
1383       C.SetX(B.X()+5.);
1384       C.SetY(B.Y()+5.);
1385       C.SetZ(B.Z()+5.);
1386       
1387     }
1388     else if (ShapeB.ShapeType()==TopAbs_FACE ) {
1389       // Shape B est une face
1390       TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
1391       // On recupere 1 edge de FaceB(la face n'a pas forcement de vertex) (l'element A est forcement dans B).
1392       TopExp_Explorer FaceExp(FaceB,TopAbs_EDGE);
1393       TopoDS_Edge EdgeFromB=TopoDS::Edge(FaceExp.Current() );
1394       // On recupere les 3 points de l'edge de face B
1395       BRepAdaptor_Curve theCurveB(EdgeFromB);
1396       // On recupere 3 points A,B,C de la curve.
1397       A=theCurveB.Value(0.1);
1398       B=theCurveB.Value(0.5);
1399       C=theCurveB.Value(0.9);
1400       
1401     }
1402     else {
1403       // B ets un vetex aussi
1404       A=BRep_Tool::Pnt(TopoDS::Vertex(ShapeA) );
1405       B=BRep_Tool::Pnt(TopoDS::Vertex(ShapeB) );
1406       C.SetX(B.X()+5.);
1407       C.SetY(B.Y()+5.);
1408       C.SetZ(B.Z()+5.);
1409       
1410     }
1411     
1412   }
1413   else {
1414     // A est une face.
1415     TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
1416     // On recupere 1 edge de FaceA
1417     TopExp_Explorer FaceExp(FaceA,TopAbs_EDGE);
1418     TopoDS_Edge EdgeFromA=TopoDS::Edge(FaceExp.Current() );
1419     // On recupere les 3 points de l'edge
1420     BRepAdaptor_Curve theCurveA(EdgeFromA);
1421     // On recupere 3 points A,B,C de la curve.
1422     A=theCurveA.Value(0.1);
1423     B=theCurveA.Value(0.5);
1424     C=theCurveA.Value(0.9);
1425     
1426   }
1427   
1428   // Fermeture du context local.
1429   TheAISContext()->CloseLocalContext(myCurrentIndex);
1430   // On construit le plane 
1431   GC_MakePlane MkPlane (A ,B ,C );
1432   Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
1433   
1434   // Construction de l'AIS_IdenticRelation
1435   Handle ( AIS_IdenticRelation ) myRelation= new AIS_IdenticRelation  (ShapeA ,ShapeB, theGeomPlane );
1436   TheAISContext()->Display(myRelation );
1437   GetMapOfAIS().Bind (myRelation,argv[1]);
1438   
1439
1440   
1441   return 0;
1442   
1443 }
1444 //==============================================================================
1445 //function : VLengthDimension
1446 //purpose  : Display the diameter dimension of a face or an edge.
1447 //Draw arg : vdiameterdim Name DiameterValue
1448 //==============================================================================
1449 static int VLenghtDimension(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1450 {
1451   // Declarations
1452   Standard_Integer aCurrentIndex;
1453   // Verification
1454   if (argc != 2)
1455   {
1456     di << argv[0] << " error: wrong number of arguments.\n";
1457     return 1;
1458   }
1459
1460   // Close all local contexts
1461   TheAISContext()->CloseAllContexts();
1462
1463   // Open local context
1464   aCurrentIndex = TheAISContext()->OpenLocalContext();
1465   // Activate 'edge', 'face' and 'vertex' selection modes.
1466   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1467   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1));
1468   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1469
1470   // First shape picking
1471   di << " Select an edge, a face or a vertex. " << "\n";
1472   // Loop that will handle the picking.
1473   Standard_Integer argc1 = 5;
1474   const char *buf1[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1475   const char **argv1 = (const char **) buf1;
1476   while (ViewerMainLoop( argc1, argv1) ) { }
1477   // end of the loop.
1478
1479   TopoDS_Shape aFirstShape;
1480   for(TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
1481   {
1482     aFirstShape = TheAISContext()->SelectedShape();
1483   }
1484
1485   if (aFirstShape.IsNull())
1486   {
1487     di << argv[0] << "error: no first picked shape.\n";
1488     return 1;
1489   }
1490
1491   // Second shape picking
1492   di << " Select an edge, a face or a vertex. " << "\n";
1493   // Loop that will handle the picking.
1494   Standard_Integer argc2 = 5;
1495   const char *buf2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1496   const char **argv2 = (const char **) buf2;
1497   while (ViewerMainLoop( argc2, argv2) ) { }
1498
1499   TopoDS_Shape aSecondShape;
1500   for(TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
1501   {
1502     aSecondShape = TheAISContext()->SelectedShape();
1503   }
1504
1505   if (aSecondShape.IsNull())
1506   {
1507     di << argv[0] << "error: no second picked shape.\n";
1508     return 1;
1509   }
1510
1511   if (aFirstShape.ShapeType() == TopAbs_EDGE)
1512   {
1513     TopoDS_Edge EdgeA = TopoDS::Edge (aFirstShape);
1514
1515     if (aSecondShape.ShapeType() == TopAbs_EDGE)
1516     {
1517       TopoDS_Edge EdgeB = TopoDS::Edge (aSecondShape);
1518       BRepExtrema_ExtCC myDeltaEdge (EdgeA ,EdgeB);
1519
1520       if (!myDeltaEdge.IsParallel())
1521       {
1522         di << argv[0] << " error: non parallel edges." << "\n";
1523         return 1;
1524       }
1525
1526       // 3 points of edges is recovered to build a plane
1527       TopoDS_Vertex aVertex1, aVertex2, aVertex3, aVertex4;
1528       TopExp::Vertices (EdgeA, aVertex1, aVertex2);
1529       TopExp::Vertices (EdgeB, aVertex3, aVertex4);
1530       gp_Pnt A = BRep_Tool::Pnt (aVertex1);
1531       gp_Pnt B = BRep_Tool::Pnt (aVertex2);
1532       gp_Pnt C = BRep_Tool::Pnt (aVertex3);
1533
1534       gce_MakePln aMakePlane (A,B,C);
1535       gp_Pln aPlane= aMakePlane.Value();
1536
1537       // Close local context
1538       TheAISContext()->CloseLocalContext (aCurrentIndex);
1539
1540       // Construct the dimension
1541       Handle(AIS_LengthDimension ) aLenghtDim = new AIS_LengthDimension (EdgeA, EdgeB, aPlane);
1542       TheAISContext()->Display (aLenghtDim);
1543       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1544     }
1545
1546     else if (aSecondShape.ShapeType() == TopAbs_VERTEX)
1547     {
1548       TopoDS_Vertex aVertex = TopoDS::Vertex (aSecondShape);
1549       BRepExtrema_ExtPC myDeltaEdgeVertex  (aVertex ,EdgeA);
1550
1551       TopoDS_Vertex aVertex1, aVertex2;
1552       TopExp::Vertices (EdgeA, aVertex1, aVertex2);
1553       gp_Pnt A=BRep_Tool::Pnt (aVertex1);
1554       gp_Pnt B=BRep_Tool::Pnt (aVertex2);
1555       gp_Pnt C=BRep_Tool::Pnt (aVertex);
1556
1557       gce_MakePln aMakePlane (A,B,C);
1558       gp_Pln aPlane= aMakePlane.Value();
1559
1560       TheAISContext()->CloseLocalContext (aCurrentIndex);
1561       Handle(AIS_LengthDimension) aLenghtDim=new AIS_LengthDimension (EdgeA, aVertex, aPlane);
1562       TheAISContext()->Display (aLenghtDim);
1563       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1564     }
1565
1566     // Second shape is a face
1567     else
1568     {
1569       TopoDS_Face FaceB = TopoDS::Face (aSecondShape);
1570       BRepExtrema_ExtCF aDeltaEdgeFace (EdgeA,FaceB);
1571
1572       if (!aDeltaEdgeFace.IsParallel())
1573       {
1574         di << argv[0] << "error: the edge isn't parallel to the face;can't compute the distance." << "\n";
1575         return 1;
1576       }
1577
1578       Handle(AIS_LengthDimension) aLenghtDim = new AIS_LengthDimension (FaceB, EdgeA);
1579       TheAISContext()->Display (aLenghtDim);
1580       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1581     }
1582   }
1583   else if (aFirstShape.ShapeType() == TopAbs_VERTEX)
1584   {
1585     TopoDS_Vertex  VertexA = TopoDS::Vertex (aFirstShape);
1586     if (aSecondShape.ShapeType() == TopAbs_EDGE )
1587     {
1588       TopoDS_Edge  EdgeB=TopoDS::Edge (aSecondShape);
1589       BRepExtrema_ExtPC aDeltaEdgeVertex (VertexA, EdgeB);
1590
1591       TopoDS_Vertex aVertex1, aVertex2;
1592       TopExp::Vertices(EdgeB, aVertex1, aVertex2);
1593       gp_Pnt A = BRep_Tool::Pnt (aVertex1);
1594       gp_Pnt B = BRep_Tool::Pnt (aVertex2);
1595       gp_Pnt C = BRep_Tool::Pnt (VertexA);
1596
1597       gce_MakePln aMakePlane (A,B,C);
1598       gp_Pln aPlane = aMakePlane.Value();
1599
1600       // Close local contex by its index.
1601       TheAISContext()->CloseLocalContext (aCurrentIndex);
1602
1603       // Construct the dimension.
1604       Handle(AIS_LengthDimension) aLenghtDim = new AIS_LengthDimension (EdgeB,VertexA, aPlane);
1605       TheAISContext()->Display (aLenghtDim);
1606       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1607     }
1608
1609     else if (aSecondShape.ShapeType() == TopAbs_VERTEX)
1610     {
1611       TopoDS_Vertex  VertexB = TopoDS::Vertex (aSecondShape);
1612
1613       gp_Pnt A = BRep_Tool::Pnt (VertexA);
1614       gp_Pnt B = BRep_Tool::Pnt (VertexB);
1615       gp_Pnt C(B.X() + 10.0, B.Y() + 10.0, B.Z() + 10.0);
1616
1617       gce_MakePln aMakePlane (A,B,C);
1618       gp_Pln aPlane= aMakePlane.Value();
1619
1620       TheAISContext()->CloseLocalContext (aCurrentIndex);
1621
1622       Handle(AIS_LengthDimension ) aLenghtDim = new AIS_LengthDimension (VertexA, VertexB, aPlane);
1623       TheAISContext()->Display (aLenghtDim);
1624       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1625     }
1626     // The second shape is face
1627     else
1628     {
1629       TopoDS_Face  FaceB = TopoDS::Face (aSecondShape);
1630
1631       BRepExtrema_ExtPF aDeltaVertexFace (VertexA, FaceB);
1632
1633       gp_Pnt A = BRep_Tool::Pnt (VertexA);
1634
1635       // Recover edge from face.
1636       TopExp_Explorer aFaceExp (FaceB,TopAbs_EDGE);
1637       TopoDS_Edge aSecondEdge = TopoDS::Edge (aFaceExp.Current());
1638
1639       TopoDS_Vertex aVertex1, aVertex2;
1640       TopExp::Vertices (aSecondEdge, aVertex1, aVertex2);
1641       gp_Pnt C = BRep_Tool::Pnt (aVertex2);
1642
1643       gp_Pnt aProjA = aDeltaVertexFace.Point(1);
1644       BRepBuilderAPI_MakeVertex aVertexMaker (aProjA);
1645       TopoDS_Vertex aVertexAProj = aVertexMaker.Vertex();
1646
1647       // Create working plane for the dimension.
1648       gce_MakePln aMakePlane (A, aProjA, C);
1649       gp_Pln aPlane = aMakePlane.Value();
1650
1651       TheAISContext()->CloseLocalContext (aCurrentIndex);
1652
1653       // Construct the dimension.
1654       Handle(AIS_LengthDimension ) aLenghtDim = new AIS_LengthDimension (VertexA, aVertexAProj, aPlane);
1655       TheAISContext()->Display (aLenghtDim);
1656       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1657     }
1658   }
1659
1660   // The first shape is a face.
1661   else
1662   {
1663     TopoDS_Face FaceA = TopoDS::Face (aFirstShape);
1664
1665     if (aSecondShape.ShapeType() == TopAbs_EDGE)
1666     {
1667       TopoDS_Edge EdgeB = TopoDS::Edge (aSecondShape);
1668       BRepExtrema_ExtCF aDeltaEdgeFace (EdgeB,FaceA );
1669
1670       if (!aDeltaEdgeFace.IsParallel())
1671       {
1672         di << argv[0] << " error: the edge isn't parallel to the face;can't compute the distance. " << "\n";
1673         return 1;
1674       }
1675
1676       Handle(AIS_LengthDimension) aLenghtDim = new AIS_LengthDimension (FaceA, EdgeB);
1677       TheAISContext()->Display (aLenghtDim);
1678       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1679     }
1680
1681     else if (aSecondShape.ShapeType() == TopAbs_VERTEX)
1682     {
1683       TopoDS_Vertex  VertexB = TopoDS::Vertex (aSecondShape);
1684       BRepExtrema_ExtPF aDeltaVertexFace (VertexB, FaceA);
1685
1686       gp_Pnt B = BRep_Tool::Pnt (VertexB);
1687
1688       TopExp_Explorer aFaceExp (FaceA, TopAbs_EDGE);
1689       TopoDS_Edge anEdgeFromA = TopoDS::Edge (aFaceExp.Current());
1690       TopoDS_Vertex  aVertex1, aVertex2;
1691       TopExp::Vertices(anEdgeFromA, aVertex1, aVertex2);
1692       gp_Pnt A=BRep_Tool::Pnt(aVertex1);
1693
1694 #ifdef OCCT_DEBUG
1695       gp_Pnt C = BRep_Tool::Pnt(aVertex2); (void)C;
1696 #endif
1697
1698       gp_Pnt aProjB = aDeltaVertexFace.Point(1);
1699       BRepBuilderAPI_MakeVertex aVertexMaker (aProjB);
1700       TopoDS_Vertex aVertexBProj = aVertexMaker.Vertex();
1701       gce_MakePln aMakePlane (A, B, aProjB);
1702       gp_Pln aPlane= aMakePlane.Value();
1703
1704       TheAISContext()->CloseLocalContext(aCurrentIndex);
1705
1706       Handle(AIS_LengthDimension) aLenghtDim  =new AIS_LengthDimension (VertexB, aVertexBProj, aPlane);
1707       TheAISContext()->Display (aLenghtDim);
1708       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1709     }
1710     // the second shape is face.
1711     else
1712     {
1713       TopoDS_Face FaceB = TopoDS::Face (aSecondShape);
1714       BRepExtrema_ExtFF aDeltaFaceFace (FaceA, FaceB);
1715
1716       if (!aDeltaFaceFace.IsParallel())
1717       {
1718         di << argv[0] << " error: the faces are not parallel. "<<"\n";
1719         return 1;
1720       }
1721
1722       TheAISContext()->CloseLocalContext (aCurrentIndex);
1723
1724       Handle(AIS_LengthDimension) aLenghtDim = new AIS_LengthDimension (FaceA,FaceB);
1725       TheAISContext()->Display (aLenghtDim);
1726       GetMapOfAIS().Bind (aLenghtDim, argv[1]);
1727     }
1728   }
1729
1730   return 0;
1731 }
1732
1733
1734 //==============================================================================
1735 //function : VRadiusDim
1736 //purpose  : Display the radius dimension of a face or an edge.
1737 //Draw arg : vradiusdim Name 
1738 //==============================================================================
1739 static int VRadiusDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1740 {
1741   // Declarations
1742   Standard_Integer aCurrentIndex;
1743   TopoDS_Edge anEdge;
1744   // Verification
1745   if (argc != 2)
1746   {
1747     di << argv[0] << " error: wrong number of parameters." << "\n";
1748     return 1;
1749   }
1750
1751   // Close all local contexts
1752   TheAISContext()->CloseAllContexts();
1753
1754   // Open local context and get its index for recovery.
1755   TheAISContext()->OpenLocalContext();
1756   aCurrentIndex = TheAISContext()->IndexOfCurrentLocal();
1757
1758   // Current selection modes - faces and edges
1759   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2));
1760   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4));
1761   di << " Select a circled edge or face." << "\n";
1762
1763   // Loop that will be handle picking.
1764   Standard_Integer argcc = 5;
1765   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1766   const char **argvv = (const char **) buff;
1767   while (ViewerMainLoop (argcc, argvv)) { }
1768   // end of the loop
1769
1770   TopoDS_Shape aShape;
1771
1772   for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected() )
1773   {
1774     aShape = TheAISContext()->SelectedShape();
1775   }
1776
1777   if (aShape.IsNull())
1778   {
1779     di << argv[0] << ": no shape is selected." << "\n";
1780     return 1;
1781   }
1782
1783   if (aShape.ShapeType() != TopAbs_EDGE && aShape.ShapeType() != TopAbs_FACE)
1784   {
1785     di << argv[0] << " error: the selection of a face or an edge was expected." << "\n";
1786     return 1;
1787   }
1788
1789   if (aShape.ShapeType() == TopAbs_EDGE)
1790   {
1791     anEdge = TopoDS::Edge (aShape);
1792   }
1793   else // Face
1794   {
1795     // Recover an edge of the face.
1796     TopoDS_Face aFace = TopoDS::Face (aShape);
1797
1798     TopExp_Explorer aFaceExp (aFace,TopAbs_EDGE);
1799     anEdge = TopoDS::Edge (aFaceExp.Current());
1800   }
1801
1802   // Compute the radius
1803   BRepAdaptor_Curve aCurve (anEdge);
1804   if (aCurve.GetType() != GeomAbs_Circle)
1805   {
1806     di << argv[0] << " error: the edge is not a circular one." << "\n";
1807     return 1;
1808   }
1809   // Close the context
1810   TheAISContext()->CloseLocalContext (aCurrentIndex);
1811
1812   // Construct radius dimension
1813   Handle (AIS_RadiusDimension) aRadDim= new AIS_RadiusDimension (aShape);
1814   VDisplayAISObject (argv[1], aRadDim);
1815
1816   return 0;
1817 }
1818
1819
1820
1821 //==============================================================================
1822 //function : VOffsetDim
1823 //purpose  : Display the offset dimension
1824 //Draw arg : voffsetdim Name 
1825 //==============================================================================
1826 static int VOffsetDimBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1827 {
1828   // Declarations
1829   Standard_Integer myCurrentIndex;
1830   Standard_Real    theDist;
1831   
1832   // Verification
1833   if (argc!=2) {di<<" voffsetdim error"<<"\n";return 1;}
1834   
1835   // Fermeture des contextes locaux
1836   TheAISContext()->CloseAllContexts();
1837   
1838   // Ouverture d'un contexte local et recuperation de son index.
1839   TheAISContext()->OpenLocalContext();
1840   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1841   
1842   // On active les modes de selections Faces.
1843   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
1844   di<<" Select a face."<<"\n";
1845   
1846   // Boucle d'attente waitpick.
1847   Standard_Integer argcc = 5;
1848   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1849   const char **argvv = (const char **) buff;
1850   while (ViewerMainLoop( argcc, argvv) ) { }
1851   // fin de la boucle
1852   
1853   TopoDS_Shape ShapeA;
1854   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1855     ShapeA = TheAISContext()->SelectedShape();
1856   }
1857   
1858   di<<" Select a face."<<"\n";
1859   // Boucle d'attente waitpick.
1860   Standard_Integer argccc = 5;
1861   const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1862   const char **argvvv = (const char **) bufff;
1863   while (ViewerMainLoop( argccc, argvvv) ) { }
1864   // fin de la boucle
1865   
1866   TopoDS_Shape ShapeB;
1867   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1868     ShapeB = TheAISContext()->SelectedShape();
1869   }
1870   
1871   
1872   // Shape A et B est une face
1873   if (ShapeA.ShapeType()==TopAbs_FACE && ShapeB.ShapeType()==TopAbs_FACE ) {
1874     
1875     TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
1876     TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
1877     
1878     BRepExtrema_ExtFF myDeltaFaceFace  (FaceA ,FaceB );
1879     // On verifie que les deux faces sont bien parelles.
1880     if (!myDeltaFaceFace.IsParallel() ) {di<<"vdistdim error: the faces are not parallel. "<<"\n";return 1; }
1881     
1882     // On saisit la distance et on l'arrondit!
1883     theDist=Round (sqrt (myDeltaFaceFace.SquareDistance(1))*10. )/10.;
1884     // Fermeture du contexte local.
1885     TheAISContext()->CloseLocalContext(myCurrentIndex);
1886     // Construction du texte.
1887     TCollection_ExtendedString TheMessage_Str(TCollection_ExtendedString("offset=")+TCollection_ExtendedString(theDist ) );
1888     
1889     // on construit l'AIS_OffsetDimension
1890     Handle(AIS_OffsetDimension) myOffsetDim=new AIS_OffsetDimension (FaceA,FaceB,theDist,TheMessage_Str );
1891     TheAISContext()->Display(myOffsetDim );
1892     GetMapOfAIS().Bind (myOffsetDim ,argv[1]);
1893     
1894     
1895     
1896   }
1897   
1898   else {
1899     di<<" voffsetdim error: the selection of a face was expected."<<"\n";return 1;
1900   }
1901   
1902   return 0;
1903   
1904 }
1905
1906
1907
1908
1909 //==============================================================================
1910 //function : VParallel
1911 //purpose  : Display the parallel relation 
1912 //Draw arg : vparallel Name 
1913 //==============================================================================
1914 static int VParallelBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
1915 {
1916   // Declarations
1917   Standard_Integer myCurrentIndex;
1918  
1919   // Verification
1920   if (argc!=2) {di<<" vparallel error"<<"\n";return 1;}
1921   
1922   // Fermeture des contextes locaux
1923   TheAISContext()->CloseAllContexts();
1924   
1925   // Ouverture d'un contexte local et recuperation de son index.
1926   TheAISContext()->OpenLocalContext();
1927   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
1928   
1929   // On active les modes de selections Edges.
1930   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
1931   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
1932   di<<" Select an edge or a face "<<"\n";
1933   
1934   // Boucle d'attente waitpick.
1935   Standard_Integer argcc = 5;
1936   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1937   const char **argvv = (const char **) buff;
1938   while (ViewerMainLoop( argcc, argvv) ) { }
1939   // fin de la boucle
1940   
1941   TopoDS_Shape ShapeA;
1942   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1943     ShapeA = TheAISContext()->SelectedShape();
1944   }
1945   
1946   // SahpeA est un edge.
1947   // ===================
1948   if (ShapeA.ShapeType()==TopAbs_EDGE ) {
1949     
1950     // desactivation du mode face
1951     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
1952     di<<" Select a second edge"<<"\n";
1953     // Boucle d'attente waitpick.
1954     Standard_Integer argccc = 5;
1955     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1956     const char **argvvv = (const char **) bufff;
1957     while (ViewerMainLoop( argccc, argvvv) ) { }
1958     // fin de la boucle
1959     
1960     TopoDS_Shape ShapeB;
1961     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
1962       ShapeB = TheAISContext()->SelectedShape();
1963     }
1964     
1965     // recuperation des edges.
1966     TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
1967     TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
1968     BRepExtrema_ExtCC myDeltaEdge (EdgeA ,EdgeB );
1969     // on verifie qu'ils ne sont pas paralleles.
1970     if (!myDeltaEdge.IsParallel() ) {di<<"vparallel error: non parallel edges."<<"\n";return 1; }
1971     
1972     
1973     // On recupere les  vertexes extremites des edge A et B.
1974     BRepAdaptor_Curve theCurveA(EdgeA);
1975     BRepAdaptor_Curve theCurveB(EdgeB);
1976     // On recupere 3 points A,B,C des  curves.
1977     gp_Pnt A=theCurveA.Value(0.1);
1978     gp_Pnt B=theCurveA.Value(0.9);
1979     gp_Pnt C=theCurveB.Value(0.5);
1980     
1981     // Construction du Geom_Plane
1982     GC_MakePlane MkPlane(A,B,C);
1983     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
1984     // Fermeture du contexte local.
1985     TheAISContext()->CloseLocalContext(myCurrentIndex);
1986     // Construction de l'AIS_ParallelRelation
1987     Handle(AIS_ParallelRelation) myParaRelation= new AIS_ParallelRelation(EdgeA ,EdgeB ,theGeomPlane );
1988     TheAISContext()->Display(myParaRelation );
1989     GetMapOfAIS().Bind (myParaRelation ,argv[1]);
1990     
1991     
1992   }
1993   
1994   // Shape A est une face
1995   // ====================
1996   else {
1997     
1998     // desactivation du mode edge
1999     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
2000     di<<" Select a second edge"<<"\n";
2001     // Boucle d'attente waitpick.
2002     Standard_Integer argccc = 5;
2003     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2004     const char **argvvv = (const char **) bufff;
2005     while (ViewerMainLoop( argccc, argvvv) ) { }
2006     // fin de la boucle
2007     
2008     TopoDS_Shape ShapeB;
2009     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2010       ShapeB = TheAISContext()->SelectedShape();
2011     }
2012     
2013     TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
2014     TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
2015     
2016     BRepExtrema_ExtFF myDeltaFaceFace  (FaceA ,FaceB );
2017     // On verifie que les deux faces sont bien parelles.
2018     if (!myDeltaFaceFace.IsParallel() ) {di<<"vdistdim error: the faces are not parallel. "<<"\n";return 1; }
2019     
2020     // recuperation des edges des faces.
2021     TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
2022     TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
2023     
2024     TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
2025     TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
2026     
2027     // On recupere les  vertexes extremites des edge A et B.
2028     BRepAdaptor_Curve theCurveA(EdgeA);
2029     BRepAdaptor_Curve theCurveB(EdgeB);
2030     // On recupere 3 points A,B,C des  curves.
2031     gp_Pnt A=theCurveA.Value(0.1);
2032     gp_Pnt B=theCurveA.Value(0.9);
2033     gp_Pnt C=theCurveB.Value(0.5);
2034     
2035     // Construction du Geom_Plane
2036     GC_MakePlane MkPlane(A,B,C);
2037     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2038     // Fermeture du contexte local.
2039     TheAISContext()->CloseLocalContext(myCurrentIndex);
2040     // Construction de l'AIS_ParallelRelation
2041     Handle(AIS_ParallelRelation) myParaRelation= new AIS_ParallelRelation(FaceA ,FaceB ,theGeomPlane );
2042     TheAISContext()->Display(myParaRelation );
2043     GetMapOfAIS().Bind (myParaRelation ,argv[1]);
2044     
2045     
2046     
2047   }
2048   
2049   
2050   return 0;
2051   
2052 }
2053
2054
2055
2056
2057 //==============================================================================
2058 //function : VPerpendicularRelation
2059 //purpose  : Display the Perpendicular Relation
2060 //Draw arg : vperpendicular Name 
2061 //==============================================================================
2062 static int VPerpendicularBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
2063 {
2064   // Declarations
2065   Standard_Integer myCurrentIndex;
2066  
2067   // Verification
2068   if (argc!=2) {di<<" vortho error"<<"\n";return 1;}
2069   
2070   // Fermeture des contextes locaux
2071   TheAISContext()->CloseAllContexts();
2072   
2073   // Ouverture d'un contexte local et recuperation de son index.
2074   TheAISContext()->OpenLocalContext();
2075   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
2076   
2077   // On active les modes de selections Edges.
2078   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
2079   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2080   di<<" Select an edge or a face "<<"\n";
2081   
2082   // Boucle d'attente waitpick.
2083   Standard_Integer argcc = 5;
2084   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2085   const char **argvv = (const char **) buff;
2086   while (ViewerMainLoop( argcc, argvv) ) { }
2087   // fin de la boucle
2088   
2089   TopoDS_Shape ShapeA;
2090   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2091     ShapeA = TheAISContext()->SelectedShape();
2092   }
2093   
2094   // ShapeA est un edge.
2095   // ===================
2096   if (ShapeA.ShapeType()==TopAbs_EDGE ) {
2097     
2098     // desactivation du mode face
2099     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2100     di<<" Select a second edge"<<"\n";
2101     // Boucle d'attente waitpick.
2102     Standard_Integer argccc = 5;
2103     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2104     const char **argvvv = (const char **) bufff;
2105     while (ViewerMainLoop( argccc, argvvv) ) { }
2106     // fin de la boucle
2107     
2108     TopoDS_Shape ShapeB;
2109     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2110       ShapeB = TheAISContext()->SelectedShape();
2111     }
2112     
2113     // recuperation des edges.
2114     TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
2115     TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
2116     
2117     // On recupere les  curves
2118     BRepAdaptor_Curve theCurveA(EdgeA);
2119     BRepAdaptor_Curve theCurveB(EdgeB);
2120     // on verifie si les edges sont orthogonaux.
2121     //gp_Lin theLineA=theCurveA.Line();
2122     //gp_Lin theLineB=theCurveB.Line();
2123     //if (abs(theLineA.Angle(theLineB) ) != M_PI/2 ) {cout<<"vperpendicular error: Edges are not  othogonals."<<endl;return 1;}
2124     
2125     // On recupere 3 points A,B,C des  curves.
2126     gp_Pnt A=theCurveA.Value(0.1);
2127     gp_Pnt B=theCurveA.Value(0.9);
2128     gp_Pnt C=theCurveB.Value(0.5);
2129     // Construction du Geom_Plane
2130     GC_MakePlane MkPlane(A,B,C);
2131     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2132     // Fermeture du contexte local.
2133     TheAISContext()->CloseLocalContext(myCurrentIndex);
2134     // Construction de l'AIS_ParallelRelation
2135     Handle(AIS_PerpendicularRelation) myOrthoRelation= new AIS_PerpendicularRelation (EdgeA ,EdgeB ,theGeomPlane );
2136     TheAISContext()->Display(myOrthoRelation );
2137     GetMapOfAIS().Bind (myOrthoRelation ,argv[1]);
2138     
2139     
2140   }
2141   
2142   // Shape A est une face
2143   // ====================
2144   else {
2145     
2146     // desactivation du mode edge
2147     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
2148     di<<" Select a second edge"<<"\n";
2149     // Boucle d'attente waitpick.
2150     Standard_Integer argccc = 5;
2151     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2152     const char **argvvv = (const char **) bufff;
2153     while (ViewerMainLoop( argccc, argvvv) ) { }
2154     // fin de la boucle
2155     
2156     TopoDS_Shape ShapeB;
2157     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2158       ShapeB = TheAISContext()->SelectedShape();
2159     }
2160     
2161     // pas de verification d'orthogonalite.
2162     TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
2163     TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
2164     
2165     // recuperation des edges des faces.
2166     TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
2167     TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
2168     
2169     TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
2170     TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
2171     
2172     // On recupere les  vertexes extremites des edge A et B.
2173     BRepAdaptor_Curve theCurveA(EdgeA);
2174     BRepAdaptor_Curve theCurveB(EdgeB);
2175     // On recupere 3 points A,B,C des  curves.
2176     gp_Pnt A=theCurveA.Value(0.1);
2177     gp_Pnt B=theCurveA.Value(0.9);
2178     gp_Pnt C=theCurveB.Value(0.5);
2179     // Construction du Geom_Plane
2180     GC_MakePlane MkPlane(A,B,C);
2181     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2182     // Fermeture du contexte local.
2183     TheAISContext()->CloseLocalContext(myCurrentIndex);
2184     // Construction de l'AIS_PerpendicularRelation
2185     Handle(AIS_PerpendicularRelation) myOrthoRelation= new AIS_PerpendicularRelation(FaceA ,FaceB );
2186     TheAISContext()->Display(myOrthoRelation );
2187     GetMapOfAIS().Bind (myOrthoRelation  ,argv[1]);
2188     
2189     
2190     
2191   }
2192   
2193   
2194   return 0;
2195   
2196 }
2197
2198
2199 //==============================================================================
2200 //function : VTangentRelation
2201 //purpose  : Display the tangent Relation
2202 //Draw arg : vtangent Name 
2203 //==============================================================================
2204 static int VTangentBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
2205 {
2206   // Declarations
2207   Standard_Integer myCurrentIndex;
2208  
2209   // Verification
2210   if (argc!=2) {di<<" vtangent error"<<"\n";return 1;}
2211   
2212   // Fermeture des contextes locaux
2213   TheAISContext()->CloseAllContexts();
2214   
2215   // Ouverture d'un contexte local et recuperation de son index.
2216   TheAISContext()->OpenLocalContext();
2217   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
2218   
2219   // On active les modes de selections Edges.
2220   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
2221   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(4) );
2222   di<<" Select two coplanar edges(First the circular edge then the tangent edge) or two faces "<<"\n";
2223   
2224   // Boucle d'attente waitpick.
2225   Standard_Integer argcc = 5;
2226   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2227   const char **argvv = (const char **) buff;
2228   while (ViewerMainLoop( argcc, argvv) ) { }
2229   // fin de la boucle
2230   
2231   TopoDS_Shape ShapeA;
2232   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2233     ShapeA = TheAISContext()->SelectedShape();
2234   }
2235   
2236   // ShapeA est un edge.
2237   // ===================
2238   if (ShapeA.ShapeType()==TopAbs_EDGE ) {
2239     
2240     // desactivation du mode face
2241     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(4) );
2242     di<<" Select a second edge"<<"\n";
2243     // Boucle d'attente waitpick.
2244     Standard_Integer argccc = 5;
2245     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2246     const char **argvvv = (const char **) bufff;
2247     while (ViewerMainLoop( argccc, argvvv) ) { }
2248     // fin de la boucle
2249     
2250     TopoDS_Shape ShapeB;
2251     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2252       ShapeB = TheAISContext()->SelectedShape();
2253     }
2254     
2255     // recuperation des edges.
2256     TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
2257     TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
2258     
2259     // On recupere les  curves
2260     BRepAdaptor_Curve theCurveA(EdgeA);
2261     BRepAdaptor_Curve theCurveB(EdgeB);
2262     
2263     // On recupere 3 points A,B,C des  curves.
2264     gp_Pnt A=theCurveA.Value(0.1);
2265     gp_Pnt B=theCurveA.Value(0.9);
2266     gp_Pnt C=theCurveB.Value(0.5);
2267
2268     // Construction du Geom_Plane
2269     GC_MakePlane MkPlane(A,B,C);
2270     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2271     // Fermeture du contexte local.
2272     TheAISContext()->CloseLocalContext(myCurrentIndex);
2273     // Construction de l'AIS_TangentRelation
2274     Handle(AIS_TangentRelation) myTanRelation= new AIS_TangentRelation  (EdgeA ,EdgeB ,theGeomPlane );
2275     TheAISContext()->Display(myTanRelation );
2276     GetMapOfAIS().Bind (myTanRelation ,argv[1]);
2277     
2278     
2279   }
2280   
2281   // Shape A est une face
2282   // ====================
2283   else {
2284     
2285     // desactivation du mode edge
2286     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
2287     di<<" Select a second edge"<<"\n";
2288     // Boucle d'attente waitpick.
2289     Standard_Integer argccc = 5;
2290     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2291     const char **argvvv = (const char **) bufff;
2292     while (ViewerMainLoop( argccc, argvvv) ) { }
2293     // fin de la boucle
2294     
2295     TopoDS_Shape ShapeB;
2296     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2297       ShapeB = TheAISContext()->SelectedShape();
2298     }
2299     
2300     TopoDS_Face  FaceA=TopoDS::Face(ShapeA);
2301     TopoDS_Face  FaceB=TopoDS::Face(ShapeB);
2302     
2303     // recuperation des edges des faces.
2304     TopExp_Explorer FaceExpA(FaceA,TopAbs_EDGE);
2305     TopExp_Explorer FaceExpB(FaceB,TopAbs_EDGE);
2306     
2307     TopoDS_Edge EdgeA=TopoDS::Edge(FaceExpA.Current() );
2308     TopoDS_Edge EdgeB=TopoDS::Edge(FaceExpB.Current() );
2309     
2310     // On recupere les  vertexes extremites des edge A et B.
2311     BRepAdaptor_Curve theCurveA(EdgeA);
2312     BRepAdaptor_Curve theCurveB(EdgeB);
2313     // On recupere 3 points A,B,C des  curves.
2314     gp_Pnt A=theCurveA.Value(0.1);
2315     gp_Pnt B=theCurveA.Value(0.9);
2316     gp_Pnt C=theCurveB.Value(0.5);
2317
2318     // Construction du Geom_Plane
2319     GC_MakePlane MkPlane(A,B,C);
2320     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2321     // Fermeture du contexte local.
2322     TheAISContext()->CloseLocalContext(myCurrentIndex);
2323     // Construction de l'AIS_PerpendicularRelation
2324     Handle(AIS_TangentRelation) myTanRelation= new AIS_TangentRelation(FaceA ,FaceB,theGeomPlane );
2325     TheAISContext()->Display(myTanRelation );
2326     GetMapOfAIS().Bind (myTanRelation  ,argv[1]);
2327     
2328     
2329     
2330   }
2331   
2332   
2333   return 0;
2334   
2335 }
2336
2337 //==============================================================================
2338 //function : VSymetricalRelation
2339 //purpose  : Display the Symetrical Relation
2340 //Draw arg : vsymetric Name 
2341 //==============================================================================
2342 static int VSymmetricBuilder(Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
2343 {
2344   // Declarations
2345   Standard_Integer myCurrentIndex;
2346  
2347   // Verification
2348   if (argc!=2) {di<<" vSymmetric error"<<"\n";return 1;}
2349   
2350   // Fermeture des contextes locaux
2351   TheAISContext()->CloseAllContexts();
2352   
2353   // Ouverture d'un contexte local et recuperation de son index.
2354   TheAISContext()->OpenLocalContext();
2355   myCurrentIndex=TheAISContext()->IndexOfCurrentLocal();
2356   
2357   // On active les modes de selections
2358   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
2359   di<<" Select an edge:the axis of symetry "<<"\n";
2360   
2361   // Boucle d'attente waitpick.
2362   Standard_Integer argcc = 5;
2363   const char *buff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2364   const char **argvv = (const char **) buff;
2365   while (ViewerMainLoop( argcc, argvv) ) { }
2366   // fin de la boucle
2367   
2368   TopoDS_Shape ShapeA;
2369   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2370     ShapeA = TheAISContext()->SelectedShape();
2371   }
2372   // recuperation des edges.
2373   TopoDS_Edge  EdgeA=TopoDS::Edge(ShapeA);
2374   
2375   // On active les modes de selections
2376   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(2) );
2377   TheAISContext()->ActivateStandardMode (AIS_Shape::SelectionType(1) );
2378   di<<" Select two edges or two vertices. "<<"\n";
2379   
2380   // Boucle d'attente waitpick.
2381   Standard_Integer argcc2 = 5;
2382 //  const char *buff2[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2383   const char **argvv2 = (const char **) buff;
2384   while (ViewerMainLoop( argcc2, argvv2) ) { }
2385   // fin de la boucle
2386   
2387   TopoDS_Shape ShapeB;
2388   for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2389     ShapeB = TheAISContext()->SelectedShape();
2390   }
2391   
2392   
2393   
2394   
2395   
2396   // ShapeB est un edge.
2397   // ===================
2398   if (ShapeB.ShapeType()==TopAbs_EDGE ) {
2399     
2400     // desactivation du mode vertex
2401     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(1) );
2402     di<<" Select a second edge"<<"\n";
2403     // Boucle d'attente waitpick.
2404     Standard_Integer argccc = 5;
2405     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2406     const char **argvvv = (const char **) bufff;
2407     while (ViewerMainLoop( argccc, argvvv) ) { }
2408     // fin de la boucle
2409     
2410     TopoDS_Shape ShapeC;
2411     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2412       ShapeC = TheAISContext()->SelectedShape();
2413     }
2414     
2415     // recuperation des edges.
2416     TopoDS_Edge  EdgeB=TopoDS::Edge(ShapeB);
2417     TopoDS_Edge  EdgeC=TopoDS::Edge(ShapeC);
2418     // on verifie que les edges sont paralleles
2419     BRepExtrema_ExtCC myDeltaEdgeAB (EdgeA ,EdgeB );
2420     BRepExtrema_ExtCC myDeltaEdgeAC (EdgeA ,EdgeC );
2421     // on verifie qu'ils  sont paralleles.
2422     if (!myDeltaEdgeAB.IsParallel() ) {di<<"vsymetric error: non parallel edges."<<"\n";return 1; }
2423     if (!myDeltaEdgeAC.IsParallel() ) {di<<"vsymetric error: non parallel edges."<<"\n";return 1; }
2424     // on recupere les vertexs
2425     TopoDS_Vertex  Va,Vb,Vc,Vd;
2426     TopExp::Vertices(EdgeB,Va,Vb );
2427     TopExp::Vertices(EdgeC,Vc,Vd );
2428     gp_Pnt A=BRep_Tool::Pnt(Va);
2429     gp_Pnt B=BRep_Tool::Pnt(Vc);
2430     gp_Pnt C = Get3DPointAtMousePosition();
2431     
2432     //    gp_Pnt C=BRep_Tool::Pnt(Vc);
2433     // Construction du Geom_Plane
2434     GC_MakePlane MkPlane(A,B,C);
2435     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2436     // Fermeture du contexte local.
2437     TheAISContext()->CloseLocalContext(myCurrentIndex);
2438     // Construction de l'AIS_SymmetricRelation
2439     Handle(AIS_SymmetricRelation) mySymRelation= new AIS_SymmetricRelation (EdgeA ,EdgeB ,EdgeC, theGeomPlane );
2440     TheAISContext()->Display(mySymRelation );
2441     GetMapOfAIS().Bind (mySymRelation ,argv[1]);
2442     
2443     
2444   }
2445   
2446   // Shape B est un vertex
2447   // =====================
2448   else {
2449     
2450     // desactivation du mode edge
2451     TheAISContext()->DeactivateStandardMode (AIS_Shape::SelectionType(2) );
2452     di<<" Select a second edge"<<"\n";
2453     // Boucle d'attente waitpick.
2454     Standard_Integer argccc = 5;
2455     const char *bufff[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2456     const char **argvvv = (const char **) bufff;
2457     while (ViewerMainLoop( argccc, argvvv) ) { }
2458     // fin de la boucle
2459     
2460     TopoDS_Shape ShapeC;
2461     for(TheAISContext()->InitSelected() ;TheAISContext()->MoreSelected() ;TheAISContext()->NextSelected() ) {
2462       ShapeC = TheAISContext()->SelectedShape();
2463     }
2464     
2465     // recuperation des Vertex
2466     TopoDS_Vertex  VertexB=TopoDS::Vertex(ShapeB);
2467     TopoDS_Vertex  VertexC=TopoDS::Vertex(ShapeC);
2468     // transfo en gp_Pnt
2469     gp_Pnt B=BRep_Tool::Pnt(VertexB);
2470     gp_Pnt C=BRep_Tool::Pnt(VertexC);
2471     
2472     // on recupere les vertexes de l'axe de sym
2473     TopoDS_Vertex  Va,Vb;
2474     TopExp::Vertices(EdgeA,Va,Vb );
2475     gp_Pnt A=BRep_Tool::Pnt(Va);
2476     // Construction du Geom_Plane
2477     GC_MakePlane MkPlane(A,B,C);
2478     Handle(Geom_Plane) theGeomPlane=MkPlane.Value();
2479     // Fermeture du contexte local.
2480     TheAISContext()->CloseLocalContext(myCurrentIndex);
2481     // Construction de l'AIS_SymmetricRelation
2482     Handle(AIS_SymmetricRelation) mySymRelation= new AIS_SymmetricRelation (EdgeA ,VertexB ,VertexC, theGeomPlane );
2483     TheAISContext()->Display(mySymRelation );
2484     GetMapOfAIS().Bind (mySymRelation ,argv[1]);
2485     
2486     
2487     
2488   }
2489   
2490   
2491   return 0;
2492   
2493 }
2494
2495 //=======================================================================
2496 //function : VDimParam
2497 //purpose  : Sets aspect parameters to dimension.
2498 //=======================================================================
2499 static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
2500 {
2501   if (theArgNum < 3)
2502   {
2503     theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
2504     return 1;
2505   }
2506
2507
2508   TCollection_AsciiString aName (theArgVec[1]);
2509   gp_Pln aWorkingPlane;
2510   Standard_Boolean isCustomPlane = Standard_False;
2511   Standard_Boolean toUpdate = Standard_True;
2512
2513   NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
2514   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
2515
2516   if (!GetMapOfAIS().IsBound2 (aName))
2517   {
2518     theDi << theArgVec[0] << "error: no object with this name.\n";
2519     return 1;
2520   }
2521
2522   Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
2523   if (anObject->Type() != AIS_KOI_Dimension)
2524   {
2525     theDi << theArgVec[0] << "error: no dimension with this name.\n";
2526     return 1;
2527   }
2528
2529   Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
2530   Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
2531
2532   if (ParseDimensionParams (theArgNum, theArgVec, 2, anAspect,
2533                             isCustomPlane, aWorkingPlane,
2534                             aRealParams, aStringParams))
2535   {
2536     return 1;
2537   }
2538
2539   if (isCustomPlane)
2540   {
2541     aDim->SetCustomPlane (aWorkingPlane);
2542   }
2543
2544   SetDimensionParams (aDim, aRealParams, aStringParams);
2545
2546   if (!aDim->IsValid())
2547   {
2548     std::cerr << "Error: Dimension geometry or plane is not valid.\n";
2549     return 1;
2550   }
2551
2552   // Redisplay a dimension after parameter changing.
2553   if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
2554   {
2555     ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
2556   }
2557
2558   return 0;
2559 }
2560
2561 //=======================================================================
2562 //function : VMoveDim
2563 //purpose  : Moves dimension or relation text label to defined or picked
2564 //           position and updates the object.
2565 //draw args: vmovedim [name] [x y z]
2566 //=======================================================================
2567 static int VMoveDim (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec) 
2568 {
2569   if (theArgNum > 5)
2570   {
2571     theDi << theArgVec[0] << " error: the wrong number of parameters.\n";
2572     return 1;
2573   }
2574
2575   // Parameters parsing
2576   Standard_Boolean isNameSet = (theArgNum ==2 || theArgNum == 5);
2577   Standard_Boolean isPointSet = (theArgNum == 4 || theArgNum == 5);
2578
2579   Handle(AIS_InteractiveObject) aPickedObj;
2580   gp_Pnt aPoint (gp::Origin());
2581   Standard_Integer aMaxPickNum = 5;
2582
2583   // Find object
2584   if (isNameSet)
2585   {
2586      TCollection_AsciiString aName (theArgVec[1]);
2587      if (!GetMapOfAIS().IsBound2 (aName))
2588      {
2589        theDi << theArgVec[0] << " error: no object with this name.\n";
2590        return 1;
2591      }
2592
2593      aPickedObj = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
2594      
2595      if (aPickedObj.IsNull())
2596      {
2597        theDi << theArgVec[0] << " error: the object with this name is not valid.\n";
2598        return 1;
2599      }
2600
2601      if (aPickedObj->Type() != AIS_KOI_Dimension && aPickedObj->Type() != AIS_KOI_Relation)
2602      {
2603        theDi << theArgVec[0] << " error: no dimension or relation with this name.\n";
2604        return 1;
2605      }
2606   }
2607   else // Pick dimension or relation
2608   {
2609     // Close all local contexts
2610     TheAISContext()->CloseAllContexts();
2611
2612     // Open local context and get its index for recovery.
2613     TheAISContext()->OpenLocalContext();
2614
2615     // Loop that will be handle picking.
2616     Standard_Integer anArgNum = 5;
2617     const char *aBuffer[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
2618     const char **anArgVec = (const char **) aBuffer;
2619
2620     Standard_Boolean isPicked = Standard_False;
2621     Standard_Integer aPickNum = 0;
2622     while (!isPicked && aPickNum < aMaxPickNum)
2623     {
2624       while (ViewerMainLoop (anArgNum, anArgVec)) { }
2625
2626       for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
2627       {
2628         aPickedObj = TheAISContext()->SelectedInteractive();
2629       }
2630
2631       isPicked = (!aPickedObj.IsNull() && (aPickedObj->Type() == AIS_KOI_Dimension || aPickedObj->Type() == AIS_KOI_Relation));
2632
2633       if (isPicked)
2634       {
2635         break;
2636       }
2637       aPickNum++;
2638     }
2639     if (!isPicked)
2640     {
2641       theDi << theArgVec[0] << ": no dimension or relation is selected." << "\n";
2642       return 1;
2643     }
2644   }
2645
2646   // Find point
2647   if (isPointSet)
2648   {
2649     aPoint = theArgNum == 4 ? gp_Pnt (atoi (theArgVec[1]), atoi (theArgVec[2]), atoi (theArgVec[3]))
2650                             : gp_Pnt (atoi (theArgVec[2]), atoi (theArgVec[3]), atoi (theArgVec[4]));
2651   }
2652   else // Pick the point
2653   {
2654     Standard_Integer aPickArgNum = 5;
2655     const char *aPickBuff[] = {"VPick", "X", "VPickY", "VPickZ", "VPickShape"};
2656     const char **aPickArgVec = (const char **) aPickBuff;
2657
2658     while (ViewerMainLoop (aPickArgNum, aPickArgVec)) { }
2659
2660     // Set text position, update relation or dimension.
2661     if (aPickedObj->Type() == AIS_KOI_Relation)
2662     {
2663       Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
2664       aPoint = Get3DPointAtMousePosition();
2665       aRelation->SetPosition (aPoint);
2666       TheAISContext()->Redisplay (aRelation);
2667     }
2668     else
2669     {
2670       Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
2671       gp_Pnt aFirstPoint, aSecondPoint;
2672       if (aDim->KindOfDimension() == AIS_KOD_PLANEANGLE)
2673       {
2674         Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (aDim);
2675         aFirstPoint = anAngleDim->FirstPoint();
2676         aSecondPoint = anAngleDim->SecondPoint();
2677       }
2678       else if (aDim->KindOfDimension() == AIS_KOD_LENGTH)
2679       {
2680         Handle(AIS_LengthDimension) aLengthDim = Handle(AIS_LengthDimension)::DownCast (aDim);
2681         aFirstPoint = aLengthDim->FirstPoint();
2682         aSecondPoint = aLengthDim->SecondPoint();
2683       }
2684       else if (aDim->KindOfDimension() == AIS_KOD_RADIUS)
2685       {
2686         Handle(AIS_RadiusDimension) aRadiusDim = Handle(AIS_RadiusDimension)::DownCast (aDim);
2687         aFirstPoint = aRadiusDim->AnchorPoint();
2688         aSecondPoint = aRadiusDim->Circle().Location();
2689       }
2690       else if (aDim->KindOfDimension() == AIS_KOD_DIAMETER)
2691       {
2692         Handle(AIS_DiameterDimension) aDiameterDim = Handle(AIS_DiameterDimension)::DownCast (aDim);
2693         aFirstPoint = aDiameterDim->AnchorPoint();
2694         aSecondPoint = aDiameterDim->Circle().Location();
2695       }
2696
2697       if (!Get3DPointAtMousePosition (aFirstPoint, aSecondPoint, aPoint))
2698       {
2699         return 1;
2700       }
2701
2702       aDim->SetTextPosition (aPoint);
2703       TheAISContext()->Redisplay (aDim);
2704     }
2705
2706   }
2707
2708   // Set text position, update relation or dimension.
2709   if (aPickedObj->Type() == AIS_KOI_Relation)
2710   {
2711     Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
2712     aRelation->SetPosition (aPoint);
2713     TheAISContext()->Redisplay (aRelation);
2714   }
2715   else
2716   {
2717     Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
2718     aDim->SetTextPosition (aPoint);
2719     TheAISContext()->Redisplay (aDim);
2720   }
2721
2722   return 0;
2723 }
2724
2725 //=======================================================================
2726 //function : RelationsCommands
2727 //purpose  : 
2728 //=======================================================================
2729       
2730
2731 void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
2732 {
2733   const char *group = "AISRelations";
2734
2735   theCommands.Add("vdimension",
2736       "vdimension name {-angle|-length|-radius|-diameter} -shapes shape1 [shape2 [shape3]]\n"
2737       "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
2738       "[-font FontName]\n"
2739       "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
2740       "[-arrow external|internal|fit]\n"
2741       "[{-arrowlength|-arlen} RealArrowLength]\n"
2742       "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
2743       "[-plane xoy|yoz|zox]\n"
2744       "[-flyout FloatValue -extension FloatValue]\n"
2745       "[-value CustomNumberValue]\n"
2746       "[-dispunits DisplayUnitsString]\n"
2747       "[-modelunits ModelUnitsString]\n"
2748       "[-showunits | -hideunits]\n"
2749       " -Builds angle, length, radius and diameter dimensions.\n"
2750       " -See also: vdimparam, vmovedim.\n",
2751       __FILE__,VDimBuilder,group);
2752
2753   theCommands.Add("vdimparam",
2754     "vdimparam name"
2755     "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
2756     "[-font FontName]\n"
2757     "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
2758     "[-arrow external|internal|fit]\n"
2759     "[{-arrowlength|-arlen} RealArrowLength]\n"
2760     "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
2761     "[-plane xoy|yoz|zox]\n"
2762     "[-flyout FloatValue -extension FloatValue]\n"
2763     "[-value CustomNumberValue]\n"
2764     "[-dispunits DisplayUnitsString]\n"
2765     "[-modelunits ModelUnitsString]\n"
2766     "[-showunits | -hideunits]\n"
2767     " -Sets parameters for angle, length, radius and diameter dimensions.\n"
2768     " -See also: vmovedim, vdimension.\n",
2769     __FILE__,VDimParam,group);
2770
2771   theCommands.Add("vangledim",
2772                   "vangledim Name:Selection in the viewer only ",
2773                   __FILE__,VAngleDimBuilder,group);
2774   
2775   theCommands.Add("vdiameterdim",
2776                   "vdiameterdim Name : Selection in the viewer only ",
2777                   __FILE__,VDiameterDimBuilder,group);
2778   
2779   theCommands.Add("vconcentric",
2780                   "vconcentric Name : Selection in the viewer only ",
2781                   __FILE__,VConcentricBuilder,group);
2782
2783   theCommands.Add("vequaldist",
2784                   "vequaldist Name Selection in the viewer only ",
2785                   __FILE__,VEqualDistRelation ,group);
2786   
2787   theCommands.Add("vequalrad",
2788                   "vequalrad Name Selection in the viewer only ",
2789                   __FILE__,VEqualRadiusRelation  ,group);
2790   
2791   theCommands.Add("vfix",  
2792                   "vfix Name Selection in the viewer only ",
2793                   __FILE__,VFixRelation  ,group);
2794   
2795   theCommands.Add("videntity",
2796                   "videntity Name Selection in the viewer only ",
2797                   __FILE__,VIdenticRelation  ,group);
2798   
2799   theCommands.Add("vdistdim",
2800                   "vdistdim Name Selection in the viewer only ",
2801                   __FILE__,VLenghtDimension ,group);
2802   
2803   theCommands.Add("vradiusdim",
2804                   "vradiusdim Name Selection in the viewer only ",
2805                   __FILE__,VRadiusDimBuilder ,group);
2806   
2807   theCommands.Add("voffsetdim",
2808                   "voffsetdim Name Selection in the viewer only ",
2809                   __FILE__,VOffsetDimBuilder ,group);
2810   
2811   theCommands.Add("vparallel",
2812                   "vparallel Name Selection in the viewer only ",
2813                   __FILE__,VParallelBuilder ,group);
2814   
2815   theCommands.Add("vortho",
2816                   "vortho Name Selection in the viewer only ",
2817                   __FILE__,VPerpendicularBuilder ,group);
2818   
2819   theCommands.Add("vtangent",  
2820                   "vtangent Name Selection in the viewer only ",
2821                   __FILE__,VTangentBuilder ,group);
2822   
2823   
2824   theCommands.Add("vsymetric",
2825                   "vsymetric Name Selection in the viewer only ",
2826                   __FILE__,VSymmetricBuilder ,group);
2827
2828   theCommands.Add("vmovedim",
2829       "vmovedim : vmovedim [name] [x y z]"
2830       "\n\t\t: Moves picked or named (if name defined)"
2831       "\n\t\t: dimension to picked mouse position or input point."
2832       "\n\t\t: Text label of dimension 'name' is moved to position, another parts of dimensionare adjusted.",
2833                   __FILE__,VMoveDim,group);
2834
2835 }