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