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