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