359a37172371fb4092039bf2ae7c234bbabfe634
[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
21 #include <DsgPrs_MidPointPresentation.ixx>
22
23 #include <Precision.hxx>
24
25 #include <TCollection_ExtendedString.hxx>
26
27 #include <gp_Lin.hxx>
28 #include <gp_Circ.hxx>
29 #include <gp_Vec.hxx>
30 #include <gp_Dir.hxx>
31 #include <gp_Ax1.hxx>
32 #include <gp_Ax2.hxx>
33 #include <gp_Pnt.hxx>
34
35 #include <ElCLib.hxx>
36
37 #include <Graphic3d_Group.hxx>
38 #include <Graphic3d_Array1OfVertex.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   Graphic3d_Array1OfVertex V(1,2);
62
63   gp_Pnt Ptmp;
64
65   gp_Ax2 ax = theAxe;
66   ax.SetLocation(MidPoint);
67   gp_Circ aCircleM (ax,rad);
68
69   if ( first )
70     {
71       // center of the symmetry - circle around the MidPoint
72       Prs3d_Root::NewGroup(aPresentation);
73       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
74       Standard_Real alpha = 2 * M_PI;
75       Standard_Integer nbp = 100;
76       Graphic3d_Array1OfVertex VC(1,nbp);
77       Standard_Real dteta = alpha/(nbp-1);
78       gp_Pnt ptcur;
79       for (Standard_Integer i = 1; i <= nbp; i++)
80         {
81           ptcur =  ElCLib::Value(dteta*(i-1),aCircleM);
82           VC(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
83         }
84       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC);
85
86       // segment from mid point to the text position
87       Prs3d_Root::NewGroup(aPresentation);
88       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
89       // mid point
90       if ( Position.IsEqual(MidPoint,rad) )
91         Ptmp = MidPoint;
92       else
93         Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM);
94       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
95       // text position
96       V(2).SetCoord(Position.X(),Position.Y(),Position.Z());
97       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
98
99       // texte 
100       TCollection_ExtendedString aText (" (+)");
101       Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
102     }
103
104   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
105     {
106       // segment from mid point to the geometry
107       Prs3d_Root::NewGroup(aPresentation);
108       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
109       // mid point
110       Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM);
111       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
112       // attach point to the geometry
113       V(2).SetCoord(AttachPoint.X(),AttachPoint.Y(),AttachPoint.Z());
114       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
115     }
116 }
117   
118 //===================================================================
119 //Function:Add
120 //Purpose: draws the representation of a radial symmetry between two linear segments.
121 //===================================================================
122 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
123                                        const Handle(Prs3d_Drawer)& aDrawer,     
124                                        const gp_Ax2&  theAxe,
125                                        const gp_Pnt&  MidPoint,
126                                        const gp_Pnt&  Position,
127                                        const gp_Pnt&  AttachPoint,
128                                        const gp_Pnt&  Point1,
129                                        const gp_Pnt&  Point2,
130                                        const Standard_Boolean first)
131 {
132   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
133   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
134
135   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
136   Graphic3d_Array1OfVertex V(1,2);
137
138   gp_Pnt Ptmp;
139
140   gp_Ax2 ax = theAxe;
141   ax.SetLocation(MidPoint);
142   gp_Circ aCircleM (ax,rad);
143
144   if ( first )
145     {
146       // center of the symmetry - circle around the MidPoint
147       Prs3d_Root::NewGroup(aPresentation);
148       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
149       Standard_Real alpha = 2 * M_PI;
150       Standard_Integer nbp = 100;
151       Graphic3d_Array1OfVertex VC(1,nbp);
152       Standard_Real dteta = alpha/(nbp-1);
153       gp_Pnt ptcur;
154       for (Standard_Integer i = 1; i <= nbp; i++)
155         {
156           ptcur =  ElCLib::Value(dteta*(i-1),aCircleM);
157           VC(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
158         }
159       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC);
160
161       // segment from mid point to the text position
162       Prs3d_Root::NewGroup(aPresentation);
163       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
164       // mid point
165       if ( Position.IsEqual(MidPoint,rad) )
166         Ptmp = MidPoint;
167       else
168         Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM);
169       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
170       // text position
171       V(2).SetCoord(Position.X(),Position.Y(),Position.Z());
172       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
173
174       // texte 
175       TCollection_ExtendedString aText (" (+)");
176       Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
177     }
178
179   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
180     {
181       // segment from mid point to the geometry
182       Prs3d_Root::NewGroup(aPresentation);
183       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
184       // mid point
185       Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM);
186       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
187       // attach point to the geometry
188       V(2).SetCoord(AttachPoint.X(),AttachPoint.Y(),AttachPoint.Z());
189       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
190     }
191
192   // segment on line
193   Prs3d_Root::NewGroup(aPresentation);
194   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
195   V(1).SetCoord(Point1.X(),Point1.Y(),Point1.Z());
196   V(2).SetCoord(Point2.X(),Point2.Y(),Point2.Z());
197   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
198 }
199   
200 //===================================================================
201 //Function:Add
202 //Purpose: draws the representation of a radial symmetry between two circular arcs.
203 //===================================================================
204 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
205                                        const Handle(Prs3d_Drawer)& aDrawer,     
206                                        const gp_Circ& aCircle,
207                                        const gp_Pnt&  MidPoint,
208                                        const gp_Pnt&  Position,
209                                        const gp_Pnt&  AttachPoint,
210                                        const gp_Pnt&  Point1,
211                                        const gp_Pnt&  Point2,
212                                        const Standard_Boolean first)
213 {
214   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
215   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
216
217   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
218   Graphic3d_Array1OfVertex V(1,2);
219
220   gp_Pnt Ptmp,ptcur;
221
222   gp_Ax2 ax = aCircle.Position();
223   ax.SetLocation(MidPoint);
224   gp_Circ aCircleM (ax,rad);
225
226   if ( first )
227     {
228       // center of the symmetry - circle around the MidPoint
229       Prs3d_Root::NewGroup(aPresentation);
230       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
231       Standard_Real alpha = 2 * M_PI;
232       Standard_Integer nbp = 100;
233       Graphic3d_Array1OfVertex VC(1,nbp);
234       Standard_Real dteta = alpha/(nbp-1);
235       for (Standard_Integer i = 1; i <= nbp; i++)
236         {
237           ptcur =  ElCLib::Value(dteta*(i-1),aCircleM);
238           VC(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
239         }
240       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC);
241
242       // segment from mid point to the text position
243       Prs3d_Root::NewGroup(aPresentation);
244       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
245       // mid point
246       if ( Position.IsEqual(MidPoint,rad) )
247         Ptmp = MidPoint;
248       else
249         Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM);
250       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
251       // text position
252       V(2).SetCoord(Position.X(),Position.Y(),Position.Z());
253       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
254
255       // texte 
256       TCollection_ExtendedString aText (" (+)");
257       Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
258     }
259
260   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
261     {
262       // segment from mid point to the geometry
263       Prs3d_Root::NewGroup(aPresentation);
264       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
265       // mid point
266       Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM);
267       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
268       // attach point to the geometry
269       V(2).SetCoord(AttachPoint.X(),AttachPoint.Y(),AttachPoint.Z());
270       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
271     }
272
273   // segment on circle
274   Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
275   Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
276   Standard_Real alpha = pl - pf;
277   if ( alpha < 0 ) alpha += 2 * M_PI;
278   Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
279   Standard_Integer nbp = Max(4,nb);
280   Graphic3d_Array1OfVertex VC1(1,nbp);
281   Standard_Real dteta = alpha/(nbp-1);
282
283   for (Standard_Integer i = 1; i <= nbp; i++)
284     {
285       ptcur = ElCLib::Value(pf + dteta*(i-1),aCircle);
286       VC1(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
287     }
288   Prs3d_Root::NewGroup(aPresentation);
289   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
290   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC1);
291 }
292   
293 //===================================================================
294 //Function:Add
295 //Purpose: draws the representation of a radial symmetry between two elliptic arcs.
296 //===================================================================
297 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
298                                        const Handle(Prs3d_Drawer)& aDrawer,     
299                                        const gp_Elips& aCircle,
300                                        const gp_Pnt&   MidPoint,
301                                        const gp_Pnt&   Position,
302                                        const gp_Pnt&   AttachPoint,
303                                        const gp_Pnt&   Point1,
304                                        const gp_Pnt&   Point2,
305                                        const Standard_Boolean first)
306 {
307   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
308   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
309
310   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
311   Graphic3d_Array1OfVertex V(1,2);
312
313   gp_Pnt Ptmp,ptcur;
314
315   gp_Ax2 ax = aCircle.Position();
316   ax.SetLocation(MidPoint);
317   gp_Circ aCircleM (ax,rad);
318
319   if ( first )
320     {
321       // center of the symmetry - circle around the MidPoint
322       Prs3d_Root::NewGroup(aPresentation);
323       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
324       Standard_Real alpha = 2 * M_PI;
325       Standard_Integer nbp = 100;
326       Graphic3d_Array1OfVertex VC(1,nbp);
327       Standard_Real dteta = alpha/(nbp-1);
328       for (Standard_Integer i = 1; i <= nbp; i++)
329         {
330           ptcur =  ElCLib::Value(dteta*(i-1),aCircleM);
331           VC(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
332         }
333       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC);
334
335       // segment from mid point to the text position
336       Prs3d_Root::NewGroup(aPresentation);
337       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
338       // mid point
339       if ( Position.IsEqual(MidPoint,rad) )
340         Ptmp = MidPoint;
341       else
342         Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM);
343       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
344       // text position
345       V(2).SetCoord(Position.X(),Position.Y(),Position.Z());
346       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
347
348       // texte 
349       TCollection_ExtendedString aText (" (+)");
350       Prs3d_Text::Draw(aPresentation,LA->TextAspect(),aText,Position);
351     }
352
353   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
354     {
355       // segment from mid point to the geometry
356       Prs3d_Root::NewGroup(aPresentation);
357       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
358       // mid point
359       Ptmp = ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM);
360       V(1).SetCoord(Ptmp.X(),Ptmp.Y(),Ptmp.Z());
361       // attach point to the geometry
362       V(2).SetCoord(AttachPoint.X(),AttachPoint.Y(),AttachPoint.Z());
363       Prs3d_Root::CurrentGroup(aPresentation)->Polyline(V);
364     }
365
366   // segment on ellipse
367   Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
368   Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
369   Standard_Real alpha = pl - pf;
370   if ( alpha < 0 ) alpha += 2 * M_PI;
371   Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
372   Standard_Integer nbp = Max(4,nb);
373   Graphic3d_Array1OfVertex VC1(1,nbp);
374   Standard_Real dteta = alpha/(nbp-1);
375
376   for (Standard_Integer i = 1; i <= nbp; i++)
377     {
378       ptcur = ElCLib::Value(pf + dteta*(i-1),aCircle);
379       VC1(i).SetCoord(ptcur.X(),ptcur.Y(),ptcur.Z());
380     }
381   Prs3d_Root::NewGroup(aPresentation);
382   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
383   Prs3d_Root::CurrentGroup(aPresentation)->Polyline(VC1);
384 }