8929246570a5ea74cd55543bdcadb491ec629292
[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 //=======================================================================
145 //function : Compute
146 //purpose  : to avoid warning at compilation (SUN)
147 //=======================================================================
148 void AIS_SymmetricRelation::Compute
149   (const Handle(PrsMgr_PresentationManager2d)& /*aPresentationManager2d*/,
150    const Handle(Graphic2d_GraphicObject)& /*aGraphicObject*/,
151    const Standard_Integer /*anInteger*/)
152 {
153 // Standard_NotImplemented::Raise("AIS_SymmetricRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
154 // PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
155 }
156
157 void AIS_SymmetricRelation::Compute(const Handle_Prs3d_Projector& aProjector,
158                                     const Handle_Geom_Transformation& aTransformation,
159                                     const Handle_Prs3d_Presentation& aPresentation)
160 {
161  Standard_NotImplemented::Raise("AIS_SymmetricRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
162  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
163 }
164
165 //=======================================================================
166 //function : ComputeSelection
167 //purpose  : 
168 //=======================================================================
169 void AIS_SymmetricRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSel, 
170                                              const Standard_Integer)
171 {
172   Handle(Select3D_SensitiveSegment) seg;
173   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
174   Standard_Real F,L;
175
176   Handle(Geom_Line) geom_axis,extcurve;
177   gp_Pnt p1,p2;
178   Standard_Boolean isinfinite,isonplane;
179   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
180                             geom_axis,p1,p2,
181                             extcurve,
182                             isinfinite,
183                             isonplane,
184                             myPlane)) return;
185
186   gp_Lin laxis (geom_axis->Lin());
187   
188   if(myFShape.ShapeType() != TopAbs_VERTEX){
189     BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
190     
191     if(cu1.GetType() == GeomAbs_Line) {
192 //      gp_Lin L1 (myFAttach,myFDirAttach);
193       gp_Pnt PjAttachPnt1  = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
194       gp_Pnt PjOffSetPnt   = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
195       Standard_Real h = fabs(PjOffSetPnt.Distance(PjAttachPnt1)/cos(myAxisDirAttach.Angle(myFDirAttach)));
196       gp_Vec VL1(myFDirAttach);
197       gp_Vec VLa(PjAttachPnt1,PjOffSetPnt);
198       Standard_Real scal = VL1.Dot(VLa);
199       if(scal < 0) VL1.Reverse();
200       VL1.Multiply(h);
201       gp_Pnt P1 = myFAttach.Translated(VL1);
202       gp_Pnt ProjAxis = ElCLib::Value(ElCLib::Parameter(laxis,P1),laxis);
203       gp_Vec v(P1,ProjAxis);
204       gp_Pnt P2 = ProjAxis.Translated(v);
205       
206       gp_Lin L3;
207       
208       if (!P1.IsEqual(P2,Precision::Confusion())) {
209         L3 = gce_MakeLin(P1,P2);
210       }
211       else {
212         L3 = gce_MakeLin(P1,myFDirAttach);
213         Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
214         Handle(Select3D_SensitiveBox) box =
215           new Select3D_SensitiveBox(own,
216                                     myPosition.X(),
217                                     myPosition.Y(),
218                                     myPosition.Z(),
219                                     myPosition.X()+size,
220                                     myPosition.Y()+size,
221                                     myPosition.Z()+size);
222         aSel->Add(box);
223       }
224       Standard_Real parmin,parmax,parcur;
225       parmin = ElCLib::Parameter(L3,P1);
226       parmax = parmin;
227       
228       parcur = ElCLib::Parameter(L3,P2);
229       parmin = Min(parmin,parcur);
230       parmax = Max(parmax,parcur);
231       
232       parcur = ElCLib::Parameter(L3,myPosition);
233       parmin = Min(parmin,parcur);
234       parmax = Max(parmax,parcur);
235       
236       gp_Pnt PointMin = ElCLib::Value(parmin,L3);
237       gp_Pnt PointMax = ElCLib::Value(parmax,L3);
238       
239       if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
240         seg = new Select3D_SensitiveSegment(own,
241                                             PointMin,
242                                             PointMax);
243         aSel->Add(seg);
244       }
245       if (!myFAttach.IsEqual(P1,Precision::Confusion())) {
246         seg = new Select3D_SensitiveSegment(own,
247                                             myFAttach,
248                                             P1);
249         aSel->Add(seg);
250       }
251       if (!mySAttach.IsEqual(P2,Precision::Confusion())) {
252         seg = new Select3D_SensitiveSegment(own,
253                                             mySAttach,
254                                             P2);
255         aSel->Add(seg);
256       }
257     }
258     
259     //=======================Pour les arcs======================    
260   if(cu1.GetType() == GeomAbs_Circle) { 
261     BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
262 //    Handle(Geom_Circle) geom_circ1 = (Handle(Geom_Circle)&) BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
263 //JR/Hp
264     Handle(Geom_Curve) aGeomCurve = BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
265     Handle(Geom_Circle) geom_circ1 = (Handle(Geom_Circle)&) aGeomCurve ;
266 //    Handle(Geom_Circle) geom_circ1 = (const Handle(Geom_Circle)&) BRep_Tool::Curve(TopoDS::Edge(myFShape),F,L);
267     gp_Circ circ1(geom_circ1->Circ());
268     gp_Pnt OffsetPnt(myPosition.X(),myPosition.Y(),myPosition.Z());
269     gp_Pnt Center1 = circ1.Location();
270     gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(laxis,OffsetPnt),laxis);
271     gp_Pnt ProjCenter1     = ElCLib::Value(ElCLib::Parameter(laxis,Center1),laxis);
272     gp_Vec Vp(ProjCenter1,Center1);
273     if (Vp.Magnitude() <= Precision::Confusion()) Vp = gp_Vec(laxis.Direction())^myPlane->Pln().Position().Direction();
274     Standard_Real Dt,R,h;
275     Dt = ProjCenter1.Distance(ProjOffsetPoint);
276     R  = circ1.Radius();
277     if (Dt > .999*R) {
278       Dt = .999*R;
279       gp_Vec Vout(ProjCenter1,ProjOffsetPoint);
280       ProjOffsetPoint = ProjCenter1.Translated(Vout.Divided(Vout.Magnitude()).Multiplied(Dt));
281       OffsetPnt = ProjOffsetPoint;
282     }
283     h  = Sqrt(R*R - Dt*Dt);
284     gp_Pnt P1 = ProjOffsetPoint.Translated(Vp.Added(Vp.Divided(Vp.Magnitude()).Multiplied(h)));
285     gp_Vec v(P1,ProjOffsetPoint);
286     gp_Pnt P2 = ProjOffsetPoint.Translated(v);
287     
288     gp_Lin L3;
289     if (!P1.IsEqual(P2,Precision::Confusion())) {
290       L3 = gce_MakeLin(P1,P2);
291     }
292     else {
293       L3 = gce_MakeLin(P1,laxis.Direction());
294       Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
295       Handle(Select3D_SensitiveBox) box =
296         new Select3D_SensitiveBox(own,
297                                   myPosition.X(),
298                                   myPosition.Y(),
299                                   myPosition.Z(),
300                                   myPosition.X()+size,
301                                   myPosition.Y()+size,
302                                   myPosition.Z()+size);
303       aSel->Add(box);
304     }
305     Standard_Real parmin,parmax,parcur;
306     parmin = ElCLib::Parameter(L3,P1);
307     parmax = parmin;
308     
309     parcur = ElCLib::Parameter(L3,P2);
310     parmin = Min(parmin,parcur);
311     parmax = Max(parmax,parcur);
312     
313     parcur = ElCLib::Parameter(L3,myPosition);
314     parmin = Min(parmin,parcur);
315     parmax = Max(parmax,parcur);
316     
317     gp_Pnt PointMin = ElCLib::Value(parmin,L3);
318     gp_Pnt PointMax = ElCLib::Value(parmax,L3);
319     
320     if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
321       seg = new Select3D_SensitiveSegment(own,
322                                           PointMin,
323                                           PointMax);
324       aSel->Add(seg);
325     }
326   }
327   }
328   //=======================Pour les points======================
329   else {
330     if (myFAttach.IsEqual(mySAttach,Precision::Confusion())) {
331       seg = new Select3D_SensitiveSegment(own,myPosition,myFAttach);
332       aSel->Add(seg);
333     }
334     else{
335       gp_Pnt ProjOffsetPoint      = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
336       gp_Pnt ProjAttachmentPoint1 = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
337       gp_Vec PjAtt1_Att1(ProjAttachmentPoint1,myFAttach);
338       gp_Pnt P1 = ProjOffsetPoint.Translated(PjAtt1_Att1);
339       gp_Pnt P2 = ProjOffsetPoint.Translated(PjAtt1_Att1.Reversed());
340       gp_Lin L3;
341       
342       if (!P1.IsEqual(P2,Precision::Confusion())) {
343         L3 = gce_MakeLin(P1,P2);
344       }
345       else {
346         L3 = gce_MakeLin(P1,myFDirAttach);
347         Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
348         Handle(Select3D_SensitiveBox) box =
349           new Select3D_SensitiveBox(own,
350                                     myPosition.X(),
351                                     myPosition.Y(),
352                                     myPosition.Z(),
353                                     myPosition.X()+size,
354                                     myPosition.Y()+size,
355                                     myPosition.Z()+size);
356         aSel->Add(box);
357       }
358       Standard_Real parmin,parmax,parcur;
359       parmin = ElCLib::Parameter(L3,P1);
360       parmax = parmin;
361       
362       parcur = ElCLib::Parameter(L3,P2);
363       parmin = Min(parmin,parcur);
364       parmax = Max(parmax,parcur);
365       
366       parcur = ElCLib::Parameter(L3,myPosition);
367       parmin = Min(parmin,parcur);
368       parmax = Max(parmax,parcur);
369       
370       gp_Pnt PointMin = ElCLib::Value(parmin,L3);
371       gp_Pnt PointMax = ElCLib::Value(parmax,L3);
372       
373       if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
374         seg = new Select3D_SensitiveSegment(own,PointMin,PointMax);
375         aSel->Add(seg);
376       }
377       if (!myFAttach.IsEqual(P1,Precision::Confusion())) {
378         seg = new Select3D_SensitiveSegment(own,myFAttach,P1);
379         aSel->Add(seg);
380       }
381       if (!mySAttach.IsEqual(P2,Precision::Confusion())) {
382         seg = new Select3D_SensitiveSegment(own,mySAttach,P2);
383         aSel->Add(seg);
384       }
385     }
386   }
387 }
388
389 //=======================================================================
390 //function : ComputeTwoFacesSymmetric
391 //purpose  : 
392 //=======================================================================
393 void AIS_SymmetricRelation::ComputeTwoFacesSymmetric(const Handle(Prs3d_Presentation)&)
394 {
395 }
396
397 //=======================================================================
398 //function : ComputeTwoEdgesSymmetric
399 //purpose  : 
400 //=======================================================================
401 void AIS_SymmetricRelation::ComputeTwoEdgesSymmetric(const Handle(Prs3d_Presentation)& aprs)
402 {
403   BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
404   if (cu1.GetType() != GeomAbs_Line && cu1.GetType() != GeomAbs_Circle) return;
405   BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
406   if (cu2.GetType() != GeomAbs_Line && cu2.GetType() != GeomAbs_Circle) return;
407 //  gp_Pnt pint3d,ptat11,ptat12,ptat21,ptat22;
408   gp_Pnt ptat11,ptat12,ptat21,ptat22;
409   Handle(Geom_Curve) geom1,geom2;
410   Standard_Boolean isInfinite1,isInfinite2;
411   Handle(Geom_Curve) extCurv;
412   if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
413                             TopoDS::Edge(mySShape),
414                             myExtShape,
415                             geom1,
416                             geom2,
417                             ptat11,
418                             ptat12,
419                             ptat21,
420                             ptat22,
421                             extCurv,
422                             isInfinite1,isInfinite2,
423                             myPlane)) {
424     return;
425   } 
426   aprs->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape !=0));
427   Handle(Geom_Line) geom_axis,extcurve;
428   gp_Pnt p1,p2;
429   Standard_Boolean isinfinite,isonplane;
430   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
431                             geom_axis,p1,p2,
432                             extcurve,
433                             isinfinite,
434                             isonplane,
435                             myPlane)) return;
436
437   gp_Lin laxis (geom_axis->Lin());
438   myAxisDirAttach = laxis.Direction();
439
440   if(cu1.GetType() == GeomAbs_Line){
441     const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
442     gp_Lin l1(geom_lin1->Lin());
443     myFDirAttach = l1.Direction();
444   }
445   gp_Circ circ;
446   if(cu1.GetType() == GeomAbs_Circle){
447     const Handle(Geom_Circle)& geom_cir1 = (Handle(Geom_Circle)&) geom1;
448     gp_Circ c(geom_cir1->Circ());
449     circ = c;
450   }
451   
452   // recherche points attache
453   gp_Pnt ProjOffset = ElCLib::Value(ElCLib::Parameter(laxis,myPosition),laxis);
454   
455 /*//----------------------------------------------------
456   //Quand on fait la symetrie de 2 edges consecutifs:
457   //              
458   //              :<-- Axe
459   //              :
460   //             /:\
461   // Edge n --->/ : \
462   //           /  :  \<-- Edge n+1
463   //              :
464   //----------------------------------------------------
465 */
466   Standard_Boolean idem = Standard_False;
467   if (isInfinite1 && isInfinite2) { // geom1 et geom2 sont des lignes
468     const gp_Lin& line2 = ((Handle(Geom_Line)&) geom2)->Lin();
469     if (myAutomaticPosition) {
470       myFAttach = ((Handle(Geom_Line)&) geom1)->Lin().Location();      
471       mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
472     }
473     else {
474       const gp_Lin& line1 = ((Handle(Geom_Line)&) geom1)->Lin();
475       myFAttach = ElCLib::Value(ElCLib::Parameter(line1,myPosition),line1);
476       mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
477     }
478   }
479   else if (!isInfinite1 && !isInfinite2) {
480     if (ptat11.IsEqual(ptat21,Precision::Confusion())) {
481       myFAttach = ptat12;
482       mySAttach = ptat22;
483       idem = Standard_True;
484     }
485     if (ptat11.IsEqual(ptat22,Precision::Confusion())) {
486       myFAttach = ptat12;
487       mySAttach = ptat21;
488       idem = Standard_True;
489     }
490     if (ptat12.IsEqual(ptat21,Precision::Confusion())) {
491       myFAttach = ptat11;
492       mySAttach = ptat22;
493       idem = Standard_True;
494     }
495     if (ptat12.IsEqual(ptat22,Precision::Confusion())) {
496       myFAttach = ptat11;
497       mySAttach = ptat21;
498       idem = Standard_True;
499     }
500     if(!idem){
501       if( ProjOffset.SquareDistance(ptat11) > ProjOffset.SquareDistance(ptat12)) myFAttach = ptat12;
502       else myFAttach = ptat11;
503       
504       if (ProjOffset.SquareDistance(ptat21) > ProjOffset.SquareDistance(ptat22)) mySAttach = ptat22;
505       else mySAttach = ptat21;
506     }
507   }
508   else if (isInfinite1) {// geom1 et geom2 sont des lignes
509     mySAttach = ptat21;
510     const gp_Lin& line1 = ((Handle(Geom_Line)&) geom1)->Lin();
511     myFAttach = ElCLib::Value(ElCLib::Parameter(line1,mySAttach),line1);
512   }
513   else if (isInfinite2) {// geom1 et geom2 sont des lignes
514     myFAttach = ptat11;
515     const gp_Lin& line2 = ((Handle(Geom_Line)&) geom2)->Lin();
516     mySAttach = ElCLib::Value(ElCLib::Parameter(line2,myFAttach),line2);
517   }
518
519 #ifdef BUC60915
520   if( !myArrowSizeIsDefined )
521 #endif
522     myArrowSize = myFAttach.Distance(mySAttach)/50.;
523   //----------------------------------------------------
524  
525   //----------------------------------------------------
526   // Si myFAttach <> mySAttach et PjFAttach = myFAttach
527   //----------------------------------------------------
528   gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
529  
530   if (PjFAttach.IsEqual(myFAttach,Precision::Confusion())){
531     const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
532     gp_Lin l2(geom_lin2->Lin());
533     myFDirAttach = l2.Direction();
534     gp_Pnt PntTempo;
535     PntTempo  = myFAttach;
536     myFAttach = mySAttach;
537     mySAttach = PntTempo;
538     PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
539   }
540   
541   //----------------------------------------------------
542 //  gp_Pnt curpos;
543
544   if (myAutomaticPosition) {    
545     //gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
546     // offset pour eviter confusion Edge et Dimension
547     gp_Vec offset(myAxisDirAttach);
548     offset = offset * myArrowSize * (-5);
549     gp_Vec Vt(myFAttach, PjFAttach);
550     gp_Pnt curpos = PjFAttach.Translated(offset.Added(Vt.Multiplied(.15)));
551     myPosition = curpos;  
552   }
553   
554   gp_Pnt Pj1 = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis);
555   gp_Pnt Pj2 = ElCLib::Value(ElCLib::Parameter(laxis,mySAttach),laxis);
556   if ((myFAttach.SquareDistance(Pj1)+mySAttach.SquareDistance(Pj2)) <= Precision::Confusion())  myArrowSize = 0.;
557   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
558   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
559   arr->SetLength(myArrowSize);
560   arr = la->Arrow2Aspect();
561   arr->SetLength(myArrowSize);
562   if(cu1.GetType() == GeomAbs_Line)
563     DsgPrs_SymmetricPresentation::Add(aprs,
564                                       myDrawer,
565                                       myFAttach,
566                                       mySAttach,
567                                       myFDirAttach,
568                                       laxis,
569                                       myPosition);
570   
571   if(cu1.GetType() == GeomAbs_Circle)
572     DsgPrs_SymmetricPresentation::Add(aprs,
573                                       myDrawer,
574                                       myFAttach,
575                                       mySAttach,
576                                       circ,
577                                       laxis,
578                                       myPosition);
579   if ( (myExtShape != 0) &&  !extCurv.IsNull()) {
580     gp_Pnt pf, pl;
581     if ( myExtShape == 1 ) {
582       if (!isInfinite1) {
583         pf = ptat11; 
584         pl = ptat12;
585       }
586       ComputeProjEdgePresentation(aprs,TopoDS::Edge(myFShape),geom1,pf,pl);
587     }
588     else {
589       if (!isInfinite2) {
590         pf = ptat21; 
591         pl = ptat22;
592       }
593       ComputeProjEdgePresentation(aprs,TopoDS::Edge(mySShape),geom2,pf,pl);
594     }
595   }
596 }
597
598 //=======================================================================
599 //function : ComputeTwoVertexsSymmetric
600 //purpose  : 
601 //=======================================================================
602 void AIS_SymmetricRelation::ComputeTwoVerticesSymmetric(const Handle(Prs3d_Presentation)& aprs)
603 {
604   if(myFShape.ShapeType() != TopAbs_VERTEX || mySShape.ShapeType() != TopAbs_VERTEX) return;
605   Handle(Geom_Line) geom_axis,extcurve;
606   gp_Pnt p1,p2;
607   Standard_Boolean isinfinite,isonplane;
608   if (!AIS::ComputeGeometry(TopoDS::Edge(myTool),
609                             geom_axis,p1,p2,
610                             extcurve,
611                             isinfinite,
612                             isonplane,
613                             myPlane)) return;
614
615   Standard_Boolean isOnPlane1, isOnPlane2;
616
617   AIS::ComputeGeometry(TopoDS::Vertex(myFShape), myFAttach, myPlane, isOnPlane1);
618   AIS::ComputeGeometry(TopoDS::Vertex(mySShape), mySAttach, myPlane, isOnPlane2);
619
620 #ifdef BUC60915
621   if( !myArrowSizeIsDefined )
622 #endif
623     myArrowSize = myFAttach.Distance(mySAttach)/50.;
624   
625   if (isOnPlane1 && isOnPlane2)
626     myExtShape = 0;
627   else if ( isOnPlane1 && !isOnPlane2)
628     myExtShape = 2;
629   else if (!isOnPlane1 && isOnPlane2)
630     myExtShape = 1;
631   else
632     return ;
633   gp_Lin laxis (geom_axis->Lin());
634   myAxisDirAttach = laxis.Direction();
635
636   // recherche points attache
637 //  gp_Pnt curpos;
638   if (myAutomaticPosition) {    
639     gp_Pnt PjFAttach = ElCLib::Value(ElCLib::Parameter(laxis,myFAttach),laxis); 
640     // offset pour eviter confusion Edge et Dimension
641     gp_Vec offset(myAxisDirAttach);
642     offset = offset * myArrowSize * (-5);
643     gp_Vec Vt(myFAttach, PjFAttach);
644     gp_Pnt curpos = PjFAttach.Translated(offset.Added(Vt.Multiplied(.15)));
645     myPosition = curpos;
646   }
647   if (2*(myFAttach.Distance(mySAttach)) <= Precision::Confusion()) myArrowSize = 0.;
648   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
649   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
650   arr->SetLength(myArrowSize);
651   arr = la->Arrow2Aspect();
652   arr->SetLength(myArrowSize);
653   DsgPrs_SymmetricPresentation::Add(aprs,
654                                     myDrawer,
655                                     myFAttach,
656                                     mySAttach,
657                                     laxis,
658                                     myPosition);
659   if ( myExtShape == 1)
660     ComputeProjVertexPresentation(aprs,TopoDS::Vertex(myFShape),myFAttach);
661   else if ( myExtShape == 2)
662     ComputeProjVertexPresentation(aprs,TopoDS::Vertex(mySShape),mySAttach);
663 }
664
665
666
667
668
669