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