0024131: TKOpenGL redesign GPU memory management for markers presentation
[occt.git] / src / DsgPrs / DsgPrs_MidPointPresentation.cxx
1 // Created on: 2000-10-20
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2000-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #include <DsgPrs_MidPointPresentation.ixx>
21
22 #include <Precision.hxx>
23
24 #include <TCollection_ExtendedString.hxx>
25
26 #include <gp_Lin.hxx>
27 #include <gp_Circ.hxx>
28 #include <gp_Vec.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Ax1.hxx>
31 #include <gp_Ax2.hxx>
32 #include <gp_Pnt.hxx>
33
34 #include <ElCLib.hxx>
35
36 #include <Graphic3d_Group.hxx>
37 #include <Graphic3d_ArrayOfSegments.hxx>
38 #include <Graphic3d_ArrayOfPolylines.hxx>
39 #include <Graphic3d_AspectLine3d.hxx>
40
41 #include <Prs3d_Root.hxx>
42 #include <Prs3d_LineAspect.hxx>
43 #include <Prs3d_LengthAspect.hxx>
44 #include <Prs3d_Text.hxx>
45
46 //===================================================================
47 //Function:Add
48 //Purpose: draws the representation of a radial symmetry between two vertices.
49 //===================================================================
50 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
51                                        const Handle(Prs3d_Drawer)& aDrawer,     
52                                        const gp_Ax2&  theAxe,
53                                        const gp_Pnt&  MidPoint,
54                                        const gp_Pnt&  Position,
55                                        const gp_Pnt&  AttachPoint,
56                                        const Standard_Boolean first)
57
58   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
59
60   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
61
62   gp_Ax2 ax = theAxe;
63   ax.SetLocation(MidPoint);
64   gp_Circ aCircleM (ax,rad);
65
66   if ( first )
67   {
68     // center of the symmetry - circle around the MidPoint
69     Prs3d_Root::NewGroup(aPresentation);
70     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
71
72     const Standard_Real alpha = 2. * M_PI;
73     const Standard_Integer nbp = 100;
74     const Standard_Real dteta = alpha/(nbp-1);
75
76     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
77     aPrims->AddBound(nbp);
78     for (Standard_Integer i = 1; i <= nbp; i++)
79       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
80
81     // segment from mid point to the text position
82     aPrims->AddBound(2);
83     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
84     aPrims->AddVertex(Position); // text position
85
86         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
87
88     // texte 
89     TCollection_ExtendedString aText(" (+)");
90     Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
91   }
92
93   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
94   {
95     if ( !first )
96     {
97       Prs3d_Root::NewGroup(aPresentation);
98       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
99     }
100
101     // segment from mid point to the geometry
102     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
103     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
104     aPrims->AddVertex(AttachPoint); // attach point to the geometry
105     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
106   }
107 }
108   
109 //===================================================================
110 //Function:Add
111 //Purpose: draws the representation of a radial symmetry between two linear segments.
112 //===================================================================
113 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
114                                        const Handle(Prs3d_Drawer)& aDrawer,     
115                                        const gp_Ax2&  theAxe,
116                                        const gp_Pnt&  MidPoint,
117                                        const gp_Pnt&  Position,
118                                        const gp_Pnt&  AttachPoint,
119                                        const gp_Pnt&  Point1,
120                                        const gp_Pnt&  Point2,
121                                        const Standard_Boolean first)
122 {
123   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
124   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
125
126   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
127
128   gp_Ax2 ax = theAxe;
129   ax.SetLocation(MidPoint);
130   gp_Circ aCircleM (ax,rad);
131
132   // segment on line
133   Prs3d_Root::NewGroup(aPresentation);
134   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
135
136   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
137   aPrims->AddVertex(Point1);
138   aPrims->AddVertex(Point2);
139   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
140
141   if ( first )
142   {
143     // center of the symmetry - circle around the MidPoint
144     const Standard_Real alpha = 2. * M_PI;
145     const Standard_Integer nbp = 100;
146     const Standard_Real dteta = alpha/(nbp-1);
147
148     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
149     aPrims->AddBound(nbp);
150     for (Standard_Integer i = 1; i <= nbp; i++)
151       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
152
153     // segment from mid point to the text position
154     aPrims->AddBound(2);
155     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
156     aPrims->AddVertex(Position); // text position
157
158         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
159
160     // texte
161     TCollection_ExtendedString aText (" (+)");
162     Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
163   }
164
165   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
166   {
167     // mid point
168     aPrims = new Graphic3d_ArrayOfSegments(2);
169     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM));
170     aPrims->AddVertex(AttachPoint); // attach point to the geometry
171     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
172   }
173 }
174   
175 //===================================================================
176 //Function:Add
177 //Purpose: draws the representation of a radial symmetry between two circular arcs.
178 //===================================================================
179 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
180                                        const Handle(Prs3d_Drawer)& aDrawer,     
181                                        const gp_Circ& aCircle,
182                                        const gp_Pnt&  MidPoint,
183                                        const gp_Pnt&  Position,
184                                        const gp_Pnt&  AttachPoint,
185                                        const gp_Pnt&  Point1,
186                                        const gp_Pnt&  Point2,
187                                        const Standard_Boolean first)
188 {
189   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
190   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
191
192   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
193
194   gp_Ax2 ax = aCircle.Position();
195   ax.SetLocation(MidPoint);
196   gp_Circ aCircleM (ax,rad);
197
198   // segment on circle
199   Prs3d_Root::NewGroup(aPresentation);
200   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
201
202   const Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
203   const Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
204   Standard_Real alpha = pl - pf;
205   if ( alpha < 0 ) alpha += 2. * M_PI;
206   const Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
207   Standard_Integer nbp = Max(4,nb);
208   Standard_Real dteta = alpha/(nbp-1);
209
210   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
211   for (Standard_Integer i = 1; i <= nbp; i++)
212     aPrims->AddVertex(ElCLib::Value(pf + dteta*(i-1),aCircle));
213   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
214
215   if ( first )
216   {
217     // center of the symmetry - circle around the MidPoint
218     alpha = 2. * M_PI;
219     nbp = 100;
220     dteta = alpha/(nbp-1);
221
222     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
223     aPrims->AddBound(nbp);
224     for (Standard_Integer i = 1; i <= nbp; i++)
225       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
226
227     // segment from mid point to the text position
228     aPrims->AddBound(2);
229     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
230     aPrims->AddVertex(Position); // text position
231
232         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
233
234     // texte 
235     TCollection_ExtendedString aText (" (+)");
236     Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
237   }
238
239   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
240   {
241     // segment from mid point to the geometry
242     aPrims = new Graphic3d_ArrayOfSegments(2);
243     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
244     aPrims->AddVertex(AttachPoint); // attach point to the geometry
245     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
246   }
247 }
248   
249 //===================================================================
250 //Function:Add
251 //Purpose: draws the representation of a radial symmetry between two elliptic arcs.
252 //===================================================================
253 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
254                                        const Handle(Prs3d_Drawer)& aDrawer,     
255                                        const gp_Elips& aCircle,
256                                        const gp_Pnt&   MidPoint,
257                                        const gp_Pnt&   Position,
258                                        const gp_Pnt&   AttachPoint,
259                                        const gp_Pnt&   Point1,
260                                        const gp_Pnt&   Point2,
261                                        const Standard_Boolean first)
262 {
263   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
264   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
265
266   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
267
268   gp_Pnt Ptmp,ptcur;
269
270   gp_Ax2 ax = aCircle.Position();
271   ax.SetLocation(MidPoint);
272   gp_Circ aCircleM (ax,rad);
273
274   // segment on ellipse
275   Prs3d_Root::NewGroup(aPresentation);
276   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
277
278   const Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
279   const Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
280   Standard_Real alpha = pl - pf;
281   if ( alpha < 0 ) alpha += 2 * M_PI;
282   const Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
283   Standard_Integer nbp = Max(4,nb);
284   Standard_Real dteta = alpha/(nbp-1);
285
286   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
287   for (Standard_Integer i = 1; i <= nbp; i++)
288     aPrims->AddVertex(ElCLib::Value(pf + dteta*(i-1),aCircle));
289   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
290
291   if ( first )
292   {
293     // center of the symmetry - circle around the MidPoint
294     alpha = 2. * M_PI;
295     nbp = 100;
296     dteta = alpha/(nbp-1);
297
298     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
299     aPrims->AddBound(nbp);
300     for (Standard_Integer i = 1; i <= nbp; i++)
301       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
302
303     // segment from mid point to the text position
304     aPrims->AddBound(2);
305         aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
306     aPrims->AddVertex(Position); // text position
307
308         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
309
310     // texte 
311     TCollection_ExtendedString aText (" (+)");
312     Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
313   }
314
315   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
316   {
317     // segment from mid point to the geometry
318     aPrims = new Graphic3d_ArrayOfSegments(2);
319     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
320     aPrims->AddVertex(AttachPoint); // attach point to the geometry
321     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
322   }
323 }