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