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