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