0023634: Eliminate Polyline and Polygon usage in drawers
[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_ArrayOfSegments.hxx>
26 #include <Graphic3d_ArrayOfPolylines.hxx>
27 #include <Prs3d_Root.hxx>
28 #include <Prs3d_Arrow.hxx>
29 #include <Prs3d_ArrowAspect.hxx>
30 #include <Prs3d_LineAspect.hxx>
31 #include <Prs3d_LengthAspect.hxx>
32 #include <TCollection_AsciiString.hxx>
33 #include <Graphic3d_AspectLine3d.hxx>
34 #include <Prs3d_Text.hxx>
35 #include <Precision.hxx>
36 #include <Graphic3d_Vertex.hxx>
37 #include <Graphic3d_AspectMarker3d.hxx>
38 #include <Aspect_TypeOfLine.hxx>
39 #include <Aspect_TypeOfMarker.hxx>
40 #include <Aspect_AspectMarker.hxx>
41 #include <Quantity_Color.hxx>
42 #include <DsgPrs.hxx>
43
44 #include <Geom_Curve.hxx>
45
46
47 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
48                                      const Handle(Prs3d_Drawer)& aDrawer,
49                                      const TCollection_ExtendedString& aText,
50                                      const gp_Pnt& AttachmentPoint1,
51                                      const gp_Pnt& AttachmentPoint2,
52                                      const gp_Dir& aDirection,
53                                      const gp_Pnt& OffsetPoint)
54 {
55   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
56   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
57
58   gp_Lin L1 (AttachmentPoint1,aDirection);
59   gp_Lin L2 (AttachmentPoint2,aDirection);
60   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,OffsetPoint),L1);
61   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,OffsetPoint),L2);
62   gp_Lin L3 = Proj1.IsEqual(Proj2,Precision::Confusion())? gp_Lin(Proj1,aDirection) : gce_MakeLin(Proj1,Proj2);
63   Standard_Real parmin,parmax,parcur;
64   parmin = ElCLib::Parameter(L3,Proj1);
65   parmax = parmin;
66   parcur = ElCLib::Parameter(L3,Proj2);
67   Standard_Real dist = Abs(parmin-parcur);
68   if (parcur < parmin) parmin = parcur;
69   if (parcur > parmax) parmax = parcur;
70   parcur = ElCLib::Parameter(L3,OffsetPoint);
71   gp_Pnt offp = ElCLib::Value(parcur,L3);
72
73   Standard_Boolean outside = Standard_False;
74   if (parcur < parmin) {
75     parmin = parcur;
76     outside = Standard_True;
77   }
78   if (parcur > parmax) {
79     parmax = parcur;
80     outside = Standard_True;
81   }
82
83   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
84   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
85
86   // face processing : 1st group
87   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(6);
88   aPrims->AddVertex(PointMin);
89   aPrims->AddVertex(PointMax);
90
91   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length()))
92     outside = Standard_True;
93
94   gp_Dir arrdir = L3.Direction().Reversed();
95   if (outside)
96     arrdir.Reverse();
97
98   // arrow 1 : 2nd group
99   Prs3d_Arrow::Draw(aPresentation,Proj1,arrdir, LA->Arrow1Aspect()->Angle(), LA->Arrow1Aspect()->Length());
100
101   Prs3d_Root::NewGroup(aPresentation);
102   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
103   
104   // arrow 2 : 3rd group
105   Prs3d_Arrow::Draw(aPresentation,Proj2,arrdir.Reversed(), LA->Arrow2Aspect()->Angle(), LA->Arrow2Aspect()->Length());
106
107   Prs3d_Root::NewGroup(aPresentation);
108   
109   // text : 4th group
110   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,offp);
111   
112   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
113
114   // processing of call 1 : 5th group
115   aPrims->AddVertex(AttachmentPoint1);
116   aPrims->AddVertex(Proj1);
117   
118   // processing of call 2 : 6th group
119   aPrims->AddVertex(AttachmentPoint2);
120   aPrims->AddVertex(Proj2);
121
122   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
123 }
124
125 //==================================================================================
126 //function : Add
127 //purpose  : Adds presentation of length dimension between two planar faces
128 //==================================================================================
129
130 void DsgPrs_LengthPresentation::Add( const Handle(Prs3d_Presentation)& aPresentation,
131                                      const Handle(Prs3d_Drawer)& aDrawer,
132                                      const TCollection_ExtendedString& aText,
133                                      const gp_Pnt& AttachmentPoint1,
134                                      const gp_Pnt& AttachmentPoint2,
135                                      const gp_Pln& PlaneOfFaces,
136                                      const gp_Dir& aDirection,
137                                      const gp_Pnt& OffsetPoint,
138                                      const DsgPrs_ArrowSide ArrowPrs ) 
139 {
140   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
141   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
142
143   gp_Pnt EndOfArrow1, EndOfArrow2;
144   gp_Dir DirOfArrow1;
145   
146   DsgPrs::ComputePlanarFacesLengthPresentation( LA->Arrow1Aspect()->Length(),
147                                                 LA->Arrow2Aspect()->Length(),
148                                                 AttachmentPoint1,
149                                                 AttachmentPoint2,
150                                                 aDirection,
151                                                 OffsetPoint,
152                                                 PlaneOfFaces,
153                                                 EndOfArrow1,
154                                                 EndOfArrow2,
155                                                 DirOfArrow1 );
156
157   // Parameters for length's line
158   gp_Lin LengthLine( OffsetPoint, DirOfArrow1 );
159   Standard_Real Par1 = ElCLib::Parameter( LengthLine, EndOfArrow1 );
160   Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
161   gp_Pnt FirstPoint, LastPoint;
162   if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
163   {
164     FirstPoint = OffsetPoint;
165     LastPoint  = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
166   }
167   else
168   {
169     FirstPoint = EndOfArrow1;
170     LastPoint  = EndOfArrow2;
171   }
172
173   // Creating the length's line
174   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(6);
175
176   aPrims->AddVertex(FirstPoint);
177   aPrims->AddVertex(LastPoint);
178
179   // Add presentation of arrows
180   DsgPrs::ComputeSymbol( aPresentation, LA, EndOfArrow1, EndOfArrow2, DirOfArrow1, DirOfArrow1.Reversed(), ArrowPrs );
181  
182   // Drawing the text
183   Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
184
185   // Line from AttachmentPoint1 to end of Arrow1
186   aPrims->AddVertex(AttachmentPoint1);
187   aPrims->AddVertex(EndOfArrow1);
188
189   // Line from AttachmentPoint2 to end of Arrow2
190   aPrims->AddVertex(AttachmentPoint2);
191   aPrims->AddVertex(EndOfArrow2);
192
193   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
194 }
195
196
197 //=========================================================================================
198 //function : Add
199 //purpose  : adds presentation of length between two edges, vertex and edge or two vertices
200 //=========================================================================================
201
202 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
203                                      const Handle(Prs3d_Drawer)& aDrawer,
204                                      const TCollection_ExtendedString& aText,
205                                      const gp_Pnt& AttachmentPoint1,
206                                      const gp_Pnt& AttachmentPoint2,
207                                      const gp_Dir& aDirection,
208                                      const gp_Pnt& OffsetPoint,
209                                      const DsgPrs_ArrowSide ArrowPrs) 
210 {
211   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
212   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
213
214   gp_Lin L1 (AttachmentPoint1,aDirection);
215   gp_Lin L2 (AttachmentPoint2,aDirection);
216   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,OffsetPoint),L1);
217   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,OffsetPoint),L2);
218   gp_Lin L3 = Proj1.IsEqual(Proj2,Precision::Confusion())? gp_Lin(Proj1,aDirection) : gce_MakeLin(Proj1,Proj2);
219   Standard_Real parmin,parmax,parcur;
220   parmin = ElCLib::Parameter(L3,Proj1);
221   parmax = parmin;
222   parcur = ElCLib::Parameter(L3,Proj2);
223   Standard_Real dist = Abs(parmin-parcur);
224   if (parcur < parmin) parmin = parcur;
225   if (parcur > parmax) parmax = parcur;
226   parcur = ElCLib::Parameter(L3,OffsetPoint);
227   gp_Pnt offp = ElCLib::Value(parcur,L3);
228
229   Standard_Boolean outside = Standard_False;
230   if (parcur < parmin) {
231     parmin = parcur;
232     outside = Standard_True;
233   }
234   if (parcur > parmax) {
235     parmax = parcur;
236     outside = Standard_True;
237   }
238
239   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
240   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
241
242   // processing of face 
243   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(6);
244
245   aPrims->AddVertex(PointMin);
246   aPrims->AddVertex(PointMax);
247
248   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length()))
249     outside = Standard_True;
250
251   gp_Dir arrdir = L3.Direction().Reversed();
252   if (outside)
253     arrdir.Reverse();
254   
255   // processing of call  1 
256   aPrims->AddVertex(AttachmentPoint1);
257   aPrims->AddVertex(Proj1);
258   
259   // processing of call 2 
260   aPrims->AddVertex(AttachmentPoint2);
261   aPrims->AddVertex(Proj2);
262
263   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
264
265   // text 
266   Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,offp);
267
268   // symbols at the extremities of the face
269   DsgPrs::ComputeSymbol(aPresentation,LA,Proj1,Proj2,arrdir,arrdir.Reversed(),ArrowPrs);
270 }
271
272
273 //==================================================================================
274 //function : Add
275 //purpose  : Adds presentation of length dimension between two curvilinear faces
276 //==================================================================================
277
278 void DsgPrs_LengthPresentation::Add( const Handle(Prs3d_Presentation)& aPresentation,
279                                      const Handle(Prs3d_Drawer)& aDrawer,
280                                      const TCollection_ExtendedString& aText,
281                                      const Handle( Geom_Surface )& SecondSurf,
282                                      const gp_Pnt& AttachmentPoint1,
283                                      const gp_Pnt& AttachmentPoint2,
284                                      const gp_Dir& aDirection,
285                                      const gp_Pnt& OffsetPoint,
286                                      const DsgPrs_ArrowSide ArrowPrs ) 
287 {
288   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
289   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
290
291   gp_Pnt EndOfArrow2;
292   gp_Dir DirOfArrow1;
293   Handle( Geom_Curve ) VCurve, UCurve;
294   Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
295   
296   DsgPrs::ComputeCurvilinearFacesLengthPresentation( LA->Arrow1Aspect()->Length(),
297                                                      LA->Arrow2Aspect()->Length(),
298                                                      SecondSurf,
299                                                      AttachmentPoint1,
300                                                      AttachmentPoint2,
301                                                      aDirection,
302                                                      EndOfArrow2,
303                                                      DirOfArrow1,
304                                                      VCurve,
305                                                      UCurve,
306                                                      FirstU, deltaU,
307                                                      FirstV, deltaV );
308                                                        
309   gp_Lin LengthLine( OffsetPoint, DirOfArrow1 );
310   Standard_Real Par1 = ElCLib::Parameter( LengthLine, AttachmentPoint1 );
311   Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
312   gp_Pnt FirstPoint, LastPoint;
313   if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
314   {
315     FirstPoint = OffsetPoint;
316     LastPoint  = (Abs( Par1 ) > Abs( Par2 ))? AttachmentPoint1 : EndOfArrow2;
317   }
318   else
319   {
320     FirstPoint = AttachmentPoint1;
321     LastPoint  = EndOfArrow2;
322   }
323
324   // Creating the length's line
325   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
326   aPrims->AddVertex(FirstPoint);
327   aPrims->AddVertex(LastPoint);
328   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
329
330   // Add presentation of arrows
331   DsgPrs::ComputeSymbol( aPresentation, LA, AttachmentPoint1, EndOfArrow2, DirOfArrow1, DirOfArrow1.Reversed(), ArrowPrs );
332  
333   // Drawing the text
334   Prs3d_Text::Draw( aPresentation, LA->TextAspect(), aText, OffsetPoint );
335  
336   // Two curves from end of Arrow2 to AttachmentPoint2
337   Standard_Real Alpha, delta;
338   Standard_Integer NodeNumber;
339   
340   Alpha  = Abs( deltaU );
341   if (Alpha > Precision::Angular() && Alpha<Precision::Infinite())
342   {
343     NodeNumber = Max( 4 , Standard_Integer (50. * Alpha / M_PI) );
344     delta = deltaU / (Standard_Real)( NodeNumber - 1 );
345     aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
346     for (Standard_Integer i = 1; i <= NodeNumber; i++, FirstU += delta)
347       aPrims->AddVertex(VCurve->Value( FirstU ));
348     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
349   }
350   Alpha  = Abs( deltaV );
351   if (Alpha > Precision::Angular() && Alpha<Precision::Infinite())
352   {
353     NodeNumber = Max( 4 , Standard_Integer (50. * Alpha / M_PI) );
354     delta = deltaV / (Standard_Real)( NodeNumber - 1 );
355     aPrims = new Graphic3d_ArrayOfPolylines(NodeNumber);
356     for (Standard_Integer i = 1; i <= NodeNumber; i++, FirstV += delta)
357       aPrims->AddVertex(UCurve->Value( FirstV ));
358     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
359   }
360 }
361
362
363 //================================
364 // Function:
365 // Purpose: Rob 26-mar-96
366 //=================================
367
368 void DsgPrs_LengthPresentation::Add (const Handle(Prs3d_Presentation)& aPrs,
369                                      const Handle(Prs3d_Drawer)& aDrawer,
370                                      const gp_Pnt& Pt1,
371                                      const gp_Pnt& Pt2,
372                                      const DsgPrs_ArrowSide ArrowPrs) 
373 {
374   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
375   aPrims->AddVertex(Pt1);
376   aPrims->AddVertex(Pt2);
377   Prs3d_Root::CurrentGroup(aPrs)->AddPrimitiveArray(aPrims);
378
379   gp_Vec V ;
380   switch(ArrowPrs)
381   {
382     case DsgPrs_AS_LASTAR:
383     Prs3d_Arrow::Draw(aPrs,Pt2,gp_Dir(gp_Vec(Pt1,Pt2)), 
384                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
385                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
386     break;
387     case DsgPrs_AS_FIRSTAR:
388     Prs3d_Arrow::Draw(aPrs,Pt1,gp_Dir(gp_Vec(Pt2,Pt1)), 
389                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
390                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
391     break;
392     case DsgPrs_AS_BOTHAR:
393     V = gp_Vec(Pt1,Pt2);
394     Prs3d_Arrow::Draw(aPrs,Pt2,gp_Dir(V), 
395                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
396                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
397     Prs3d_Arrow::Draw(aPrs,Pt1,gp_Dir(V.Reversed()), 
398                       aDrawer->LengthAspect()->Arrow1Aspect()->Angle(),
399                       aDrawer->LengthAspect()->Arrow1Aspect()->Length());
400     break;
401     default:
402     break;
403   }
404 }