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