0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / DsgPrs / DsgPrs_EqualDistancePresentation.cxx
1 // Created on: 1998-01-27
2 // Created by: Julia GERASIMOVA
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 #include <DsgPrs_EqualDistancePresentation.ixx>
22
23 #include <DsgPrs.hxx>
24 #include <Graphic3d_Group.hxx>
25 #include <Prs3d_LengthAspect.hxx>
26 #include <Prs3d_LineAspect.hxx>
27 #include <Graphic3d_ArrayOfSegments.hxx>
28 #include <Graphic3d_ArrayOfPolylines.hxx>
29 #include <Prs3d_Root.hxx>
30 #include <gp_Dir.hxx>
31 #include <gce_MakeDir.hxx>
32 #include <gp_Vec.hxx>
33 #include <gp_Pln.hxx>
34 #include <Precision.hxx>
35 #include <ElCLib.hxx>
36 #include <gp_Circ.hxx>
37 #include <TCollection_ExtendedString.hxx>
38 #include <Prs3d_Text.hxx>
39
40 //=================================================================================
41 //function  : Add
42 //=================================================================================
43 void DsgPrs_EqualDistancePresentation::Add( const Handle( Prs3d_Presentation )& aPresentation,
44                                             const Handle( Prs3d_Drawer )& aDrawer,
45                                             const gp_Pnt& Point1,
46                                             const gp_Pnt& Point2,
47                                             const gp_Pnt& Point3,
48                                             const gp_Pnt& Point4,
49                                             const Handle( Geom_Plane )& Plane )
50 {
51   Handle( Prs3d_LengthAspect ) LA = aDrawer->LengthAspect();
52   Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
53
54   // Line between two middles
55   gp_Pnt Middle12( (Point1.XYZ() + Point2.XYZ()) * 0.5 ), Middle34( (Point3.XYZ() + Point4.XYZ()) * 0.5 );
56
57   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
58   aPrims->AddVertex(Middle12);
59   aPrims->AddVertex(Middle34);
60   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
61
62   // Add presentation of arrows (points)
63   gp_Dir aDir( 0, 0, 1 );
64   DsgPrs::ComputeSymbol(aPresentation, LA, Middle12, Middle34, aDir, aDir, DsgPrs_AS_BOTHPT );
65 // ota -- begin --  
66   // Two small lines in the middle of this line
67   gp_Pnt Middle( (Middle12.XYZ() + Middle34.XYZ()) * 0.5 ), aTextPos;
68   Standard_Real Dist = Middle12.Distance( Middle34 );
69   Standard_Real SmallDist;
70   gp_Dir LineDir, OrtDir;
71   gp_Vec LineVec, OrtVec;
72
73   if (Dist > Precision::Confusion())
74   {
75     SmallDist = Dist * 0.05; // 1/20.0 part
76     if (SmallDist <= Precision::Confusion())
77       SmallDist = Dist;
78     LineDir = gce_MakeDir( Middle12, Middle34 );
79     OrtDir  = Plane->Pln().Axis().Direction() ^ LineDir;
80     LineVec = gp_Vec( LineDir ) * SmallDist;
81     OrtVec  = gp_Vec( OrtDir ) * SmallDist;
82
83     aTextPos = Middle.Translated( OrtVec );
84   }
85   else
86   {
87     gp_Vec Vec1( Middle, Point1 );
88
89     if (Vec1.SquareMagnitude() > Precision::Confusion()*Precision::Confusion())
90         {
91           Standard_Real Angle = gp_Vec( Middle, Point1 ).Angle( gp_Vec( Middle, Point3 ) );
92           gp_Pnt MidPnt = Point1.Rotated( Plane->Pln().Axis(), Angle*0.5 );
93           OrtDir  = gce_MakeDir( Middle, MidPnt );
94           LineDir = OrtDir ^ Plane->Pln().Axis().Direction();
95           
96           Standard_Real Distance = Point1.Distance( Point2 );
97           SmallDist = Distance * 0.05; // 1/20.0
98           if (SmallDist <= Precision::Confusion())
99             SmallDist = Distance;
100           
101           OrtVec = gp_Vec( OrtDir ) * SmallDist;
102           LineVec = gp_Vec( LineDir ) * SmallDist;
103         }
104     else
105         {
106           SmallDist = 5.0;
107           OrtVec = gp_Vec( Plane->Pln().XAxis().Direction() ) * SmallDist;
108           LineVec = gp_Vec( Plane->Pln().YAxis().Direction() ) * SmallDist;
109         }
110     aTextPos =  Middle.Translated (OrtVec);
111   }
112
113   TCollection_ExtendedString aText("==");
114
115   //Draw the text
116   Prs3d_Text::Draw(aPresentation,LA->TextAspect(), aText, aTextPos);
117 }
118
119
120 //==================================================================================
121 //function  : AddInterval
122 //purpose   : is used for presentation of interval between two lines or two points, 
123 //            or between one line and one point.
124 //==================================================================================
125  void DsgPrs_EqualDistancePresentation::AddInterval(const Handle(Prs3d_Presentation)& aPresentation,
126                                                     const Handle(Prs3d_Drawer)& aDrawer,
127                                                     const gp_Pnt& aPoint1,
128                                                     const gp_Pnt& aPoint2,
129                                                     const gp_Dir& aDirection,
130                                                     const gp_Pnt& aPosition,
131                                                     const DsgPrs_ArrowSide anArrowSide,
132                                                     gp_Pnt& aProj1,
133                                                     gp_Pnt& aProj2) 
134 {
135   const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
136   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
137   
138   gp_Lin L1 (aPoint1,aDirection);
139   gp_Lin L2 (aPoint2,aDirection);
140   aProj1 = ElCLib::Value(ElCLib::Parameter(L1, aPosition),L1);
141   aProj2 = ElCLib::Value(ElCLib::Parameter(L2, aPosition),L2);
142
143   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(4);
144   aPrims->AddVertex(aPoint1);
145   aPrims->AddVertex(aProj1);
146   aPrims->AddVertex(aProj2);
147   aPrims->AddVertex(aPoint2);
148   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
149
150   //add arrows presentation
151   gp_Dir aDir(aProj2.XYZ() - aProj1.XYZ());
152   
153   DsgPrs::ComputeSymbol(aPresentation, LA, aProj1, aProj2, aDir.Reversed(), aDir, anArrowSide);
154 }
155
156
157 //========================================================================
158 // function : AddIntervalBetweenTwoArcs 
159 // purpose  : is used for presentation of interval between two arcs. One
160 //            of the arcs can have a zero radius (being a point really) 
161 //========================================================================
162  void 
163   DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(const Handle(Prs3d_Presentation)& aPresentation,
164                                                               const Handle(Prs3d_Drawer)& aDrawer,
165                                                               const gp_Circ& aCirc1,
166                                                               const gp_Circ& aCirc2,
167                                                               const gp_Pnt& aPoint1,
168                                                               const gp_Pnt& aPoint2,
169                                                               const gp_Pnt& aPoint3,
170                                                               const gp_Pnt& aPoint4,
171                                                               const DsgPrs_ArrowSide anArrowSide) 
172 {
173   const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
174   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
175
176   Standard_Real aPar11, aPar12, aPar21, aPar22;
177   if(aCirc1.Radius() > Precision::Confusion()){
178     aPar11 = ElCLib::Parameter (aCirc1, aPoint1);
179     aPar12 = ElCLib::Parameter(aCirc1, aPoint2);
180   }
181   else {
182     aPar11 = M_PI;
183     aPar12 = M_PI;
184   }
185   if (aCirc2.Radius() > Precision::Confusion()){
186     aPar21 = ElCLib::Parameter(aCirc2, aPoint3 );
187     aPar22 = ElCLib::Parameter(aCirc2, aPoint4);
188   }
189   else {
190     aPar21 = M_PI;
191     aPar22 = M_PI;
192   }
193
194   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
195   aPrims->AddVertex(aPoint2);
196   aPrims->AddVertex(aPoint4);
197   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
198
199   Standard_Integer i, aNodeNb;
200   Standard_Real aDelta, aCurPar;
201   if(aPar12 < aPar11 ) aPar12 += 2.*M_PI;
202   if (Abs(aPar12 - aPar11) > Precision::Confusion())
203   {
204     aNodeNb = Standard_Integer(Max(Abs(aPar12 - aPar11)*50./M_PI + 0.5, 4.));
205     aDelta = (aPar12 - aPar11)/aNodeNb;
206     aCurPar= aPar11;
207
208     aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
209     for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
210       aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc1));
211     aPrims->AddVertex(aPoint2);
212     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
213   }
214   if (aPar22 < aPar21) aPar22 += 2.*M_PI;
215   if ( Abs(aPar22 - aPar21) > Precision::Confusion())
216   {
217     aNodeNb = Standard_Integer(Max(Abs(aPar22 - aPar21)*50./M_PI + 0.5, 4.));
218     aDelta = (aPar22 - aPar21)/aNodeNb;
219     aCurPar= aPar21;
220
221     aPrims = new Graphic3d_ArrayOfPolylines(aNodeNb+1);
222     for (i = 1; i<= aNodeNb; aCurPar += aDelta, i++)
223       aPrims->AddVertex(ElCLib::Value( aCurPar, aCirc2));
224     aPrims->AddVertex(aPoint4);
225     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
226   }
227
228   //get the direction of interval
229   gp_Dir DirOfArrow;
230   if(aPoint4.Distance(aPoint2) > Precision::Confusion())
231   {
232     DirOfArrow.SetXYZ(aPoint4.XYZ() - aPoint2.XYZ());
233   }
234   else
235   {
236     //Let's take the radius direction
237     gp_Pnt aCenter = aCirc1.Location();
238     if(aPoint4.Distance(aCenter) < Precision::Confusion())
239       return;
240     DirOfArrow.SetXYZ(aPoint4.XYZ() - aCenter.XYZ());
241   }
242
243   // Add presentation of arrows
244   DsgPrs::ComputeSymbol( aPresentation, LA, aPoint2, aPoint4, DirOfArrow.Reversed(), DirOfArrow, anArrowSide );
245 }
246 //-- ota -- end