1c702fdaa2e4fd8819e5e9498a4675cd216264cf
[occt.git] / src / DsgPrs / DsgPrs_LengthPresentation.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <DsgPrs_LengthPresentation.ixx>
20 #include <gp_Lin.hxx>
21 #include <gp_Dir.hxx>
22 #include <ElCLib.hxx>
23 #include <gce_MakeLin.hxx>
24 #include <Graphic3d_Group.hxx>
25 #include <Graphic3d_Array1OfVertex.hxx>
26 #include <Prs3d_Root.hxx>
27 #include <Prs3d_Arrow.hxx>
28 #include <Prs3d_ArrowAspect.hxx>
29 #include <Prs3d_LineAspect.hxx>
30 #include <Prs3d_LengthAspect.hxx>
31 #include <TCollection_AsciiString.hxx>
32 #include <Graphic3d_AspectLine3d.hxx>
33 #include <Prs3d_Text.hxx>
34 #include <Precision.hxx>
35 #include <Graphic3d_Vertex.hxx>
36 #include <Graphic3d_AspectMarker3d.hxx>
37 #include <Aspect_TypeOfLine.hxx>
38 #include <Aspect_TypeOfMarker.hxx>
39 #include <Aspect_AspectMarker.hxx>
40 #include <Quantity_Color.hxx>
41 #include <DsgPrs.hxx>
42
43 #include <Geom_Curve.hxx>
44
45
46 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
47                                      const Handle(Prs3d_Drawer)& aDrawer,
48                                      const TCollection_ExtendedString& aText,
49                                      const gp_Pnt& AttachmentPoint1,
50                                      const gp_Pnt& AttachmentPoint2,
51                                      const gp_Dir& aDirection,
52                                      const gp_Pnt& OffsetPoint)
53 {
54   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
55   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
56   gp_Lin L1 (AttachmentPoint1,aDirection);
57   gp_Lin L2 (AttachmentPoint2,aDirection);
58   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,OffsetPoint),L1);
59   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,OffsetPoint),L2);
60   gp_Lin L3;
61   if (!Proj1.IsEqual(Proj2,Precision::Confusion())) {
62     L3 = gce_MakeLin(Proj1,Proj2);
63   }
64   else {
65     L3 = gp_Lin(Proj1,aDirection);
66   }
67   Standard_Real parmin,parmax,parcur;
68   parmin = ElCLib::Parameter(L3,Proj1);
69   parmax = parmin;
70   parcur = ElCLib::Parameter(L3,Proj2);
71   Standard_Real dist = Abs(parmin-parcur);
72   if (parcur < parmin) parmin = parcur;
73   if (parcur > parmax) parmax = parcur;
74   parcur = ElCLib::Parameter(L3,OffsetPoint);
75   gp_Pnt offp = ElCLib::Value(parcur,L3);
76
77   Standard_Boolean outside = Standard_False;
78   if (parcur < parmin) {
79     parmin = parcur;
80     outside = Standard_True;
81   }
82   if (parcur > parmax) {
83     parmax = parcur;
84     outside = Standard_True;
85   }
86
87   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
88   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
89
90   Graphic3d_Array1OfVertex V(1,2);
91
92   Quantity_Length X,Y,Z;
93
94   PointMin.Coord(X,Y,Z);
95   V(1).SetCoord(X,Y,Z);
96
97   PointMax.Coord(X,Y,Z);
98   V(2).SetCoord(X,Y,Z);
99   // face processing : 1st group
100   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
101
102   Prs3d_Root::NewGroup(aPresentation);
103   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
104   
105   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) {
106     outside = Standard_True;
107   }
108   gp_Dir arrdir = L3.Direction().Reversed();
109
110   if (outside) {
111     arrdir.Reverse();
112   }
113   // arrow 1 : 2nd group
114   Prs3d_Arrow::Draw(aPresentation,Proj1,arrdir,
115                     LA->Arrow1Aspect()->Angle(),
116                     LA->Arrow1Aspect()->Length());
117
118   Prs3d_Root::NewGroup(aPresentation);
119   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
120   
121   // arrow 2 : 3rd group
122   Prs3d_Arrow::Draw(aPresentation,Proj2,arrdir.Reversed(),
123                     LA->Arrow2Aspect()->Angle(),
124                     LA->Arrow2Aspect()->Length());
125
126   Prs3d_Root::NewGroup(aPresentation);
127   
128   // text : 4th group
129   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,offp);
130   
131   AttachmentPoint1.Coord(X,Y,Z);
132   V(1).SetCoord(X,Y,Z);
133   Proj1.Coord(X,Y,Z);
134   V(2).SetCoord(X,Y,Z);
135
136   Prs3d_Root::NewGroup(aPresentation);
137   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
138   // processing of call 1 : 5th group
139   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
140   
141   AttachmentPoint2.Coord(X,Y,Z);
142   V(1).SetCoord(X,Y,Z);
143   Proj2.Coord(X,Y,Z);
144   V(2).SetCoord(X,Y,Z);
145
146   Prs3d_Root::NewGroup(aPresentation);
147   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
148   // processing of call 2 : 6th group
149   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
150   
151 }
152
153 //==================================================================================
154 //function : Add
155 //purpose  : Adds presentation of length dimension between two planar faces
156 //==================================================================================
157
158 void DsgPrs_LengthPresentation::Add( const Handle(Prs3d_Presentation)& aPresentation,
159                                      const Handle(Prs3d_Drawer)& aDrawer,
160                                      const TCollection_ExtendedString& aText,
161                                      const gp_Pnt& AttachmentPoint1,
162                                      const gp_Pnt& AttachmentPoint2,
163                                      const gp_Pln& PlaneOfFaces,
164                                      const gp_Dir& aDirection,
165                                      const gp_Pnt& OffsetPoint,
166                                      const DsgPrs_ArrowSide ArrowPrs ) 
167 {
168   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
169   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
170
171   gp_Pnt EndOfArrow1, EndOfArrow2;
172   gp_Dir DirOfArrow1;
173   
174   DsgPrs::ComputePlanarFacesLengthPresentation( LA->Arrow1Aspect()->Length(),
175                                                 LA->Arrow2Aspect()->Length(),
176                                                 AttachmentPoint1,
177                                                 AttachmentPoint2,
178                                                 aDirection,
179                                                 OffsetPoint,
180                                                 PlaneOfFaces,
181                                                 EndOfArrow1,
182                                                 EndOfArrow2,
183                                                 DirOfArrow1 );
184   Graphic3d_Array1OfVertex VertexArray( 1, 2 );
185
186   // Parameters for length's line
187   gp_Lin LengthLine( OffsetPoint, DirOfArrow1 );
188   Standard_Real Par1 = ElCLib::Parameter( LengthLine, EndOfArrow1 );
189   Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
190   gp_Pnt FirstPoint, LastPoint;
191   if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
192     {
193       FirstPoint = OffsetPoint;
194       LastPoint  = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
195     }
196   else
197     {
198       FirstPoint = EndOfArrow1;
199       LastPoint  = EndOfArrow2;
200     }
201
202   // Creating the length's line
203   VertexArray(1).SetCoord( FirstPoint.X(), FirstPoint.Y(), FirstPoint.Z() );
204   VertexArray(2).SetCoord( LastPoint.X(), LastPoint.Y(), LastPoint.Z() );
205   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
206
207   // Add presentation of arrows
208   DsgPrs::ComputeSymbol( aPresentation, LA,
209                          EndOfArrow1, EndOfArrow2, //EndOfArrow1,
210                          DirOfArrow1, DirOfArrow1.Reversed(), ArrowPrs );
211  
212   // Drawing the text
213   Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
214
215   // Line from AttachmentPoint1 to end of Arrow1
216   VertexArray(1).SetCoord(AttachmentPoint1.X(),
217                           AttachmentPoint1.Y(),
218                           AttachmentPoint1.Z());
219   VertexArray(2).SetCoord( EndOfArrow1.X(), EndOfArrow1.Y(), EndOfArrow1.Z() );
220   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
221
222   // Line from AttachmentPoint2 to end of Arrow2
223   VertexArray(1).SetCoord(AttachmentPoint2.X(),
224                           AttachmentPoint2.Y(),
225                           AttachmentPoint2.Z());
226   VertexArray(2).SetCoord( EndOfArrow2.X(), EndOfArrow2.Y(), EndOfArrow2.Z() );
227   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
228 }
229
230
231 //=========================================================================================
232 //function : Add
233 //purpose  : adds presentation of length between two edges, vertex and edge or two vertices
234 //=========================================================================================
235
236 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
237                                      const Handle(Prs3d_Drawer)& aDrawer,
238                                      const TCollection_ExtendedString& aText,
239                                      const gp_Pnt& AttachmentPoint1,
240                                      const gp_Pnt& AttachmentPoint2,
241                                      const gp_Dir& aDirection,
242                                      const gp_Pnt& OffsetPoint,
243                                      const DsgPrs_ArrowSide ArrowPrs) 
244 {
245   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
246   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
247
248   gp_Lin L1 (AttachmentPoint1,aDirection);
249   gp_Lin L2 (AttachmentPoint2,aDirection);
250   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,OffsetPoint),L1);
251   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,OffsetPoint),L2);
252   gp_Lin L3;
253   if (!Proj1.IsEqual(Proj2,Precision::Confusion())) {
254     L3 = gce_MakeLin(Proj1,Proj2);
255   }
256   else {
257     L3 = gp_Lin(Proj1,aDirection);
258   }
259   Standard_Real parmin,parmax,parcur;
260   parmin = ElCLib::Parameter(L3,Proj1);
261   parmax = parmin;
262   parcur = ElCLib::Parameter(L3,Proj2);
263   Standard_Real dist = Abs(parmin-parcur);
264   if (parcur < parmin) parmin = parcur;
265   if (parcur > parmax) parmax = parcur;
266   parcur = ElCLib::Parameter(L3,OffsetPoint);
267   gp_Pnt offp = ElCLib::Value(parcur,L3);
268
269   Standard_Boolean outside = Standard_False;
270   if (parcur < parmin) {
271     parmin = parcur;
272     outside = Standard_True;
273   }
274   if (parcur > parmax) {
275     parmax = parcur;
276     outside = Standard_True;
277   }
278
279   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
280   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
281
282   Graphic3d_Array1OfVertex V(1,2);
283
284   Quantity_Length X,Y,Z;
285
286   PointMin.Coord(X,Y,Z);
287   V(1).SetCoord(X,Y,Z);
288
289   PointMax.Coord(X,Y,Z);
290   V(2).SetCoord(X,Y,Z);
291
292   // processing of face 
293   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
294   
295   
296   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) {
297     outside = Standard_True;
298   }
299   gp_Dir arrdir = L3.Direction().Reversed();
300
301   if (outside) {
302     arrdir.Reverse();
303   }
304
305   
306   AttachmentPoint1.Coord(X,Y,Z);
307   V(1).SetCoord(X,Y,Z);
308   Proj1.Coord(X,Y,Z);
309   V(2).SetCoord(X,Y,Z);
310
311   // processing of call  1 
312   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
313   
314   AttachmentPoint2.Coord(X,Y,Z);
315   V(1).SetCoord(X,Y,Z);
316   Proj2.Coord(X,Y,Z);
317   V(2).SetCoord(X,Y,Z);
318
319   // processing of call 2 
320   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
321
322  
323   // text 
324   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,offp);
325
326   // symbols at the extremities of the face
327   DsgPrs::ComputeSymbol(aPresentation,LA,Proj1,Proj2,arrdir,arrdir.Reversed(),ArrowPrs);
328 }
329
330
331
332 //==================================================================================
333 //function : Add
334 //purpose  : Adds presentation of length dimension between two curvilinear faces
335 //==================================================================================
336
337 void DsgPrs_LengthPresentation::Add( const Handle(Prs3d_Presentation)& aPresentation,
338                                      const Handle(Prs3d_Drawer)& aDrawer,
339                                      const TCollection_ExtendedString& aText,
340                                      const Handle( Geom_Surface )& SecondSurf,
341                                      const gp_Pnt& AttachmentPoint1,
342                                      const gp_Pnt& AttachmentPoint2,
343                                      const gp_Dir& aDirection,
344                                      const gp_Pnt& OffsetPoint,
345                                      const DsgPrs_ArrowSide ArrowPrs ) 
346 {
347   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
348   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
349
350   gp_Pnt EndOfArrow2;
351   gp_Dir DirOfArrow1;
352   Handle( Geom_Curve ) VCurve, UCurve;
353   Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
354   
355   DsgPrs::ComputeCurvilinearFacesLengthPresentation( LA->Arrow1Aspect()->Length(),
356                                                      LA->Arrow2Aspect()->Length(),
357                                                      SecondSurf,
358                                                      AttachmentPoint1,
359                                                      AttachmentPoint2,
360                                                      aDirection,
361                                                      EndOfArrow2,
362                                                      DirOfArrow1,
363                                                      VCurve,
364                                                      UCurve,
365                                                      FirstU, deltaU,
366                                                      FirstV, deltaV );
367                                                        
368   Graphic3d_Array1OfVertex VertexArray( 1, 2 );
369
370   gp_Lin LengthLine( OffsetPoint, DirOfArrow1 );
371   Standard_Real Par1 = ElCLib::Parameter( LengthLine, AttachmentPoint1 );
372   Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
373   gp_Pnt FirstPoint, LastPoint;
374   if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
375     {
376       FirstPoint = OffsetPoint;
377       LastPoint  = (Abs( Par1 ) > Abs( Par2 ))? AttachmentPoint1 : EndOfArrow2;
378     }
379   else
380     {
381       FirstPoint = AttachmentPoint1;
382       LastPoint  = EndOfArrow2;
383     }
384
385   // Creating the length's line
386   VertexArray(1).SetCoord( FirstPoint.X(), FirstPoint.Y(), FirstPoint.Z() );
387   VertexArray(2).SetCoord( LastPoint.X(), LastPoint.Y(), LastPoint.Z() );
388   Prs3d_Root::CurrentGroup( aPresentation )->Polyline( VertexArray );
389
390   // Add presentation of arrows
391   DsgPrs::ComputeSymbol( aPresentation, LA, 
392                          AttachmentPoint1, EndOfArrow2,
393                          DirOfArrow1, DirOfArrow1.Reversed(), ArrowPrs );
394  
395   // Drawing the text
396   Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
397  
398   // Two curves from end of Arrow2 to AttachmentPoint2
399   Standard_Real Alpha, delta;
400   Standard_Integer NodeNumber;
401   
402   Alpha  = Abs( deltaU );
403   if (Alpha > Precision::Angular() && Alpha<Precision::Infinite())
404     {
405       NodeNumber = Max( 4 , Standard_Integer (50. * Alpha / M_PI) );
406       Graphic3d_Array1OfVertex ApproxCurve( 1, NodeNumber );
407       delta = deltaU / (Standard_Real)( NodeNumber - 1 );
408       gp_Pnt CurPnt;
409       for (Standard_Integer i = 1; i <= NodeNumber; i++)
410         {
411           CurPnt =  VCurve->Value( FirstU );
412           ApproxCurve(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
413           FirstU += delta;
414         }
415       Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxCurve );
416     }
417   Alpha  = Abs( deltaV );
418   if (Alpha > Precision::Angular() && Alpha<Precision::Infinite())
419     {
420       NodeNumber = Max( 4 , Standard_Integer (50. * Alpha / M_PI) );
421       Graphic3d_Array1OfVertex ApproxCurve( 1, NodeNumber );
422       delta = deltaV / (Standard_Real)( NodeNumber - 1 );
423       gp_Pnt CurPnt;
424       for (Standard_Integer i = 1; i <= NodeNumber; i++)
425         {
426           CurPnt =  UCurve->Value( FirstV );
427           ApproxCurve(i).SetCoord( CurPnt.X(), CurPnt.Y(), CurPnt.Z() );
428           FirstV += delta;
429         }
430       Prs3d_Root::CurrentGroup( aPresentation )->Polyline( ApproxCurve );
431     }
432 }
433
434
435
436
437
438
439 //================================
440 // Function:
441 // Purpose: Rob 26-mar-96
442 //=================================
443
444 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPrs,
445                                      const Handle(Prs3d_Drawer)& aDrawer,
446                                      const gp_Pnt& Pt1,
447                                      const gp_Pnt& Pt2,
448                                      const DsgPrs_ArrowSide ArrowPrs) 
449 {
450   Prs3d_Root::CurrentGroup(aPrs)->BeginPrimitives();
451   Graphic3d_Array1OfVertex Vx(1,2);
452   Vx(1).SetCoord(Pt1.X(),Pt1.Y(),Pt1.Z());
453   Vx(2).SetCoord(Pt2.X(),Pt2.Y(),Pt2.Z());
454   Prs3d_Root::CurrentGroup(aPrs)->Polyline(Vx);
455   
456   gp_Vec V ;
457   switch(ArrowPrs){
458   case DsgPrs_AS_NONE:
459     break;
460   case DsgPrs_AS_LASTAR:
461     Prs3d_Arrow::Draw(aPrs,Pt2,gp_Dir(gp_Vec(Pt1,Pt2)), 
462                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
463                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
464     break;
465   case DsgPrs_AS_FIRSTAR:
466     Prs3d_Arrow::Draw(aPrs,Pt1,gp_Dir(gp_Vec(Pt2,Pt1)), 
467                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
468                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
469     break;
470   case DsgPrs_AS_BOTHAR:
471     V = gp_Vec(Pt1,Pt2);
472     Prs3d_Arrow::Draw(aPrs,Pt2,gp_Dir(V), 
473                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
474                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
475     Prs3d_Arrow::Draw(aPrs,Pt1,gp_Dir(V.Reversed()), 
476                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
477                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
478     break;
479   default:
480     break;
481   }
482   Prs3d_Root::CurrentGroup(aPrs)->EndPrimitives();
483   
484 }