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