0030679: Attached model hangs most of OCCT common functionality
[occt.git] / src / DsgPrs / DsgPrs_MidPointPresentation.cxx
1 // Created on: 2000-10-20
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <DsgPrs_MidPointPresentation.hxx>
18 #include <ElCLib.hxx>
19 #include <gp_Ax1.hxx>
20 #include <gp_Ax2.hxx>
21 #include <gp_Circ.hxx>
22 #include <gp_Dir.hxx>
23 #include <gp_Elips.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Pnt.hxx>
26 #include <gp_Vec.hxx>
27 #include <Graphic3d_ArrayOfPolylines.hxx>
28 #include <Graphic3d_ArrayOfSegments.hxx>
29 #include <Graphic3d_AspectLine3d.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <Precision.hxx>
32 #include <Prs3d_DimensionAspect.hxx>
33 #include <Prs3d_LineAspect.hxx>
34 #include <Prs3d_Presentation.hxx>
35 #include <Prs3d_Root.hxx>
36 #include <Prs3d_Text.hxx>
37 #include <TCollection_ExtendedString.hxx>
38
39 //===================================================================
40 //Function:Add
41 //Purpose: draws the representation of a radial symmetry between two vertices.
42 //===================================================================
43 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
44                                        const Handle(Prs3d_Drawer)& aDrawer,     
45                                        const gp_Ax2&  theAxe,
46                                        const gp_Pnt&  MidPoint,
47                                        const gp_Pnt&  Position,
48                                        const gp_Pnt&  AttachPoint,
49                                        const Standard_Boolean first)
50
51   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
52
53   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
54
55   gp_Ax2 ax = theAxe;
56   ax.SetLocation(MidPoint);
57   gp_Circ aCircleM (ax,rad);
58
59   if ( first )
60   {
61     // center of the symmetry - circle around the MidPoint
62     Prs3d_Root::NewGroup(aPresentation);
63     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
64
65     const Standard_Real alpha = 2. * M_PI;
66     const Standard_Integer nbp = 100;
67     const Standard_Real dteta = alpha/(nbp-1);
68
69     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
70     aPrims->AddBound(nbp);
71     for (Standard_Integer i = 1; i <= nbp; i++)
72       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
73
74     // segment from mid point to the text position
75     aPrims->AddBound(2);
76     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
77     aPrims->AddVertex(Position); // text position
78
79         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
80
81     // texte 
82     TCollection_ExtendedString aText(" (+)");
83     Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, Position);
84   }
85
86   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
87   {
88     if ( !first )
89     {
90       Prs3d_Root::NewGroup(aPresentation);
91       Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
92     }
93
94     // segment from mid point to the geometry
95     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
96     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
97     aPrims->AddVertex(AttachPoint); // attach point to the geometry
98     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
99   }
100 }
101   
102 //===================================================================
103 //Function:Add
104 //Purpose: draws the representation of a radial symmetry between two linear segments.
105 //===================================================================
106 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
107                                        const Handle(Prs3d_Drawer)& aDrawer,     
108                                        const gp_Ax2&  theAxe,
109                                        const gp_Pnt&  MidPoint,
110                                        const gp_Pnt&  Position,
111                                        const gp_Pnt&  AttachPoint,
112                                        const gp_Pnt&  Point1,
113                                        const gp_Pnt&  Point2,
114                                        const Standard_Boolean first)
115 {
116   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
117   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
118
119   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
120
121   gp_Ax2 ax = theAxe;
122   ax.SetLocation(MidPoint);
123   gp_Circ aCircleM (ax,rad);
124
125   // segment on line
126   Prs3d_Root::NewGroup(aPresentation);
127   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
128
129   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
130   aPrims->AddVertex(Point1);
131   aPrims->AddVertex(Point2);
132   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
133
134   if ( first )
135   {
136     // center of the symmetry - circle around the MidPoint
137     const Standard_Real alpha = 2. * M_PI;
138     const Standard_Integer nbp = 100;
139     const Standard_Real dteta = alpha/(nbp-1);
140
141     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
142     aPrims->AddBound(nbp);
143     for (Standard_Integer i = 1; i <= nbp; i++)
144       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
145
146     // segment from mid point to the text position
147     aPrims->AddBound(2);
148     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
149     aPrims->AddVertex(Position); // text position
150
151         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
152
153     // texte
154     TCollection_ExtendedString aText (" (+)");
155     Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, Position);
156   }
157
158   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
159   {
160     // mid point
161     aPrims = new Graphic3d_ArrayOfSegments(2);
162     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM));
163     aPrims->AddVertex(AttachPoint); // attach point to the geometry
164     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
165   }
166 }
167   
168 //===================================================================
169 //Function:Add
170 //Purpose: draws the representation of a radial symmetry between two circular arcs.
171 //===================================================================
172 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
173                                        const Handle(Prs3d_Drawer)& aDrawer,     
174                                        const gp_Circ& aCircle,
175                                        const gp_Pnt&  MidPoint,
176                                        const gp_Pnt&  Position,
177                                        const gp_Pnt&  AttachPoint,
178                                        const gp_Pnt&  Point1,
179                                        const gp_Pnt&  Point2,
180                                        const Standard_Boolean first)
181 {
182   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
183   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
184
185   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
186
187   gp_Ax2 ax = aCircle.Position();
188   ax.SetLocation(MidPoint);
189   gp_Circ aCircleM (ax,rad);
190
191   // segment on circle
192   Prs3d_Root::NewGroup(aPresentation);
193   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
194
195   const Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
196   const Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
197   Standard_Real alpha = pl - pf;
198   if ( alpha < 0 ) alpha += 2. * M_PI;
199   const Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
200   Standard_Integer nbp = Max(4,nb);
201   Standard_Real dteta = alpha/(nbp-1);
202
203   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
204   for (Standard_Integer i = 1; i <= nbp; i++)
205     aPrims->AddVertex(ElCLib::Value(pf + dteta*(i-1),aCircle));
206   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
207
208   if ( first )
209   {
210     // center of the symmetry - circle around the MidPoint
211     alpha = 2. * M_PI;
212     nbp = 100;
213     dteta = alpha/(nbp-1);
214
215     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
216     aPrims->AddBound(nbp);
217     for (Standard_Integer i = 1; i <= nbp; i++)
218       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
219
220     // segment from mid point to the text position
221     aPrims->AddBound(2);
222     aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
223     aPrims->AddVertex(Position); // text position
224
225         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
226
227     // texte 
228     TCollection_ExtendedString aText (" (+)");
229     Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, Position);
230   }
231
232   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
233   {
234     // segment from mid point to the geometry
235     aPrims = new Graphic3d_ArrayOfSegments(2);
236     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
237     aPrims->AddVertex(AttachPoint); // attach point to the geometry
238     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
239   }
240 }
241   
242 //===================================================================
243 //Function:Add
244 //Purpose: draws the representation of a radial symmetry between two elliptic arcs.
245 //===================================================================
246 void DsgPrs_MidPointPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
247                                        const Handle(Prs3d_Drawer)& aDrawer,     
248                                        const gp_Elips& aCircle,
249                                        const gp_Pnt&   MidPoint,
250                                        const gp_Pnt&   Position,
251                                        const gp_Pnt&   AttachPoint,
252                                        const gp_Pnt&   Point1,
253                                        const gp_Pnt&   Point2,
254                                        const Standard_Boolean first)
255 {
256   Standard_Real rad = AttachPoint.Distance(MidPoint)/20.0;
257   if ( rad <= Precision::Confusion() ) rad = Point1.Distance(Point2)/20.0;
258
259   Handle(Prs3d_DimensionAspect) LA = aDrawer->DimensionAspect();
260
261   gp_Pnt Ptmp,ptcur;
262
263   gp_Ax2 ax = aCircle.Position();
264   ax.SetLocation(MidPoint);
265   gp_Circ aCircleM (ax,rad);
266
267   // segment on ellipse
268   Prs3d_Root::NewGroup(aPresentation);
269   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
270
271   const Standard_Real pf = ElCLib::Parameter(aCircle,Point1);
272   const Standard_Real pl = ElCLib::Parameter(aCircle,Point2);
273   Standard_Real alpha = pl - pf;
274   if ( alpha < 0 ) alpha += 2 * M_PI;
275   const Standard_Integer nb = (Standard_Integer)(50.0*alpha/M_PI);
276   Standard_Integer nbp = Max(4,nb);
277   Standard_Real dteta = alpha/(nbp-1);
278
279   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfPolylines(nbp);
280   for (Standard_Integer i = 1; i <= nbp; i++)
281     aPrims->AddVertex(ElCLib::Value(pf + dteta*(i-1),aCircle));
282   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
283
284   if ( first )
285   {
286     // center of the symmetry - circle around the MidPoint
287     alpha = 2. * M_PI;
288     nbp = 100;
289     dteta = alpha/(nbp-1);
290
291     aPrims = new Graphic3d_ArrayOfPolylines(nbp+2,2);
292     aPrims->AddBound(nbp);
293     for (Standard_Integer i = 1; i <= nbp; i++)
294       aPrims->AddVertex(ElCLib::Value(dteta*(i-1),aCircleM));
295
296     // segment from mid point to the text position
297     aPrims->AddBound(2);
298         aPrims->AddVertex(Position.IsEqual(MidPoint,rad)? MidPoint : ElCLib::Value(ElCLib::Parameter(aCircleM,Position),aCircleM)); // mid point
299     aPrims->AddVertex(Position); // text position
300
301         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
302
303     // texte 
304     TCollection_ExtendedString aText (" (+)");
305     Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (aPresentation), LA->TextAspect(), aText, Position);
306   }
307
308   if ( !AttachPoint.IsEqual(MidPoint, Precision::Confusion()) )
309   {
310     // segment from mid point to the geometry
311     aPrims = new Graphic3d_ArrayOfSegments(2);
312     aPrims->AddVertex(ElCLib::Value(ElCLib::Parameter(aCircleM,AttachPoint),aCircleM)); // mid point
313     aPrims->AddVertex(AttachPoint); // attach point to the geometry
314     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
315   }
316 }