0031459: Visualization, AIS_TextLabel - add missing getters
[occt.git] / src / AIS / AIS_EqualDistanceRelation.cxx
1 // Created on: 1998-01-24
2 // Created by: Julia GERASIMOVA
3 // Copyright (c) 1998-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_EqualDistanceRelation.hxx>
19 #include <AIS_LengthDimension.hxx>
20 #include <Bnd_Box.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve.hxx>
23 #include <BRepBuilderAPI_MakeEdge.hxx>
24 #include <BRepBuilderAPI_MakeVertex.hxx>
25 #include <DsgPrs_EqualDistancePresentation.hxx>
26 #include <ElCLib.hxx>
27 #include <Geom_Circle.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_Transformation.hxx>
31 #include <GeomAPI_ProjectPointOnCurve.hxx>
32 #include <GeomAPI_ProjectPointOnSurf.hxx>
33 #include <gp_Lin.hxx>
34 #include <gp_Pnt.hxx>
35 #include <Precision.hxx>
36 #include <Prs3d_ArrowAspect.hxx>
37 #include <Prs3d_DimensionAspect.hxx>
38 #include <Prs3d_Drawer.hxx>
39 #include <Prs3d_Presentation.hxx>
40 #include <Select3D_SensitiveBox.hxx>
41 #include <Select3D_SensitiveCircle.hxx>
42 #include <Select3D_SensitiveSegment.hxx>
43 #include <SelectMgr_EntityOwner.hxx>
44 #include <Standard_NotImplemented.hxx>
45 #include <Standard_Type.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Vertex.hxx>
49
50 IMPLEMENT_STANDARD_RTTIEXT(AIS_EqualDistanceRelation,AIS_Relation)
51
52 //=======================================================================
53 //function : AIS_EqualDistanceRelation
54 //purpose  : 
55 //=======================================================================
56 AIS_EqualDistanceRelation::AIS_EqualDistanceRelation( const TopoDS_Shape& aShape1,
57                                                       const TopoDS_Shape& aShape2,
58                                                       const TopoDS_Shape& aShape3,
59                                                       const TopoDS_Shape& aShape4,
60                                                       const Handle( Geom_Plane )& aPlane )
61      :AIS_Relation()
62 {
63   myFShape = aShape1;
64   mySShape = aShape2;
65   myShape3 = aShape3;
66   myShape4 = aShape4;
67   myPlane  = aPlane;
68
69   //Temporary
70   myArrowSize = 3.0; //set the concrete value
71   mySymbolPrs = DsgPrs_AS_BOTHAR;
72 }
73
74 //=======================================================================
75 //function : Compute
76 //purpose  : 
77 //=======================================================================
78
79 void AIS_EqualDistanceRelation::Compute( const Handle( PrsMgr_PresentationManager3d )&,
80                                          const Handle( Prs3d_Presentation )& aPresentation,
81                                          const Standard_Integer ) 
82 {
83   gp_Pnt Position12 =  myPosition, Position34 = myPosition;
84
85   Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
86   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
87   arr->SetLength(myArrowSize);
88 // -- ota -- begin
89   if (!myAutomaticPosition ){
90     gp_Pnt aMiddle12 ((myPoint1.XYZ() + myPoint2.XYZ())*0.5);
91     gp_Pnt aMiddle34 ((myPoint3.XYZ() + myPoint4.XYZ())*0.5);
92
93     if (myPosition.Distance(aMiddle12) > myPosition.Distance(aMiddle34))
94       Position12.SetXYZ((myPoint1.XYZ() + myPoint2.XYZ())*0.5);
95     else        
96       Position34.SetXYZ((myPoint3.XYZ() + myPoint4.XYZ())*0.5);
97
98   }
99   
100   if (myFShape.ShapeType() == TopAbs_EDGE && mySShape.ShapeType() == TopAbs_EDGE)
101     AIS_EqualDistanceRelation::ComputeTwoEdgesLength(aPresentation,
102                                                      myDrawer,
103                                                      myArrowSize,
104                                                      TopoDS::Edge(myFShape),
105                                                      TopoDS::Edge(mySShape),
106                                                      myPlane,
107                                                      myAutomaticPosition,
108                                                      myIsSetBndBox,
109                                                      myBndBox,
110                                                      Position12,
111                                                      myAttachPoint1,
112                                                      myAttachPoint2,
113                                                      myPoint1,
114                                                      myPoint2,
115                                                      mySymbolPrs );
116          
117   
118   else if (myFShape.ShapeType() == TopAbs_VERTEX && mySShape.ShapeType() == TopAbs_VERTEX)
119     AIS_EqualDistanceRelation::ComputeTwoVerticesLength( aPresentation,
120                                                         myDrawer,
121                                                         myArrowSize,
122                                                         TopoDS::Vertex(myFShape),
123                                                         TopoDS::Vertex(mySShape),
124                                                         myPlane,
125                                                         myAutomaticPosition,
126                                                         myIsSetBndBox,
127                                                         myBndBox,
128                                                         AIS_TOD_Unknown,
129                                                         Position12,
130                                                         myAttachPoint1,
131                                                         myAttachPoint2,
132                                                         myPoint1,
133                                                         myPoint2,
134                                                         mySymbolPrs );
135   else 
136     AIS_EqualDistanceRelation::ComputeOneEdgeOneVertexLength( aPresentation,
137                                                              myDrawer,
138                                                              myArrowSize,
139                                                              myFShape,
140                                                              mySShape,
141                                                              myPlane,
142                                                              myAutomaticPosition,
143                                                              myIsSetBndBox,
144                                                              myBndBox,
145                                                              Position12,
146                                                              myAttachPoint1,
147                                                              myAttachPoint2,
148                                                              myPoint1,
149                                                              myPoint2,
150                                                              mySymbolPrs );
151
152   if (myShape3.ShapeType() == TopAbs_EDGE && myShape4.ShapeType() == TopAbs_EDGE)
153     AIS_EqualDistanceRelation::ComputeTwoEdgesLength(aPresentation,
154                                                      myDrawer,
155                                                      myArrowSize,
156                                                      TopoDS::Edge(myShape3),
157                                                      TopoDS::Edge(myShape4),
158                                                      myPlane,
159                                                      myAutomaticPosition,
160                                                      myIsSetBndBox,
161                                                      myBndBox,
162                                                      Position34,
163                                                      myAttachPoint3,
164                                                      myAttachPoint4,
165                                                      myPoint3,
166                                                      myPoint4,
167                                                      mySymbolPrs );
168   
169   else if (myShape3.ShapeType() == TopAbs_VERTEX && myShape4.ShapeType() == TopAbs_VERTEX)
170     AIS_EqualDistanceRelation::ComputeTwoVerticesLength( aPresentation,
171                                                         myDrawer,
172                                                         myArrowSize,
173                                                         TopoDS::Vertex(myShape3),
174                                                         TopoDS::Vertex(myShape4),
175                                                         myPlane,
176                                                         myAutomaticPosition,
177                                                         myIsSetBndBox,
178                                                         myBndBox,
179                                                         AIS_TOD_Unknown,
180                                                         Position34,
181                                                         myAttachPoint3,
182                                                         myAttachPoint4,
183                                                         myPoint3,
184                                                         myPoint4,
185                                                         mySymbolPrs );
186    
187   else
188     AIS_EqualDistanceRelation::ComputeOneEdgeOneVertexLength( aPresentation,
189                                                              myDrawer,
190                                                              myArrowSize,
191                                                              myShape3,
192                                                              myShape4,
193                                                              myPlane,
194                                                              myAutomaticPosition,
195                                                              myIsSetBndBox,
196                                                              myBndBox,
197                                                              Position34,
198                                                              myAttachPoint3,
199                                                              myAttachPoint4,
200                                                              myPoint3,
201                                                              myPoint4,
202                                                              mySymbolPrs );
203   
204   DsgPrs_EqualDistancePresentation::Add( aPresentation, myDrawer, 
205                                         myPoint1, myPoint2, myPoint3, myPoint4, myPlane );
206 }
207
208 //=======================================================================
209 //function : ComputeSelection
210 //purpose  : 
211 //=======================================================================
212
213 void AIS_EqualDistanceRelation::ComputeSelection( const Handle( SelectMgr_Selection )& aSelection,
214                                                   const Standard_Integer ) 
215 {
216   Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
217   Handle( Select3D_SensitiveSegment ) seg;
218
219   seg = new Select3D_SensitiveSegment( own, myPoint1, myPoint2 );
220   aSelection->Add( seg );
221
222   seg = new Select3D_SensitiveSegment( own, myPoint3, myPoint4 );
223   aSelection->Add( seg );
224
225   // Line between two middles
226   gp_Pnt Middle12( (myPoint1.XYZ() + myPoint2.XYZ()) * 0.5 ), 
227          Middle34( (myPoint3.XYZ() + myPoint4.XYZ()) *0.5 );
228   seg = new Select3D_SensitiveSegment( own, Middle12, Middle34 );
229   aSelection->Add( seg );
230
231   gp_Pnt Middle((Middle12.XYZ() +  Middle34.XYZ())*0.5);
232   Standard_Real SmallDist = .001;
233   Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
234                                                                   Middle.X() - SmallDist,
235                                                                   Middle.Y() - SmallDist,
236                                                                   Middle.Z() - SmallDist,
237                                                                   Middle.X() + SmallDist,
238                                                                   Middle.Y() + SmallDist,
239                                                                   Middle.Z() + SmallDist );
240   aSelection->Add(box);
241
242   if (myFShape.ShapeType() == TopAbs_EDGE){
243     BRepAdaptor_Curve aCurve(TopoDS::Edge(myFShape));
244     if (aCurve.GetType() == GeomAbs_Line){
245         //add sensetive element - line
246       seg = new Select3D_SensitiveSegment( own, myAttachPoint1, myPoint1);
247       aSelection->Add( seg );
248     }
249     else if (aCurve.GetType() == GeomAbs_Circle){
250       Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
251       Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint1),
252                     LastPar  = ElCLib::Parameter(aCircle->Circ(), myPoint1);
253       if (LastPar < FirstPar ) LastPar+=M_PI*2;
254       //add sensetive arc
255       Handle(Select3D_SensitiveCircle) circ = 
256         new Select3D_SensitiveCircle( own, aCircle,  FirstPar, LastPar);
257       aSelection->Add( circ );
258     }
259   }
260   else {
261       seg = new Select3D_SensitiveSegment( own, myAttachPoint1, myPoint1);
262       aSelection->Add( seg );
263     }
264   
265   if (mySShape.ShapeType() == TopAbs_EDGE){
266     BRepAdaptor_Curve aCurve(TopoDS::Edge(mySShape));
267     if (aCurve.GetType() == GeomAbs_Line) {
268       //add sensetive element - line
269       seg = new Select3D_SensitiveSegment( own, myAttachPoint2, myPoint2);
270       aSelection->Add( seg );
271     }
272     else if (aCurve.GetType() == GeomAbs_Circle){
273       Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
274       Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint2),
275       LastPar  = ElCLib::Parameter(aCircle->Circ(), myPoint2);
276       if (LastPar < FirstPar ) LastPar+=M_PI*2;
277       //add sensetive arc
278       Handle(Select3D_SensitiveCircle) circ = 
279         new Select3D_SensitiveCircle( own,aCircle,  FirstPar, LastPar);
280       aSelection->Add( circ );
281     }
282   }
283   else {
284     seg = new Select3D_SensitiveSegment( own, myAttachPoint2, myPoint2);
285     aSelection->Add( seg );
286   }
287     
288   if (myShape3.ShapeType() == TopAbs_EDGE){
289     BRepAdaptor_Curve aCurve(TopoDS::Edge(myShape3));
290     if (aCurve.GetType() == GeomAbs_Line) {
291       //add sensetive element - line
292       seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
293       aSelection->Add( seg );
294     }
295     else if (aCurve.GetType() == GeomAbs_Circle){
296       Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
297       Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint3),
298       LastPar  = ElCLib::Parameter(aCircle->Circ(), myPoint3);
299       if (LastPar < FirstPar ) LastPar+=M_PI*2;
300       Handle(Select3D_SensitiveCircle) circ = 
301         new Select3D_SensitiveCircle( own, aCircle,  FirstPar, LastPar);
302       aSelection->Add( circ );
303     }
304     else {
305       seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
306       aSelection->Add( seg );
307     }
308   }
309   else {
310     seg = new Select3D_SensitiveSegment( own, myAttachPoint3, myPoint3);
311     aSelection->Add( seg );
312   }
313
314   if (myShape4.ShapeType() == TopAbs_EDGE){
315     BRepAdaptor_Curve aCurve(TopoDS::Edge(myShape4));
316     if (aCurve.GetType() == GeomAbs_Line) {
317       //add sensetive element - line
318       seg = new Select3D_SensitiveSegment( own, myAttachPoint4, myPoint4);
319       aSelection->Add( seg );
320     }
321     else if (aCurve.GetType() == GeomAbs_Circle){
322       Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve.Curve().Curve());
323       Standard_Real FirstPar = ElCLib::Parameter(aCircle->Circ(), myAttachPoint4),
324       LastPar  = ElCLib::Parameter(aCircle->Circ(), myPoint4);
325       if (LastPar < FirstPar ) LastPar+=M_PI*2;
326       //add sensetive arc
327       Handle(Select3D_SensitiveCircle) circ = 
328         new Select3D_SensitiveCircle( own,aCircle,  FirstPar, LastPar);
329       aSelection->Add( circ );
330     }
331   }
332   else {
333     seg = new Select3D_SensitiveSegment( own, myAttachPoint4, myPoint4);
334     aSelection->Add( seg );
335   }
336 }
337
338 //=======================================================================
339 //function : ComputeTwoEdgesLength
340 //purpose  : 
341 //=======================================================================
342 void AIS_EqualDistanceRelation::ComputeTwoEdgesLength( const Handle( Prs3d_Presentation )& aPresentation,
343                                                       const Handle( Prs3d_Drawer )& aDrawer,
344                                                       const Standard_Real ArrowSize,
345                                                       const TopoDS_Edge & FirstEdge,
346                                                       const TopoDS_Edge & SecondEdge,
347                                                       const Handle( Geom_Plane )& Plane,
348                                                       const Standard_Boolean AutomaticPos,
349                                                       const Standard_Boolean IsSetBndBox,
350                                                       const Bnd_Box & BndBox,
351                                                       gp_Pnt& Position,
352                                                       gp_Pnt& FirstAttach,
353                                                       gp_Pnt& SecondAttach,
354                                                       gp_Pnt& FirstExtreme,
355                                                       gp_Pnt& SecondExtreme, 
356                                                       DsgPrs_ArrowSide & SymbolPrs )
357
358   gp_Dir DirAttach;
359   BRepAdaptor_Curve cu1( FirstEdge );
360   BRepAdaptor_Curve cu2( SecondEdge );
361   
362   // 3d lines
363   Handle(Geom_Curve) geom1,geom2;
364   gp_Pnt ptat11,ptat12,ptat21,ptat22;
365   
366   Standard_Boolean isInfinite1(Standard_False),isInfinite2(Standard_False);
367   Handle(Geom_Curve) extCurv;
368   Standard_Real arrsize = ArrowSize;// size
369   Standard_Real Val=0.;
370   Standard_Boolean isInPlane1, isInPlane2;
371
372   if(!AIS::ComputeGeometry(FirstEdge,geom1, ptat11, ptat12,extCurv,isInfinite1,isInPlane1, Plane ))
373     return;
374   if(!AIS::ComputeGeometry(SecondEdge, geom2, ptat21, ptat22, extCurv, isInfinite2,isInPlane2, Plane))
375     return;
376   
377   aPresentation->SetInfiniteState(isInfinite1 || isInfinite2);
378   
379   if (cu1.GetType() == GeomAbs_Line && cu2.GetType() == GeomAbs_Line) 
380     {
381       Handle(Geom_Line) geom_lin1 (Handle(Geom_Line)::DownCast (geom1));
382       Handle(Geom_Line) geom_lin2 (Handle(Geom_Line)::DownCast (geom2));
383       const gp_Lin& l1 = geom_lin1->Lin();
384       const gp_Lin& l2 = geom_lin2->Lin();
385       
386       //Get Val value
387       Val = l1.Distance( l2 );
388       
389       DirAttach = l1.Direction();
390       
391       if (AutomaticPos) {
392         // compute position of offset point
393         gp_Pnt curpos;
394         Standard_Real par1=0., par2=0.;
395         if(!(isInfinite1 || isInfinite2))
396           {
397             par1 = ElCLib::Parameter(l1,ptat11);
398             par2 = ElCLib::Parameter(l1,ptat21);
399             if (par1 <par2){//project ptat11 on l2
400               gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
401               curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())*0.5);
402             }
403             else {//project ptat21 on l1
404               gp_Pnt p2 = ElCLib::Value(par2, l1);
405               curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())*0.5);
406             }
407           }
408         else if (!isInfinite1){
409           par2 = ElCLib::Parameter(l1,ptat21);
410           gp_Pnt p2 = ElCLib::Value(par2,l1);
411           curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
412         }
413         else if (!isInfinite2) {
414           gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
415           curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())*0.5);
416         }
417         else   
418           curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())*0.5);
419  
420     // compute  offset
421     gp_Vec offset(DirAttach);
422     offset = offset*ArrowSize*(-10.);
423     curpos.Translate(offset);
424     Position = curpos;
425   }
426   else {    // project point on the plane
427     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
428   }
429
430   // find attach points
431   if (!isInfinite1) {
432     if (Position.Distance(ptat11) > Position.Distance(ptat12)) FirstAttach = ptat12;
433     else FirstAttach = ptat11;
434   }
435   else {
436     FirstAttach = ElCLib::Value(ElCLib::Parameter(l1,Position),l1);
437   }
438   
439   if (!isInfinite2) {
440     if (Position.Distance(ptat21) > Position.Distance(ptat22)) SecondAttach = ptat22;
441     else SecondAttach = ptat21;
442   }
443   else {
444     SecondAttach = ElCLib::Value(ElCLib::Parameter(l2,Position),l2);
445   }
446
447   Standard_Real confusion(Precision::Confusion());
448   if (arrsize < confusion) arrsize = Val*0.1;
449   if (Abs(Val) <= confusion) {arrsize = 0.;}
450
451   Handle(Prs3d_DimensionAspect) la = aDrawer->DimensionAspect();
452   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();  
453   arr->SetLength(arrsize);
454   arr = la->ArrowAspect();
455   arr->SetLength(arrsize);
456
457   if (AutomaticPos && IsSetBndBox)
458     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
459  
460    DsgPrs_EqualDistancePresentation::AddInterval(aPresentation,
461                                                 aDrawer,
462                                                 FirstAttach,
463                                                 SecondAttach,
464                                                 DirAttach,
465                                                 Position,
466                                                 SymbolPrs,
467                                                 FirstExtreme,
468                                                 SecondExtreme);
469                                                 
470       
471 }
472   if (cu1.GetType() == GeomAbs_Circle && cu2.GetType() == GeomAbs_Circle){
473     //Get first and last points of circles
474     Handle(Geom_Circle) aCir1 (Handle(Geom_Circle)::DownCast(geom1));
475     Handle(Geom_Circle) aCir2 (Handle(Geom_Circle)::DownCast(geom2));
476     gp_Circ aCirc1 = aCir1->Circ();
477     gp_Circ aCirc2 = aCir2->Circ();
478
479     //To avoid circles with different orientaion
480     Standard_Real aTol = Precision::Confusion();
481     if(aCirc2.Axis().IsOpposite(aCirc1.Axis(), aTol) ||
482        aCirc2.XAxis().IsOpposite(aCirc1.XAxis(), aTol) || 
483        aCirc2.YAxis().IsOpposite(aCirc1.YAxis(), aTol) )
484       {
485         aCirc2.SetPosition(aCirc1.Position());
486         aCirc2.SetAxis(aCirc1.Axis());
487       }
488     
489     if (AutomaticPos){ 
490       Standard_Real par1 = 0, par2 = 0;
491       gp_Pln aPln =  Plane->Pln();
492       //Project ptat12 and ptat22 on constraint plane
493       gp_Pnt PrPnt12 = AIS::ProjectPointOnPlane(ptat12, aPln);
494       gp_Pnt PrPnt22 = AIS::ProjectPointOnPlane(ptat22, aPln);
495       //Project circles center on constraint plane
496       gp_Pnt PrCenter = AIS::ProjectPointOnPlane(aCirc1.Location(), aPln);
497
498       gp_Dir XDir = aPln.XAxis().Direction();
499       gp_Dir YDir = aPln.YAxis().Direction();
500       
501       
502       if (PrPnt12.Distance(PrCenter) >Precision::Confusion())
503         {
504           gp_Dir aDir1(PrPnt12.XYZ() - PrCenter.XYZ());
505           Standard_Real anAngle = aDir1.Angle(XDir); //Get the angle in range [0, M_PI]
506           if (aDir1.Dot(YDir) < 0)
507             anAngle = 2 * M_PI - anAngle;
508           par1 = anAngle;
509         }
510       
511       if (PrPnt22.Distance(PrCenter) >Precision::Confusion())
512         {
513           gp_Dir aDir2(PrPnt22.XYZ() - PrCenter.XYZ());
514           Standard_Real anAngle = aDir2.Angle(XDir); //Get the angle in range [0, M_PI]
515           if (aDir2.Dot(YDir) < 0)
516             anAngle = 2 * M_PI - anAngle;
517           par2 = anAngle;
518         }
519       
520       
521       if(par1 > par2 ){
522         FirstExtreme = ptat12;
523         Standard_Real aPar1 = ElCLib::Parameter(aCirc2, ptat12);
524         SecondExtreme = ElCLib::Value(aPar1, aCirc2);
525       }
526       else {
527         Standard_Real aPar2 =  ElCLib::Parameter(aCirc1, ptat22);
528         FirstExtreme = ElCLib::Value(aPar2, aCirc1);
529         SecondExtreme = ptat22;
530       }
531     }
532     else {
533       Standard_Real pospar = ElCLib::Parameter(aCirc1, Position);
534       FirstExtreme  =  ElCLib::Value(pospar, aCirc1);
535       pospar = ElCLib::Parameter(aCirc2, Position);
536       SecondExtreme =  ElCLib::Value(pospar, aCirc2);
537     }
538
539     DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(aPresentation,
540                                                                 aDrawer,
541                                                                 aCirc1,
542                                                                 aCirc2,
543                                                                 ptat12,
544                                                                 FirstExtreme, 
545                                                                 ptat22,
546                                                                 SecondExtreme,
547                                                                 SymbolPrs);
548     
549     FirstAttach = ptat12; SecondAttach = ptat22; //assign attach points
550     Position.SetXYZ( (FirstAttach.XYZ() + SecondAttach.XYZ())*0.5);
551   }
552
553   if (arrsize < Precision::Confusion()) arrsize = Val*0.1;
554   if (Abs(Val) <=  Precision::Confusion()) {arrsize = 0.;}
555
556 //  gp_Pnt pf, pl;
557   if (!isInPlane1) {
558     AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, FirstEdge, geom1, ptat11, ptat12);
559   }
560   if(!isInPlane2) {
561     AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, SecondEdge, geom2, ptat21, ptat22);
562   }
563 }
564
565 //=======================================================================
566 //function : ComputeTwoVerticesLength
567 //purpose  : 
568 //=======================================================================
569
570 void AIS_EqualDistanceRelation::ComputeTwoVerticesLength( const Handle( Prs3d_Presentation )& aPresentation,
571                                                          const Handle( Prs3d_Drawer )& aDrawer,
572                                                          const Standard_Real ArrowSize,
573                                                          const TopoDS_Vertex& FirstVertex,
574                                                          const TopoDS_Vertex& SecondVertex,
575                                                          const Handle( Geom_Plane )& Plane,
576                                                          const Standard_Boolean AutomaticPos,
577                                                          const Standard_Boolean IsSetBndBox,
578                                                          const Bnd_Box& BndBox,
579                                                          const AIS_TypeOfDist TypeDist,
580                                                          gp_Pnt& Position,
581                                                          gp_Pnt& FirstAttach,
582                                                          gp_Pnt& SecondAttach,
583                                                          gp_Pnt& FirstExtreme,
584                                                          gp_Pnt& SecondExtreme, 
585                                                          DsgPrs_ArrowSide& SymbolPrs )
586 {
587   Standard_Boolean isOnPlane1, isOnPlane2;
588   gp_Dir DirAttach;
589   AIS::ComputeGeometry( FirstVertex, FirstAttach, Plane, isOnPlane1);
590   AIS::ComputeGeometry( SecondVertex, SecondAttach, Plane, isOnPlane2);
591
592   Standard_Real confusion(Precision::Confusion());
593   Standard_Boolean samePoint(FirstAttach.IsEqual(SecondAttach,confusion));
594
595   if (TypeDist == AIS_TOD_Vertical) DirAttach =  Plane->Pln().XAxis().Direction();
596   else if (TypeDist == AIS_TOD_Horizontal) DirAttach =  Plane->Pln().YAxis().Direction();
597   else {
598     if (!samePoint) {
599       DirAttach.SetXYZ(SecondAttach.XYZ() - FirstAttach.XYZ());
600       DirAttach.Rotate(Plane->Pln().Axis(),M_PI/2.);
601     }
602   }
603   
604   // size
605   if (AutomaticPos) {
606    if (!samePoint) {
607      gp_Pnt curpos((FirstAttach.XYZ()+SecondAttach.XYZ())*0.5);
608      // make offset of curpos
609      gp_Vec offset(DirAttach);
610      offset = offset*ArrowSize*(-10.);
611      curpos.Translate(offset);
612      Position = curpos;
613    }
614    else {
615      gp_Dir aDir = Plane->Pln().Axis().Direction();
616      gp_Vec aVec (aDir.XYZ()*10*ArrowSize);
617      //Position = gp_Pnt(FirstAttach.XYZ()+gp_XYZ(1.,1.,1.)); // not correct
618      Position = FirstAttach.Translated(aVec);
619      Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );//not needed really
620      DirAttach.SetXYZ(Position.XYZ() - FirstAttach.XYZ());
621    }
622   }
623   else {   
624     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
625   }
626
627  
628   Handle(Prs3d_DimensionAspect) la = aDrawer->DimensionAspect();
629   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();  
630   arr->SetLength(ArrowSize);
631   arr = la->ArrowAspect();
632   arr->SetLength(ArrowSize);
633
634   if (AutomaticPos && IsSetBndBox)
635     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
636
637   DsgPrs_EqualDistancePresentation::AddInterval(aPresentation,
638                                                 aDrawer,
639                                                 FirstAttach,
640                                                 SecondAttach,
641                                                 DirAttach,
642                                                 Position,
643                                                 SymbolPrs,
644                                                 FirstExtreme, //returned
645                                                 SecondExtreme); //returned
646
647   // Compute projection
648   if ( !isOnPlane1)
649     AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, FirstVertex, FirstAttach);
650   if ( !isOnPlane2)
651     AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, SecondVertex, SecondAttach);
652
653
654
655
656 //=======================================================================
657 //function : ComputeOneEdgeOneVertexLength
658 //purpose  : 
659 //=======================================================================
660
661 void AIS_EqualDistanceRelation::ComputeOneEdgeOneVertexLength( const Handle( Prs3d_Presentation )& aPresentation,
662                                                               const Handle( Prs3d_Drawer )& aDrawer,
663                                                               const Standard_Real ArrowSize,
664                                                               const TopoDS_Shape & FirstShape,
665                                                               const TopoDS_Shape & SecondShape,
666                                                               const Handle( Geom_Plane )& Plane,
667                                                               const Standard_Boolean AutomaticPos,
668                                                               const Standard_Boolean IsSetBndBox,
669                                                               const Bnd_Box & BndBox,
670                                                               gp_Pnt & Position,
671                                                               gp_Pnt & FirstAttach,
672                                                               gp_Pnt & SecondAttach,
673                                                               gp_Pnt& FirstExtreme,
674                                                               gp_Pnt& SecondExtreme, 
675                                                               DsgPrs_ArrowSide & SymbolPrs )
676 {
677   TopoDS_Vertex thevertex;
678   TopoDS_Edge theedge;
679   
680   gp_Pnt ptonedge1,ptonedge2;
681   Handle(Geom_Curve) aCurve;
682   Handle(Geom_Curve) extCurv;
683   Standard_Boolean isInfinite;
684   Standard_Real Val;
685   Standard_Boolean isOnPlanEdge, isOnPlanVertex;
686   Standard_Integer edgenum ;
687
688   if (FirstShape.ShapeType() == TopAbs_VERTEX) {  
689     thevertex = TopoDS::Vertex(FirstShape);
690     theedge   = TopoDS::Edge(SecondShape);
691     edgenum   = 2; //edge is the second shape
692   }
693   else {
694     thevertex = TopoDS::Vertex(SecondShape);
695     theedge   = TopoDS::Edge(FirstShape);
696     edgenum   = 1;//edge is the first shape
697   }
698   if (!AIS::ComputeGeometry(theedge,aCurve,ptonedge1,ptonedge2,extCurv,isInfinite,isOnPlanEdge,Plane))
699     return;
700   aPresentation->SetInfiniteState(isInfinite);
701   AIS::ComputeGeometry(thevertex, FirstAttach, Plane, isOnPlanVertex);
702
703   if ( aCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) 
704     {
705   Handle(Geom_Line) geom_lin (Handle(Geom_Line)::DownCast (aCurve));
706   const gp_Lin& l = geom_lin->Lin();
707
708   // computation of Val
709   Val = l.Distance( FirstAttach );
710
711   gp_Dir DirAttach = l.Direction();
712   // size
713   Standard_Real arrsize = ArrowSize;
714   if (Abs(Val) <= Precision::Confusion()) {arrsize = 0.;}
715
716   if (AutomaticPos) {
717     gp_Pnt p = ElCLib::Value(ElCLib::Parameter(l,FirstAttach),l);
718     gp_Pnt curpos((FirstAttach.XYZ()+p.XYZ())*0.5);
719     // make offset 
720     gp_Vec offset(DirAttach);
721     offset = offset*ArrowSize*(-10.);
722     curpos.Translate(offset);
723     Position = curpos;
724   }
725   else { // project point on the plane
726     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
727   }
728   
729   if (!isInfinite) {
730     if (Position.Distance(ptonedge1) > Position.Distance(ptonedge2)) SecondAttach = ptonedge2;
731     else SecondAttach = ptonedge1;
732   }
733   else {
734     SecondAttach = ElCLib::Value(ElCLib::Parameter(l,Position),l);
735   }
736   
737   Handle(Prs3d_DimensionAspect) la = aDrawer->DimensionAspect();
738   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();  
739   arr->SetLength(arrsize);
740   arr = la->ArrowAspect();
741   arr->SetLength(arrsize);
742
743   if (AutomaticPos && IsSetBndBox)
744     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
745   DsgPrs_EqualDistancePresentation::AddInterval(aPresentation,
746                                                 aDrawer,
747                                                 FirstAttach,
748                                                 SecondAttach,
749                                                 DirAttach,
750                                                 Position,
751                                                 SymbolPrs,
752                                                 FirstExtreme,
753                                                 SecondExtreme);
754   
755 }
756   if (aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))){
757     gp_Circ aCirc1 = (Handle(Geom_Circle)::DownCast(aCurve))->Circ();
758     gp_Circ aCirc2(aCirc1); aCirc2.SetRadius(0); //create the second formal circle
759     if(AutomaticPos)
760       {
761         SecondAttach = ptonedge2; //a vertex
762         Position.SetXYZ((SecondAttach.XYZ() + aCirc1.Location().XYZ())*0.5);
763       }
764     else {
765       Standard_Real aPar =  ElCLib::Parameter(aCirc1, Position);
766       SecondAttach =  ElCLib::Value(aPar, aCirc1);
767     }
768
769     Handle(Geom_Circle) aCurve2 = new Geom_Circle(aCirc2);
770     DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(aPresentation,
771                                                                 aDrawer,
772                                                                 aCirc1, //circle or arc
773                                                                 aCirc2, //really vertex
774                                                                 ptonedge2, //last point of aCirc1
775                                                                 SecondAttach,
776                                                                 FirstAttach, //vertex really
777                                                                 FirstAttach, 
778                                                                 SymbolPrs);
779     
780     //Assign arc points 
781     if (edgenum == 1){
782       FirstExtreme = SecondAttach; SecondExtreme = FirstAttach;
783       SecondAttach = FirstAttach; FirstAttach = ptonedge2; 
784     } else { //vertex is the first shape, circle is sthe last.
785       FirstExtreme = FirstAttach; SecondExtreme = SecondAttach;
786       SecondAttach = ptonedge2;
787     }
788   }
789  
790   // computation of Val
791   Val = FirstAttach.Distance(SecondAttach);
792   
793   //Display the pieces of attached to the curve if it is not 
794   // in the WP
795   if (!isOnPlanEdge) { // add presentation of projection of the edge in WP
796       AIS::ComputeProjEdgePresentation(aPresentation,aDrawer,theedge,aCurve,ptonedge1,ptonedge2);
797       }
798   if (!isOnPlanVertex) { // add presentation of projection of the vertex in WP 
799     AIS::ComputeProjVertexPresentation(aPresentation,aDrawer,thevertex,FirstAttach);
800     }
801   
802 }
803 // -- ota -- end