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