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