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