f0d77232ed649e82c5cc9141ecf8a3a4f5842661
[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
22
23 #include <DsgPrs_EqualDistancePresentation.ixx>
24
25 #include <DsgPrs.hxx>
26 #include <Graphic3d_Group.hxx>
27 #include <Prs3d_LengthAspect.hxx>
28 #include <Prs3d_LineAspect.hxx>
29 #include <Graphic3d_Array1OfVertex.hxx>
30 #include <Prs3d_Root.hxx>
31 #include <gp_Dir.hxx>
32 #include <gce_MakeDir.hxx>
33 #include <gp_Vec.hxx>
34 #include <gp_Pln.hxx>
35 #include <Precision.hxx>
36 #include <ElCLib.hxx>
37 #include <gp_Circ.hxx>
38 #include <TCollection_ExtendedString.hxx>
39 #include <Prs3d_Text.hxx>
40
41 //=================================================================================
42 //function  : Add
43 //=================================================================================
44 void DsgPrs_EqualDistancePresentation::Add( const Handle( Prs3d_Presentation )& aPresentation,
45                                             const Handle( Prs3d_Drawer )& aDrawer,
46                                             const gp_Pnt& Point1,
47                                             const gp_Pnt& Point2,
48                                             const gp_Pnt& Point3,
49                                             const gp_Pnt& Point4,
50                                             const Handle( Geom_Plane )& Plane )
51 {
52   Handle( Prs3d_LengthAspect ) LA = aDrawer->LengthAspect();
53   Prs3d_Root::CurrentGroup( aPresentation )->SetPrimitivesAspect( LA->LineAspect()->Aspect() );
54
55   Graphic3d_Array1OfVertex VertexArray( 1, 2 );
56   Quantity_Length X,Y,Z;
57
58   // Line between two middles
59   gp_Pnt Middle12( (Point1.XYZ() + Point2.XYZ()) * 0.5 ), Middle34( (Point3.XYZ() + Point4.XYZ()) * 0.5 );
60
61   Middle12.Coord( X, Y, Z );
62   VertexArray( 1 ).SetCoord( X, Y, Z );
63   Middle34.Coord( X, Y, Z );
64   VertexArray( 2 ).SetCoord( X, Y, Z );
65   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
66
67   // Add presentation of arrows (points)
68   gp_Dir aDir( 0, 0, 1 );
69   DsgPrs::ComputeSymbol(aPresentation, LA,
70                         Middle12, Middle34,
71                         aDir, aDir,
72                         DsgPrs_AS_BOTHPT );
73 // ota -- begin --  
74   // Two small lines in the middle of this line
75   gp_Pnt Middle( (Middle12.XYZ() + Middle34.XYZ()) * 0.5 ), aTextPos;
76   Standard_Real Dist = Middle12.Distance( Middle34 );
77   Standard_Real SmallDist;
78   gp_Dir LineDir, OrtDir;
79   gp_Vec LineVec, OrtVec;
80
81   if (Dist > Precision::Confusion())
82     {
83       SmallDist = Dist * 0.05; // 1/20.0 part
84       if (SmallDist <= Precision::Confusion())
85         SmallDist = Dist;
86       LineDir = gce_MakeDir( Middle12, Middle34 );
87       OrtDir  = Plane->Pln().Axis().Direction() ^ LineDir;
88       LineVec = gp_Vec( LineDir ) * SmallDist;
89       OrtVec  = gp_Vec( OrtDir ) * SmallDist;
90
91       aTextPos = Middle.Translated( OrtVec );
92     }
93   else
94     {
95       gp_Vec Vec1( Middle, Point1 );
96
97       if (Vec1.SquareMagnitude() > Precision::SquareConfusion())
98         {
99           Standard_Real Angle = gp_Vec( Middle, Point1 ).Angle( gp_Vec( Middle, Point3 ) );
100           gp_Pnt MidPnt = Point1.Rotated( Plane->Pln().Axis(), Angle*0.5 );
101           OrtDir  = gce_MakeDir( Middle, MidPnt );
102           LineDir = OrtDir ^ Plane->Pln().Axis().Direction();
103           
104           Standard_Real Distance = Point1.Distance( Point2 );
105           SmallDist = Distance * 0.05; // 1/20.0
106           if (SmallDist <= Precision::Confusion())
107             SmallDist = Distance;
108           
109           OrtVec = gp_Vec( OrtDir ) * SmallDist;
110           LineVec = gp_Vec( LineDir ) * SmallDist;
111         }
112       else
113         {
114           SmallDist = 5.0;
115           OrtVec = gp_Vec( Plane->Pln().XAxis().Direction() ) * SmallDist;
116           LineVec = gp_Vec( Plane->Pln().YAxis().Direction() ) * SmallDist;
117         }
118       aTextPos =  Middle.Translated (OrtVec);
119     }
120
121   TCollection_ExtendedString aText("==");
122
123   //Draw the text
124   Prs3d_Text::Draw(aPresentation,LA->TextAspect(), aText, aTextPos);
125 }
126
127 //==================================================================================
128 //function  : AddInterval
129 //purpose   : is used for presentation of interval between two lines or two points, 
130 //            or between one line and one point.
131 //==================================================================================
132  void DsgPrs_EqualDistancePresentation::AddInterval(const Handle(Prs3d_Presentation)& aPresentation,
133                                                     const Handle(Prs3d_Drawer)& aDrawer,
134                                                     const gp_Pnt& aPoint1,
135                                                     const gp_Pnt& aPoint2,
136                                                     const gp_Dir& aDirection,
137                                                     const gp_Pnt& aPosition,
138                                                     const DsgPrs_ArrowSide anArrowSide,
139                                                     gp_Pnt& aProj1,
140                                                     gp_Pnt& aProj2) 
141 {
142   const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
143 //set color
144   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
145   
146   gp_Lin L1 (aPoint1,aDirection);
147   gp_Lin L2 (aPoint2,aDirection);
148   aProj1 = ElCLib::Value(ElCLib::Parameter(L1, aPosition),L1);
149   aProj2 = ElCLib::Value(ElCLib::Parameter(L2, aPosition),L2);
150
151   Graphic3d_Array1OfVertex V(1,2);
152
153   Quantity_Length X,Y,Z;
154
155   aProj1.Coord (X, Y, Z);
156   V(1).SetCoord(X, Y, Z);
157
158   aPoint1.Coord(X, Y, Z);
159   V(2).SetCoord(X, Y, Z);
160
161   //add first attached line  
162   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
163
164   //add distance interval 
165   aProj2.Coord(X, Y, Z);
166   V(2).SetCoord(X, Y, Z);
167   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
168
169
170   //add second attached line
171   aPoint2.Coord(X, Y, Z);
172   V(1).SetCoord(X, Y, Z);
173   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
174
175   //add arrows presentation
176   gp_Dir aDir(aProj2.XYZ() - aProj1.XYZ());
177   
178   DsgPrs::ComputeSymbol(aPresentation, LA,
179                         aProj1, aProj2,
180                         aDir.Reversed(), aDir,
181                         anArrowSide);
182 }
183
184 //========================================================================
185 // function : AddIntervalBetweenTwoArcs 
186 // purpose  : is used for presentation of interval between two arcs. One
187 //            of the arcs can have a zero radius (being a point really) 
188 //========================================================================
189  void 
190   DsgPrs_EqualDistancePresentation::AddIntervalBetweenTwoArcs(const Handle(Prs3d_Presentation)& aPresentation,
191                                                               const Handle(Prs3d_Drawer)& aDrawer,
192                                                               const gp_Circ& aCirc1,
193                                                               const gp_Circ& aCirc2,
194                                                               const gp_Pnt& aPoint1,
195                                                               const gp_Pnt& aPoint2,
196                                                               const gp_Pnt& aPoint3,
197                                                               const gp_Pnt& aPoint4,
198                                                               const DsgPrs_ArrowSide anArrowSide) 
199 {
200 //it seems to set color
201   const Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
202   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
203   Standard_Real aPar11, aPar12, aPar21, aPar22;
204   if(aCirc1.Radius() > Precision::Confusion()){
205     aPar11 = ElCLib::Parameter (aCirc1, aPoint1);
206     aPar12 = ElCLib::Parameter(aCirc1, aPoint2);
207   }
208   else {
209     aPar11 = M_PI;
210     aPar12 = M_PI;
211   }
212   if (aCirc2.Radius() > Precision::Confusion()){
213     aPar21 = ElCLib::Parameter(aCirc2, aPoint3 );
214     aPar22 = ElCLib::Parameter(aCirc2, aPoint4);
215   }
216   else {
217     aPar21 = M_PI;
218     aPar22 = M_PI;
219   }
220
221   Graphic3d_Array1OfVertex V(1,2);
222   V(1).SetCoord(aPoint2.X(), aPoint2.Y(), aPoint2.Z());
223   V(2).SetCoord(aPoint4.X(), aPoint4.Y(), aPoint4.Z());
224   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( V );
225
226   Standard_Integer aNodeNb; 
227   Standard_Real aDelta, aCurPar;
228   if(aPar12 < aPar11 ) aPar12 +=2*M_PI;
229   if (Abs(aPar12 - aPar11) > Precision::Confusion()) {
230     aNodeNb = Standard_Integer(Max(Abs(aPar12 - aPar11)*50./M_PI + 0.5, 4.));
231     Graphic3d_Array1OfVertex ApproxArc1( 1, aNodeNb+1);
232     aDelta = (aPar12 - aPar11)/aNodeNb;
233     aCurPar= aPar11;
234     for ( int i = 1; i<= aNodeNb ; aCurPar+= aDelta, i++)
235       {
236         gp_Pnt CurPnt =  ElCLib::Value( aCurPar, aCirc1);
237         ApproxArc1(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
238       }
239     ApproxArc1(aNodeNb+1).SetCoord( aPoint2.X(), aPoint2.Y(), aPoint2.Z() );
240
241     Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxArc1 );
242   }
243   if (aPar22 < aPar21) aPar22 += 2*M_PI;
244   if ( Abs(aPar22 - aPar21) > Precision::Confusion()){
245     aNodeNb = Standard_Integer(Max(Abs(aPar22 - aPar21)*50./M_PI + 0.5, 4.));
246     Graphic3d_Array1OfVertex ApproxArc2( 1, aNodeNb+1);
247     aDelta = (aPar22 - aPar21)/aNodeNb;
248     aCurPar= aPar21;
249     for ( int i=1; i<= aNodeNb; aCurPar+= aDelta, i++)
250       {
251         gp_Pnt CurPnt =  ElCLib::Value( aCurPar, aCirc2);
252         ApproxArc2(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
253       }
254     ApproxArc2(aNodeNb+1).SetCoord( aPoint4.X(), aPoint4.Y(), aPoint4.Z() );
255     Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxArc2 );
256   }
257
258   //get the direction of interval
259   gp_Dir  DirOfArrow;
260   if(aPoint4.Distance(aPoint2) > Precision::Confusion()){
261     DirOfArrow.SetXYZ(aPoint4.XYZ() - aPoint2.XYZ());
262   }
263   else {
264     //Let's take the radius direction
265     gp_Pnt aCenter = aCirc1.Location();
266     if(aPoint4.Distance(aCenter) < Precision::Confusion())
267       return;
268     DirOfArrow.SetXYZ(aPoint4.XYZ() - aCenter.XYZ());
269   }
270
271   // Add presentation of arrows
272   DsgPrs::ComputeSymbol( aPresentation, LA, aPoint2, aPoint4, DirOfArrow.Reversed(), DirOfArrow, anArrowSide );
273   
274 }
275 //-- ota -- end