Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_SymmetricRelation.cxx
1 // File:        AIS_SymmetricRelation.cxx
2 // Created:     Mon Mar  3 16:17:40 1997
3 // Author:      Jean-Pierre COMBE
4 //              <jpr>
5
6 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
7 //                      if any in all dimensions.
8
9 #include <Standard_NotImplemented.hxx>
10
11 #include <AIS_SymmetricRelation.ixx>
12 #include <AIS.hxx>
13 #include <AIS_Drawer.hxx>
14
15 #include <gce_MakeLin.hxx>
16 #include <SelectMgr_EntityOwner.hxx>
17 #include <Select3D_SensitiveSegment.hxx>
18 #include <Select3D_SensitiveBox.hxx>
19 #include <Precision.hxx>
20 #include <TopoDS.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Circ.hxx>
26 #include <gp_Pnt.hxx>
27 #include <ElCLib.hxx>
28 #include <gp_Pln.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Ax1.hxx>
31 #include <gp_Ax2.hxx>
32
33 #include <Geom_Plane.hxx>
34 #include <Geom_Line.hxx>
35 #include <Geom_Circle.hxx>
36 #include <TopExp_Explorer.hxx>
37
38 #include <Precision.hxx>
39 #include <Prs3d_Drawer.hxx>
40 #include <Prs3d_ArrowAspect.hxx>
41 #include <Prs3d_LengthAspect.hxx>
42
43 #include <DsgPrs_SymmetricPresentation.hxx>
44
45 //=======================================================================
46 //function : AIS_SymmetricRelation
47 //purpose  : 
48 //=======================================================================
49 AIS_SymmetricRelation::AIS_SymmetricRelation(const TopoDS_Shape& aSymmTool, 
50                                              const TopoDS_Shape& FirstShape, 
51                                              const TopoDS_Shape& SecondShape, 
52                                              const Handle(Geom_Plane)& aPlane)
53 :AIS_Relation(),
54  myTool(aSymmTool)
55 {
56  SetFirstShape(FirstShape);
57  SetSecondShape(SecondShape);
58  SetPlane(aPlane);
59  myPosition = aPlane->Pln().Location();
60 }
61
62 //=======================================================================
63 //function : Compute
64 //purpose  : 
65 //=======================================================================
66 void AIS_SymmetricRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, 
67                                     const Handle(Prs3d_Presentation)& aprs, 
68                                     const Standard_Integer)
69 {
70   aprs->Clear();
71
72   switch (myFShape.ShapeType()) {
73   case TopAbs_FACE :
74     {
75       // cas symetrie entre deux faces
76       ComputeTwoFacesSymmetric(aprs);
77     }
78     break;
79   case TopAbs_EDGE :
80     {
81       // cas symetrie entre deux edges
82       ComputeTwoEdgesSymmetric(aprs);
83     }
84     break;
85   case TopAbs_VERTEX :
86     {
87       // cas symetrie entre deux vertexs
88       ComputeTwoVerticesSymmetric(aprs);
89     }
90     break;
91   default:
92     break;
93   }
94   if (myTool.ShapeType() == TopAbs_EDGE) {
95     Handle(Geom_Curve) aCurve,extcurve;
96     gp_Pnt p1,p2;
97     Standard_Boolean isinfinite,isonplane;
98     if (AIS::ComputeGeometry(TopoDS::Edge(myTool),
99                              aCurve,p1,p2,
100                              extcurve,
101                              isinfinite,
102                              isonplane,
103                              myPlane)) {
104       if (!extcurve.IsNull()) { 
105         gp_Pnt pf, pl;
106         if (!isinfinite) {
107           pf = p1; 
108           pl = p2;
109         }
110         if (isinfinite) aprs->SetInfiniteState(Standard_True);
111         ComputeProjEdgePresentation(aprs,TopoDS::Edge(myTool),aCurve,pf,pl);
112       }
113     }
114   }
115 }
116
117 //=======================================================================
118 //function : Compute
119 //purpose  : to avoid warning at compilation (SUN)
120 //=======================================================================
121 void AIS_SymmetricRelation::Compute(const Handle(Prs3d_Projector)& /*aProjector*/,
122                                     const Handle(Prs3d_Presentation)& /*aPresentation*/)
123 {
124 // Standard_NotImplemented::Raise("AIS_SymmetricRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
125 // PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
126 }
127
128 //=======================================================================
129 //function : Compute
130 //purpose  : to avoid warning at compilation (SUN)
131 //=======================================================================
132 void AIS_SymmetricRelation::Compute
133   (const Handle(PrsMgr_PresentationManager2d)& /*aPresentationManager2d*/,
134    const Handle(Graphic2d_GraphicObject)& /*aGraphicObject*/,
135    const Standard_Integer /*anInteger*/)
136 {
137 // Standard_NotImplemented::Raise("AIS_SymmetricRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
138 // PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
139 }
140
141 void AIS_SymmetricRelation::Compute(const Handle_Prs3d_Projector& aProjector,
142                                     const Handle_Geom_Transformation& aTransformation,
143                                     const Handle_Prs3d_Presentation& aPresentation)
144 {
145  Standard_NotImplemented::Raise("AIS_SymmetricRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
146  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
147 }
148
149 //=======================================================================
150 //function : ComputeSelection
151 //purpose  : 
152 //=======================================================================
153 void AIS_SymmetricRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSel, 
154                                              const Standard_Integer)
155 {
156   Handle(Select3D_SensitiveSegment) seg;
157   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
158   Standard_Real F,L;
159
160   Handle(Geom_Line) geom_axis,extcurve;
161   gp_Pnt p1,p2;
162   Standard_Boolean isinfinite,isonplane;
163   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
164                             geom_axis,p1,p2,
165                             extcurve,
166                             isinfinite,
167                             isonplane,
168                             myPlane)) return;
169
170   gp_Lin laxis (geom_axis->Lin());
171   
172   if(myFShape.ShapeType() != TopAbs_VERTEX){
173     BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
174     
175     if(cu1.GetType() == GeomAbs_Line) {
176 //      gp_Lin L1 (myFAttach,myFDirAttach);
177       gp_Pnt PjAttachPnt1  = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
178       gp_Pnt PjOffSetPnt   = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
179       Standard_Real h = fabs(PjOffSetPnt.Distance(PjAttachPnt1)/cos(myAxisDirAttach.Angle(myFDirAttach)));
180       gp_Vec VL1(myFDirAttach);
181       gp_Vec VLa(PjAttachPnt1,PjOffSetPnt);
182       Standard_Real scal = VL1.Dot(VLa);
183       if(scal < 0) VL1.Reverse();
184       VL1.Multiply(h);
185       gp_Pnt P1 = myFAttach.Translated(VL1);
186       gp_Pnt ProjAxis = ElCLib::Value(ElCLib::Parameter(laxis,P1),laxis);
187       gp_Vec v(P1,ProjAxis);
188       gp_Pnt P2 = ProjAxis.Translated(v);
189       
190       gp_Lin L3;
191       
192       if (!P1.IsEqual(P2,Precision::Confusion())) {
193         L3 = gce_MakeLin(P1,P2);
194       }
195       else {
196         L3 = gce_MakeLin(P1,myFDirAttach);
197         Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
198         Handle(Select3D_SensitiveBox) box =
199           new Select3D_SensitiveBox(own,
200                                     myPosition.X(),
201                                     myPosition.Y(),
202                                     myPosition.Z(),
203                                     myPosition.X()+size,
204                                     myPosition.Y()+size,
205                                     myPosition.Z()+size);
206         aSel->Add(box);
207       }
208       Standard_Real parmin,parmax,parcur;
209       parmin = ElCLib::Parameter(L3,P1);
210       parmax = parmin;
211       
212       parcur = ElCLib::Parameter(L3,P2);
213       parmin = Min(parmin,parcur);
214       parmax = Max(parmax,parcur);
215       
216       parcur = ElCLib::Parameter(L3,myPosition);
217       parmin = Min(parmin,parcur);
218       parmax = Max(parmax,parcur);
219       
220       gp_Pnt PointMin = ElCLib::Value(parmin,L3);
221       gp_Pnt PointMax = ElCLib::Value(parmax,L3);
222       
223       if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
224         seg = new Select3D_SensitiveSegment(own,
225                                             PointMin,
226                                             PointMax);
227         aSel->Add(seg);
228       }
229       if (!myFAttach.IsEqual(P1,Precision::Confusion())) {
230         seg = new Select3D_SensitiveSegment(own,
231                                             myFAttach,
232                                             P1);
233         aSel->Add(seg);
234       }
235       if (!mySAttach.IsEqual(P2,Precision::Confusion())) {
236         seg = new Select3D_SensitiveSegment(own,
237                                             mySAttach,
238                                             P2);
239         aSel->Add(seg);
240       }
241     }
242     
243     //=======================Pour les arcs======================    
244   if(cu1.GetType() == GeomAbs_Circle) { 
245     BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
246 //    Handle(Geom_Circle) geom_circ1 = (Handle(Geom_Circle)&) BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
247 //JR/Hp
248     Handle(Geom_Curve) aGeomCurve = BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
249     Handle(Geom_Circle) geom_circ1 = (Handle(Geom_Circle)&) aGeomCurve ;
250 //    Handle(Geom_Circle) geom_circ1 = (const Handle(Geom_Circle)&) BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
251     gp_Circ circ1(geom_circ1->Circ());
252     gp_Pnt OffsetPnt(myPosition.X(),myPosition.Y(),myPosition.Z());
253     gp_Pnt Center1 = circ1.Location();
254     gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(laxis,OffsetPnt),laxis);
255     gp_Pnt ProjCenter1     = ElCLib::Value(ElCLib::Parameter(laxis,Center1),laxis);
256     gp_Vec Vp(ProjCenter1,Center1);
257     if (Vp.Magnitude() <= Precision::Confusion()) Vp = gp_Vec(laxis.Direction())^myPlane->Pln().Position().Direction();
258     Standard_Real Dt,R,h;
259     Dt = ProjCenter1.Distance(ProjOffsetPoint);
260     R  = circ1.Radius();
261     if (Dt > .999*R) {
262       Dt = .999*R;
263       gp_Vec Vout(ProjCenter1,ProjOffsetPoint);
264       ProjOffsetPoint = ProjCenter1.Translated(Vout.Divided(Vout.Magnitude()).Multiplied(Dt));
265       OffsetPnt = ProjOffsetPoint;
266     }
267     h  = Sqrt(R*R - Dt*Dt);
268     gp_Pnt P1 = ProjOffsetPoint.Translated(Vp.Added(Vp.Divided(Vp.Magnitude()).Multiplied(h)));
269     gp_Vec v(P1,ProjOffsetPoint);
270     gp_Pnt P2 = ProjOffsetPoint.Translated(v);
271     
272     gp_Lin L3;
273     if (!P1.IsEqual(P2,Precision::Confusion())) {
274       L3 = gce_MakeLin(P1,P2);
275     }
276     else {
277       L3 = gce_MakeLin(P1,laxis.Direction());
278       Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
279       Handle(Select3D_SensitiveBox) box =
280         new Select3D_SensitiveBox(own,
281                                   myPosition.X(),
282                                   myPosition.Y(),
283                                   myPosition.Z(),
284                                   myPosition.X()+size,
285                                   myPosition.Y()+size,
286                                   myPosition.Z()+size);
287       aSel->Add(box);
288     }
289     Standard_Real parmin,parmax,parcur;
290     parmin = ElCLib::Parameter(L3,P1);
291     parmax = parmin;
292     
293     parcur = ElCLib::Parameter(L3,P2);
294     parmin = Min(parmin,parcur);
295     parmax = Max(parmax,parcur);
296     
297     parcur = ElCLib::Parameter(L3,myPosition);
298     parmin = Min(parmin,parcur);
299     parmax = Max(parmax,parcur);
300     
301     gp_Pnt PointMin = ElCLib::Value(parmin,L3);
302     gp_Pnt PointMax = ElCLib::Value(parmax,L3);
303     
304     if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
305       seg = new Select3D_SensitiveSegment(own,
306                                           PointMin,
307                                           PointMax);
308       aSel->Add(seg);
309     }
310   }
311   }
312   //=======================Pour les points======================
313   else {
314     if (myFAttach.IsEqual(mySAttach,Precision::Confusion())) {
315       seg = new Select3D_SensitiveSegment(own,myPosition,myFAttach);
316       aSel->Add(seg);
317     }
318     else{
319       gp_Pnt ProjOffsetPoint      = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
320       gp_Pnt ProjAttachmentPoint1 = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
321       gp_Vec PjAtt1_Att1(ProjAttachmentPoint1,myFAttach);
322       gp_Pnt P1 = ProjOffsetPoint.Translated(PjAtt1_Att1);
323       gp_Pnt P2 = ProjOffsetPoint.Translated(PjAtt1_Att1.Reversed());
324       gp_Lin L3;
325       
326       if (!P1.IsEqual(P2,Precision::Confusion())) {
327         L3 = gce_MakeLin(P1,P2);
328       }
329       else {
330         L3 = gce_MakeLin(P1,myFDirAttach);
331         Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
332         Handle(Select3D_SensitiveBox) box =
333           new Select3D_SensitiveBox(own,
334                                     myPosition.X(),
335                                     myPosition.Y(),
336                                     myPosition.Z(),
337                                     myPosition.X()+size,
338                                     myPosition.Y()+size,
339                                     myPosition.Z()+size);
340         aSel->Add(box);
341       }
342       Standard_Real parmin,parmax,parcur;
343       parmin = ElCLib::Parameter(L3,P1);
344       parmax = parmin;
345       
346       parcur = ElCLib::Parameter(L3,P2);
347       parmin = Min(parmin,parcur);
348       parmax = Max(parmax,parcur);
349       
350       parcur = ElCLib::Parameter(L3,myPosition);
351       parmin = Min(parmin,parcur);
352       parmax = Max(parmax,parcur);
353       
354       gp_Pnt PointMin = ElCLib::Value(parmin,L3);
355       gp_Pnt PointMax = ElCLib::Value(parmax,L3);
356       
357       if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
358         seg = new Select3D_SensitiveSegment(own,PointMin,PointMax);
359         aSel->Add(seg);
360       }
361       if (!myFAttach.IsEqual(P1,Precision::Confusion())) {
362         seg = new Select3D_SensitiveSegment(own,myFAttach,P1);
363         aSel->Add(seg);
364       }
365       if (!mySAttach.IsEqual(P2,Precision::Confusion())) {
366         seg = new Select3D_SensitiveSegment(own,mySAttach,P2);
367         aSel->Add(seg);
368       }
369     }
370   }
371 }
372
373 //=======================================================================
374 //function : ComputeTwoFacesSymmetric
375 //purpose  : 
376 //=======================================================================
377 void AIS_SymmetricRelation::ComputeTwoFacesSymmetric(const Handle(Prs3d_Presentation)&)
378 {
379 }
380
381 //=======================================================================
382 //function : ComputeTwoEdgesSymmetric
383 //purpose  : 
384 //=======================================================================
385 void AIS_SymmetricRelation::ComputeTwoEdgesSymmetric(const Handle(Prs3d_Presentation)& aprs)
386 {
387   BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
388   if (cu1.GetType() != GeomAbs_Line && cu1.GetType() != GeomAbs_Circle) return;
389   BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
390   if (cu2.GetType() != GeomAbs_Line && cu2.GetType() != GeomAbs_Circle) return;
391 //  gp_Pnt pint3d,ptat11,ptat12,ptat21,ptat22;
392   gp_Pnt ptat11,ptat12,ptat21,ptat22;
393   Handle(Geom_Curve) geom1,geom2;
394   Standard_Boolean isInfinite1,isInfinite2;
395   Handle(Geom_Curve) extCurv;
396   if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
397                             TopoDS::Edge(mySShape),
398                             myExtShape,
399                             geom1,
400                             geom2,
401                             ptat11,
402                             ptat12,
403                             ptat21,
404                             ptat22,
405                             extCurv,
406                             isInfinite1,isInfinite2,
407                             myPlane)) {
408     return;
409   } 
410   aprs->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape !=0));
411   Handle(Geom_Line) geom_axis,extcurve;
412   gp_Pnt p1,p2;
413   Standard_Boolean isinfinite,isonplane;
414   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
415                             geom_axis,p1,p2,
416                             extcurve,
417                             isinfinite,
418                             isonplane,
419                             myPlane)) return;
420
421   gp_Lin laxis (geom_axis->Lin());
422   myAxisDirAttach = laxis.Direction();
423
424   if(cu1.GetType() == GeomAbs_Line){
425     const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
426     gp_Lin l1(geom_lin1->Lin());
427     myFDirAttach = l1.Direction();
428   }
429   gp_Circ circ;
430   if(cu1.GetType() == GeomAbs_Circle){
431     const Handle(Geom_Circle)& geom_cir1 = (Handle(Geom_Circle)&) geom1;
432     gp_Circ c(geom_cir1->Circ());
433     circ = c;
434   }
435   
436   // recherche points attache
437   gp_Pnt ProjOffset = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
438   
439 /*//----------------------------------------------------
440   //Quand on fait la symetrie de 2 edges consecutifs:
441   //              
442   //              :<-- Axe
443   //              :
444   //             /:\
445   // Edge n --->/ : \
446   //           /  :  \<-- Edge n+1
447   //              :
448   //----------------------------------------------------
449 */
450   Standard_Boolean idem = Standard_False;
451   if (isInfinite1 && isInfinite2) { // geom1 et geom2 sont des lignes
452     const gp_Lin& line2 = ((Handle(Geom_Line)&) geom2)->Lin();
453     if (myAutomaticPosition) {
454       myFAttach = ((Handle(Geom_Line)&) geom1)->Lin().Location();      
455       mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
456     }
457     else {
458       const gp_Lin& line1 = ((Handle(Geom_Line)&) geom1)->Lin();
459       myFAttach = ElCLib::Value(ElCLib::Parameter(line1,myPosition),line1);
460       mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
461     }
462   }
463   else if (!isInfinite1 && !isInfinite2) {
464     if (ptat11.IsEqual(ptat21,Precision::Confusion())) {
465       myFAttach = ptat12;
466       mySAttach = ptat22;
467       idem = Standard_True;
468     }
469     if (ptat11.IsEqual(ptat22,Precision::Confusion())) {
470       myFAttach = ptat12;
471       mySAttach = ptat21;
472       idem = Standard_True;
473     }
474     if (ptat12.IsEqual(ptat21,Precision::Confusion())) {
475       myFAttach = ptat11;
476       mySAttach = ptat22;
477       idem = Standard_True;
478     }
479     if (ptat12.IsEqual(ptat22,Precision::Confusion())) {
480       myFAttach = ptat11;
481       mySAttach = ptat21;
482       idem = Standard_True;
483     }
484     if(!idem){
485       if( ProjOffset.SquareDistance(ptat11) > ProjOffset.SquareDistance(ptat12)) myFAttach = ptat12;
486       else myFAttach = ptat11;
487       
488       if (ProjOffset.SquareDistance(ptat21) > ProjOffset.SquareDistance(ptat22)) mySAttach = ptat22;
489       else mySAttach = ptat21;
490     }
491   }
492   else if (isInfinite1) {// geom1 et geom2 sont des lignes
493     mySAttach = ptat21;
494     const gp_Lin& line1 = ((Handle(Geom_Line)&) geom1)->Lin();
495     myFAttach = ElCLib::Value(ElCLib::Parameter(line1,mySAttach),line1);
496   }
497   else if (isInfinite2) {// geom1 et geom2 sont des lignes
498     myFAttach = ptat11;
499     const gp_Lin& line2 = ((Handle(Geom_Line)&) geom2)->Lin();
500     mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
501   }
502
503 #ifdef BUC60915
504   if( !myArrowSizeIsDefined )
505 #endif
506     myArrowSize = myFAttach.Distance(mySAttach)/50.;
507   //----------------------------------------------------
508  
509   //----------------------------------------------------
510   // Si myFAttach <> mySAttach et PjFAttach = myFAttach
511   //----------------------------------------------------
512   gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
513  
514   if (PjFAttach.IsEqual(myFAttach,Precision::Confusion())){
515     const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
516     gp_Lin l2(geom_lin2->Lin());
517     myFDirAttach = l2.Direction();
518     gp_Pnt PntTempo;
519     PntTempo  = myFAttach;
520     myFAttach = mySAttach;
521     mySAttach = PntTempo;
522     PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
523   }
524   
525   //----------------------------------------------------
526 //  gp_Pnt curpos;
527
528   if (myAutomaticPosition) {    
529     //gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
530     // offset pour eviter confusion Edge et Dimension
531     gp_Vec offset(myAxisDirAttach);
532     offset = offset * myArrowSize * (-5);
533     gp_Vec Vt(myFAttach, PjFAttach);
534     gp_Pnt curpos = PjFAttach.Translated(offset.Added(Vt.Multiplied(.15)));
535     myPosition = curpos;  
536   }
537   
538   gp_Pnt Pj1 = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
539   gp_Pnt Pj2 = ElCLib::Value(ElCLib::Parameter(laxis,mySAttach),laxis);
540   if ((myFAttach.SquareDistance(Pj1)+mySAttach.SquareDistance(Pj2)) <= Precision::Confusion())  myArrowSize = 0.;
541   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
542   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
543   arr->SetLength(myArrowSize);
544   arr = la->Arrow2Aspect();
545   arr->SetLength(myArrowSize);
546   if(cu1.GetType() == GeomAbs_Line)
547     DsgPrs_SymmetricPresentation::Add(aprs,
548                                       myDrawer,
549                                       myFAttach,
550                                       mySAttach,
551                                       myFDirAttach,
552                                       laxis,
553                                       myPosition);
554   
555   if(cu1.GetType() == GeomAbs_Circle)
556     DsgPrs_SymmetricPresentation::Add(aprs,
557                                       myDrawer,
558                                       myFAttach,
559                                       mySAttach,
560                                       circ,
561                                       laxis,
562                                       myPosition);
563   if ( (myExtShape != 0) &&  !extCurv.IsNull()) {
564     gp_Pnt pf, pl;
565     if ( myExtShape == 1 ) {
566       if (!isInfinite1) {
567         pf = ptat11; 
568         pl = ptat12;
569       }
570       ComputeProjEdgePresentation(aprs,TopoDS::Edge(myFShape),geom1,pf,pl);
571     }
572     else {
573       if (!isInfinite2) {
574         pf = ptat21; 
575         pl = ptat22;
576       }
577       ComputeProjEdgePresentation(aprs,TopoDS::Edge(mySShape),geom2,pf,pl);
578     }
579   }
580 }
581
582 //=======================================================================
583 //function : ComputeTwoVertexsSymmetric
584 //purpose  : 
585 //=======================================================================
586 void AIS_SymmetricRelation::ComputeTwoVerticesSymmetric(const Handle(Prs3d_Presentation)& aprs)
587 {
588   if(myFShape.ShapeType() != TopAbs_VERTEX || mySShape.ShapeType() != TopAbs_VERTEX) return;
589   Handle(Geom_Line) geom_axis,extcurve;
590   gp_Pnt p1,p2;
591   Standard_Boolean isinfinite,isonplane;
592   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
593                             geom_axis,p1,p2,
594                             extcurve,
595                             isinfinite,
596                             isonplane,
597                             myPlane)) return;
598
599   Standard_Boolean isOnPlane1, isOnPlane2;
600
601   AIS::ComputeGeometry(TopoDS::Vertex(myFShape), myFAttach, myPlane, isOnPlane1);
602   AIS::ComputeGeometry(TopoDS::Vertex(mySShape), mySAttach, myPlane, isOnPlane2);
603
604 #ifdef BUC60915
605   if( !myArrowSizeIsDefined )
606 #endif
607     myArrowSize = myFAttach.Distance(mySAttach)/50.;
608   
609   if (isOnPlane1 && isOnPlane2)
610     myExtShape = 0;
611   else if ( isOnPlane1 && !isOnPlane2)
612     myExtShape = 2;
613   else if (!isOnPlane1 && isOnPlane2)
614     myExtShape = 1;
615   else
616     return ;
617   gp_Lin laxis (geom_axis->Lin());
618   myAxisDirAttach = laxis.Direction();
619
620   // recherche points attache
621 //  gp_Pnt curpos;
622   if (myAutomaticPosition) {    
623     gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
624     // offset pour eviter confusion Edge et Dimension
625     gp_Vec offset(myAxisDirAttach);
626     offset = offset * myArrowSize * (-5);
627     gp_Vec Vt(myFAttach, PjFAttach);
628     gp_Pnt curpos = PjFAttach.Translated(offset.Added(Vt.Multiplied(.15)));
629     myPosition = curpos;
630   }
631   if (2*(myFAttach.Distance(mySAttach)) <= Precision::Confusion()) myArrowSize = 0.;
632   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
633   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
634   arr->SetLength(myArrowSize);
635   arr = la->Arrow2Aspect();
636   arr->SetLength(myArrowSize);
637   DsgPrs_SymmetricPresentation::Add(aprs,
638                                     myDrawer,
639                                     myFAttach,
640                                     mySAttach,
641                                     laxis,
642                                     myPosition);
643   if ( myExtShape == 1)
644     ComputeProjVertexPresentation(aprs,TopoDS::Vertex(myFShape),myFAttach);
645   else if ( myExtShape == 2)
646     ComputeProjVertexPresentation(aprs,TopoDS::Vertex(mySShape),mySAttach);
647 }
648
649
650
651
652
653