0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / DsgPrs / DsgPrs_SymmetricPresentation.cxx
1 // Created on: 1997-01-22
2 // Created by: Prestataire Michael ALEONARD
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 #include <DsgPrs_SymmetricPresentation.ixx>
22
23 #include <Precision.hxx>
24
25 #include <gp_Lin.hxx>
26 #include <gp_Circ.hxx>
27 #include <gp_Vec.hxx>
28 #include <gp_Dir.hxx>
29 #include <gp_Ax1.hxx>
30 #include <gp_Ax2.hxx>
31 #include <gp_Pnt.hxx>
32 #include <gp_Pnt2d.hxx>
33
34 #include <Geom_Plane.hxx>
35 #include <Geom_Line.hxx>
36
37 #include <ElCLib.hxx>
38
39 #include <gce_MakeLin.hxx>
40 #include <gce_MakeDir.hxx>
41
42 #include <Graphic3d_Group.hxx>
43 #include <Graphic3d_ArrayOfSegments.hxx>
44 #include <Graphic3d_ArrayOfPolylines.hxx>
45 #include <Graphic3d_AspectLine3d.hxx>
46 #include <Graphic3d_AspectMarker3d.hxx>
47 #include <Graphic3d_Vertex.hxx>
48
49 #include <Prs3d_Arrow.hxx>
50 #include <Prs3d_ArrowAspect.hxx>
51 #include <Prs3d_LineAspect.hxx>
52 #include <Prs3d_LengthAspect.hxx>
53
54 #include <TCollection_AsciiString.hxx>
55
56 #include <Geom2d_Line.hxx>
57
58 #include <GeomAPI.hxx>
59
60 #include <IntAna2d_AnaIntersection.hxx>
61
62
63 //===================================================================
64 //Function:Add
65 //Purpose: draws the representation of an axial symmetry between two segments.
66 //===================================================================
67 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
68                                         const Handle(Prs3d_Drawer)& aDrawer,    
69                                         const gp_Pnt& AttachmentPoint1,
70                                         const gp_Pnt& AttachmentPoint2,
71                                         const gp_Dir& aDirection1,
72                                         const gp_Lin& aAxis,
73                                         const gp_Pnt& OffsetPoint)
74
75   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
76   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
77
78   gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(aAxis,OffsetPoint),aAxis);
79   gp_Pnt PjAttachPnt1    = ElCLib::Value(ElCLib::Parameter(aAxis,AttachmentPoint1),aAxis);
80   gp_Dir aDirectionAxis  = aAxis.Direction();
81   Standard_Real h = fabs(ProjOffsetPoint.Distance(PjAttachPnt1)/cos(aDirectionAxis.Angle(aDirection1)));
82   
83   gp_Vec VL1(aDirection1);
84   gp_Vec VLa(PjAttachPnt1,ProjOffsetPoint);
85   Standard_Real scal;
86   scal = VL1.Dot(VLa);
87   if (scal < 0) VL1.Reverse();
88   VL1.Multiply(h);
89
90   gp_Pnt P1,P2;
91
92   //===================================
93   // SYMETRY OF EDGE PERPEND. TO THE AXIS    
94   //   ____        :        ____
95   // edge2 |       : -=-   | edge 1
96   //       |<------:------>|
97   //               :        
98   //===================================
99
100   if (VLa.Dot(VL1) == 0) {
101     P1 = AttachmentPoint1.Translated(VLa);
102     gp_Vec VPntat2Axe(PjAttachPnt1,AttachmentPoint2);  
103     P2 = ProjOffsetPoint.Translated(VPntat2Axe);
104   }
105   else {
106     P1 = AttachmentPoint1.Translated(VL1);
107     gp_Vec VPntat1Axe(P1,ProjOffsetPoint);
108     P2 = ProjOffsetPoint.Translated(VPntat1Axe);
109   }
110
111   gp_Lin L3 = gce_MakeLin(P1,P2);
112   Standard_Real parmin,parmax,parcur;
113   parmin = ElCLib::Parameter(L3,P1);
114   parmax = parmin;
115   parcur = ElCLib::Parameter(L3,P2);
116   Standard_Real dist = Abs(parmin-parcur);
117   if (parcur < parmin) parmin = parcur;
118   if (parcur > parmax) parmax = parcur;
119   parcur = ElCLib::Parameter(L3,OffsetPoint);
120   gp_Pnt offp = ElCLib::Value(parcur,L3);
121
122   Standard_Boolean outside = Standard_False;
123   if (parcur < parmin) {
124     parmin = parcur;
125     outside = Standard_True;
126   }
127   if (parcur > parmax) {
128     parmax = parcur;
129     outside = Standard_True;
130   }
131
132   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
133   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
134
135   Quantity_Length X,Y,Z;
136   Standard_Real D1(aAxis.Distance(AttachmentPoint1)),coeff(.5);
137   gp_Pnt pint,Pj_P1,P1Previous = P1;
138   
139   //=======================================================
140   // TO AVOID CROSSING
141   //        P1  -=- P2                P2  -=- P1         
142   //          \<-->/                    |<-->|
143   //           \  /                     |    |
144   //            \/                      |    | 
145   //            /\                      |    |
146   //           /  \                     |    |
147   // Pattach2 /____\ Pattach1 Pattach2 /______\ Pattach1
148   //         /  NO \                  /   YES  \
149   //=======================================================
150
151   Standard_Boolean Cross = Standard_False;
152   gp_Vec Attch1_PjAttch1(AttachmentPoint1,PjAttachPnt1);
153   gp_Vec v(P1,ProjOffsetPoint);
154   if (v.IsOpposite((Attch1_PjAttch1),Precision::Confusion())){
155     Cross = Standard_True;
156     gp_Pnt PntTempo;
157     PntTempo = P1;
158     P1       = P2;
159     P2       = PntTempo;
160   }  
161   //===================================
162   // FRACTURES OF TRAITS OF CALL    
163   //        /             \         
164   //       /               \
165   //       |      -=-      |
166   //       |<------------->| 
167   //===================================
168
169   gp_Vec        Vfix;
170   Standard_Real alpha,b;
171
172   if(aAxis.Distance(P1) > D1*(1 + coeff) && !Cross){
173
174     //==== PROCESSING OF FACE ===========
175     Prs3d_Root::NewGroup(aPresentation);
176     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
177
178     Pj_P1 = ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis);
179     gp_Vec Vp(Pj_P1,P1);
180     Vfix = Vp.Divided(Vp.Magnitude()).Multiplied(D1*(1 + coeff));
181     P1 = Pj_P1.Translated(Vfix);
182     P2 = Pj_P1.Translated(Vfix.Reversed());
183
184     //=================================
185     // LISTING AT THE EXTERIOR
186     //                        -=-
187     //      ->|----------|<------
188     //        |          |
189     //=================================
190     
191     L3 = gce_MakeLin(P1,P2);
192     parmin = ElCLib::Parameter(L3,P1);
193     parmax = parmin;
194     parcur = ElCLib::Parameter(L3,P2);
195     dist = Abs(parmin-parcur);
196     if (parcur < parmin) parmin = parcur;
197     if (parcur > parmax) parmax = parcur;
198     parcur = ElCLib::Parameter(L3,OffsetPoint);
199     offp = ElCLib::Value(parcur,L3);  
200     outside = Standard_False;
201     if (parcur < parmin) {
202       parmin = parcur;
203       outside = Standard_True;
204     }
205     if (parcur > parmax) {
206       parmax = parcur;
207       outside = Standard_True;
208     }    
209     PointMin = ElCLib::Value(parmin,L3);
210     PointMax = ElCLib::Value(parmax,L3);
211
212     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(8,3);
213
214     aPrims->AddBound(2);
215     aPrims->AddVertex(PointMin);
216     aPrims->AddVertex(PointMax);
217     
218     //==== PROCESSING OF CALL 1 =====
219     alpha = aDirectionAxis.Angle(aDirection1);
220     b = (coeff*D1)/sin(alpha);
221     gp_Vec Vpint(AttachmentPoint1,P1Previous);
222     pint = AttachmentPoint1.Translated(Vpint.Divided(Vpint.Magnitude()).Multiplied(b));
223
224     aPrims->AddBound(3);
225     aPrims->AddVertex(AttachmentPoint1);
226     aPrims->AddVertex(pint);
227     aPrims->AddVertex(P1);
228
229     //==== PROCESSING OF CALL 2 =====
230     gp_Pnt Pj_pint  = ElCLib::Value(ElCLib::Parameter(aAxis,pint),aAxis);
231     gp_Vec V_int(pint, Pj_pint);
232     gp_Pnt Sym_pint = Pj_pint.Translated(V_int);
233
234     aPrims->AddBound(3);
235     aPrims->AddVertex(AttachmentPoint2);
236     aPrims->AddVertex(Sym_pint);
237     aPrims->AddVertex(P2);
238
239         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
240   }
241
242   //===================================
243   // FRACTURES OF PROCESSING OF CALL    
244   //              -=-    
245   //         |<--------->| 
246   //         |           |   
247   //        /             \         
248   //       /               \
249   //===================================
250   else if (aAxis.Distance(P1) < D1*(1 - coeff) || Cross) {
251
252     //------ PROCESSING OF FACE ------------
253     Prs3d_Root::NewGroup(aPresentation);
254     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
255
256     Pj_P1 = ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis);
257     gp_Vec VpInf(Pj_P1,P1);
258     Vfix = VpInf.Divided(VpInf.Magnitude()).Multiplied(D1*(1 - coeff));
259     Pj_P1.Translated(Vfix).Coord(X,Y,Z);
260     P1.SetCoord(X,Y,Z);
261     Pj_P1.Translated(Vfix.Reversed()).Coord(X,Y,Z);
262     P2.SetCoord(X,Y,Z);
263
264     //=================================
265     // LISTING AT THE EXTERIOR
266     //                        -=-
267     //      ->|----------|<------
268     //        |          |
269     //=================================
270     L3 = gce_MakeLin(P1,P2);
271     parmin = ElCLib::Parameter(L3,P1);
272     parmax = parmin;
273     parcur = ElCLib::Parameter(L3,P2);
274     dist = Abs(parmin-parcur);
275     if (parcur < parmin) parmin = parcur;
276     if (parcur > parmax) parmax = parcur;
277     parcur = ElCLib::Parameter(L3,OffsetPoint);
278     offp = ElCLib::Value(parcur,L3);  
279     outside = Standard_False;
280     if (parcur < parmin) {
281       parmin = parcur;
282       outside = Standard_True;
283     }
284     if (parcur > parmax) {
285       parmax = parcur;
286       outside = Standard_True;
287     }    
288     PointMin = ElCLib::Value(parmin,L3);
289     PointMax = ElCLib::Value(parmax,L3);
290
291     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(8,3);
292
293     aPrims->AddBound(2);
294         aPrims->AddVertex(PointMin);
295     aPrims->AddVertex(PointMax);
296     
297     //==== PROCESSING OF CALL 1 =====
298     alpha = aDirectionAxis.Angle(aDirection1);
299     b = (coeff*D1)/sin(alpha);
300     gp_Vec Vpint(AttachmentPoint1,P1Previous);
301     pint = AttachmentPoint1.Translated(Vpint.Divided(Vpint.Magnitude()).Multiplied(b));
302
303     aPrims->AddBound(3);
304     aPrims->AddVertex(AttachmentPoint1);
305     aPrims->AddVertex(pint);
306     aPrims->AddVertex(P1);
307     
308     //==== PROCESSING OF CALL 2 =====
309     gp_Pnt Pj_pint  = ElCLib::Value(ElCLib::Parameter(aAxis,pint),aAxis);
310     gp_Vec V_int(pint, Pj_pint);
311     gp_Pnt Sym_pint = Pj_pint.Translated(V_int);
312
313     aPrims->AddBound(3);
314     aPrims->AddVertex(AttachmentPoint2);
315     aPrims->AddVertex(Sym_pint);
316     aPrims->AddVertex(P2);
317
318         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
319   }
320   else {
321     
322     //==== PROCESSING OF FACE ===========
323     Prs3d_Root::NewGroup(aPresentation);
324     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
325
326     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(6);
327
328         aPrims->AddVertex(PointMin);
329     aPrims->AddVertex(PointMax);
330     
331     //==== PROCESSING OF CALL 1 =====
332     aPrims->AddVertex(AttachmentPoint1);
333     aPrims->AddVertex(P1);
334
335     //==== PROCESSING OF CALL 2 =====
336     aPrims->AddVertex(AttachmentPoint2);
337     aPrims->AddVertex(P2);
338
339         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
340   }
341
342   //==== ARROWS ================
343   Prs3d_Root::NewGroup(aPresentation);
344   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
345   
346   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) outside = Standard_True;
347   gp_Dir arrdir = L3.Direction().Reversed();
348   if (outside) arrdir.Reverse();
349   // arrow 1 ----
350   Prs3d_Arrow::Draw(aPresentation,P1,arrdir,LA->Arrow1Aspect()->Angle(),LA->Arrow1Aspect()->Length());
351   
352   // arrow 2 ----
353   Prs3d_Arrow::Draw(aPresentation,P2,arrdir.Reversed(),LA->Arrow2Aspect()->Angle(),LA->Arrow2Aspect()->Length());
354
355   //-------------------------------------------------------------------------------------
356   //|                                SYMBOL OF SYMMETRY                                 |
357   //-------------------------------------------------------------------------------------
358
359   //           -------    : Superior Segment 
360   //         -----------  : Axis
361   //           -------    : Inferior Segment 
362   
363   gp_Vec Vvar(P1,P2);
364   gp_Vec vec;
365   gp_Vec Vtmp = Vvar.Divided(Vvar.Magnitude()).Multiplied((aAxis.Distance(AttachmentPoint1)+
366                                                            aAxis.Distance(AttachmentPoint2)));
367   vec.SetCoord(Vtmp.X(),Vtmp.Y(),Vtmp.Z());
368   gp_Vec vecA = vec.Multiplied(.1);
369
370   gp_Dir DirAxis = aAxis.Direction();
371   gp_Vec Vaxe(DirAxis);
372   gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
373   vecB.Multiply(.5);
374
375   gp_Pnt pm,pOff;
376   if (VLa.Dot(VL1) == 0) {
377     gp_Vec Vper(P1,ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis));
378     pm = P1.Translated(Vper);
379   }
380   else {
381     pm = P1.Translated(Vvar.Multiplied(.5));
382   }
383   pOff = OffsetPoint.Translated(vecB);
384   
385   //Calculate the extremities of the symbol axis
386   gp_Vec vecAxe = vecA.Multiplied(.7);
387
388   Prs3d_Root::NewGroup(aPresentation);
389   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
390
391   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(13,5);
392
393   aPrims->AddBound(2);
394   aPrims->AddVertex(pOff.Translated(vecAxe));
395   aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
396
397   //Calculate the extremities of the superior segment of the symbol
398   gp_Vec vec1 = vecAxe.Multiplied(.6);
399   vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
400   gp_Vec vec2 = vecAxe.Multiplied(.4);
401
402   aPrims->AddBound(2);
403   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
404   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
405
406   //Calculate the extremities of the inferior segment of the symbol
407   aPrims->AddBound(2);
408   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
409   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
410
411   //--------------------------------------------------------------------------------------
412   //|                          MARKING OF THE SYMMETRY AXIS                             |
413   //--------------------------------------------------------------------------------------     
414   //        ____
415   //        \  / :Cursor
416   //         \/
417   //         /\
418   //        /__\
419
420   Standard_Real Dist = (aAxis.Distance(AttachmentPoint1)+aAxis.Distance(AttachmentPoint2))/75;
421   gp_Vec vs(aDirectionAxis);
422   gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
423   gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
424   
425   aPrims->AddBound(5);
426   gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
427   aPrims->AddVertex(pm1);
428   pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
429   aPrims->AddVertex(pm1);
430   pm1 = pm1.Translated(vsymper.Multiplied(2));
431   aPrims->AddVertex(pm1);
432   pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
433   aPrims->AddVertex(pm1);
434   pm1 = pm1.Translated(vsymper.Multiplied(2));
435   aPrims->AddVertex(pm1);
436
437   vsym.Multiply(4);
438
439   aPrims->AddBound(2);
440   aPrims->AddVertex(pm.Translated(vsym));
441   aPrims->AddVertex(pm.Translated(vsym.Reversed()));
442
443   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
444 }
445   
446 //===================================================================
447 //Function:Add
448 //Purpose: draws the representation of an axial symmetry between two arcs.
449 //===================================================================
450 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
451                                         const Handle(Prs3d_Drawer)& aDrawer,    
452                                         const gp_Pnt&  AttachmentPoint1,
453                                         const gp_Pnt&  AttachmentPoint2,
454                                         const gp_Circ& aCircle1,
455                                         const gp_Lin&  aAxis,
456                                         const gp_Pnt&  OffsetPoint)
457 {
458   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
459   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());  
460
461   gp_Pnt OffsetPnt(OffsetPoint.X(),OffsetPoint.Y(),OffsetPoint.Z());
462   gp_Pnt Center1 = aCircle1.Location();
463   gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(aAxis,OffsetPnt),aAxis);
464   gp_Pnt ProjCenter1     = ElCLib::Value(ElCLib::Parameter(aAxis,Center1),aAxis);
465   gp_Vec Vp(ProjCenter1,Center1);
466   if (Vp.Magnitude() <= Precision::Confusion()) Vp = gp_Vec(aAxis.Direction())^aCircle1.Position().Direction();
467
468   Standard_Real Dt,R,h;
469   Dt = ProjCenter1.Distance(ProjOffsetPoint);
470   R  = aCircle1.Radius();
471   if (Dt > .999*R) {
472     Dt = .999*R;
473     gp_Vec Vout(ProjCenter1,ProjOffsetPoint);
474     ProjOffsetPoint = ProjCenter1.Translated(Vout.Divided(Vout.Magnitude()).Multiplied(Dt));
475     OffsetPnt = ProjOffsetPoint;
476   }
477   h  = Sqrt(R*R - Dt*Dt);
478   gp_Pnt P1 = ProjOffsetPoint.Translated(Vp.Added(Vp.Divided(Vp.Magnitude()).Multiplied(h)));
479   gp_Vec v(P1,ProjOffsetPoint);
480   gp_Pnt P2 = ProjOffsetPoint.Translated(v);
481
482   gp_Lin L3 = gce_MakeLin(P1,P2);
483   Standard_Real parmin,parmax,parcur;
484   parmin = ElCLib::Parameter(L3,P1);
485   parmax = parmin;
486   parcur = ElCLib::Parameter(L3,P2);
487   Standard_Real dist = Abs(parmin-parcur);
488   if (parcur < parmin) parmin = parcur;
489   if (parcur > parmax) parmax = parcur;
490   parcur = ElCLib::Parameter(L3,OffsetPnt);
491
492   Standard_Boolean outside = Standard_False;
493   if (parcur < parmin) {
494     parmin = parcur;
495     outside = Standard_True;
496   }
497   if (parcur > parmax) {
498     parmax = parcur;
499     outside = Standard_True;
500   }
501   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
502   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
503
504   //==== PROCESSING OF FACE ===========
505   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
506   aPrims->AddVertex(PointMin);
507   aPrims->AddVertex(PointMax);
508   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
509
510   //==== PROCESSING OF CALL 1 =====
511   Standard_Integer nbp = 10;
512   Standard_Real ParamP1       = ElCLib::Parameter(aCircle1,P1);
513   Standard_Real ParamPAttach1 = ElCLib::Parameter(aCircle1,AttachmentPoint1);
514   Standard_Real alpha,Dalpha,alphaIter;
515
516   alpha = fabs(ParamP1 - ParamPAttach1);
517   if(ParamP1 < ParamPAttach1){
518     if(alpha > M_PI){
519       alpha  = (2.*M_PI) - alpha;
520       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
521       Dalpha = alpha/(nbp - 1);
522     }
523     else{
524       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
525       Dalpha = -alpha/(nbp - 1);
526     }
527   }
528   else{
529     if(alpha > M_PI){
530       alpha  = (2.*M_PI) - alpha;
531       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
532       Dalpha = -alpha/(nbp - 1);
533     }
534     else{
535       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
536       Dalpha = alpha/(nbp - 1);
537     }
538   }
539
540   aPrims = new Graphic3d_ArrayOfPolylines(nbp);
541   aPrims->AddVertex(AttachmentPoint1);
542   alphaIter = Dalpha;
543   gp_Pnt PntIter;
544   Standard_Integer i;
545   for(i = 2; i <= nbp; i++, alphaIter += Dalpha)
546     aPrims->AddVertex(ElCLib::Value(ParamPAttach1 + alphaIter,aCircle1));
547   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
548   
549   //==== PROCESSING OF CALL 2 =====
550   gp_Pnt Center2 = ProjCenter1.Translated(Vp.Reversed());
551   gp_Dir DirC2 = aCircle1.Axis().Direction();
552   gp_Ax2 AxeC2(Center2,DirC2);
553   gp_Circ aCircle2(AxeC2,aCircle1.Radius());
554   Standard_Real ParamP2       = ElCLib::Parameter(aCircle2,P2);
555   Standard_Real ParamPAttach2 = ElCLib::Parameter(aCircle2,AttachmentPoint2);
556
557   alpha = fabs(ParamP2 - ParamPAttach2);
558   if (alpha <= Precision::Confusion()) alpha = 1.e-5;
559   if(ParamP2 < ParamPAttach2){
560     if(alpha > M_PI){
561       alpha  = (2*M_PI) - alpha;
562       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
563       Dalpha = alpha/(nbp - 1);
564     }
565     else{
566       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
567       Dalpha = -alpha/(nbp - 1);
568     }
569   }
570   else{
571     if(alpha > M_PI){
572       alpha  = (2*M_PI) - alpha;
573       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
574       Dalpha = -alpha/(nbp - 1);
575     }
576     else{
577       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
578       Dalpha = alpha/(nbp - 1);
579     }
580   }
581
582   aPrims = new Graphic3d_ArrayOfPolylines(nbp);
583   aPrims->AddVertex(AttachmentPoint2);
584   alphaIter = Dalpha;
585   for(i = 2; i <= nbp; i++, alphaIter += Dalpha)
586     aPrims->AddVertex(ElCLib::Value(ParamPAttach2 + alphaIter,aCircle2));
587   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
588
589   //==== ARROWS ================
590   Prs3d_Root::NewGroup(aPresentation);
591   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
592   
593   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) outside = Standard_True;
594   gp_Dir arrdir = L3.Direction().Reversed();
595   if (outside) arrdir.Reverse();
596   // arrow 1 ----
597   Prs3d_Arrow::Draw(aPresentation,P1,arrdir,LA->Arrow1Aspect()->Angle(),LA->Arrow1Aspect()->Length());
598   
599   // arrow 2 ----
600   Prs3d_Arrow::Draw(aPresentation,P2,arrdir.Reversed(),LA->Arrow2Aspect()->Angle(),LA->Arrow2Aspect()->Length());
601
602   //-------------------------------------------------------------------------------------
603   //|                                SYMBOL OF SYMMETRY                                 |
604   //-------------------------------------------------------------------------------------
605
606   //           -------    : Superior Segment
607   //         -----------  : Axis
608   //           -------    : Inferior Segment 
609   
610   gp_Vec Vvar(P1,P2);
611   gp_Vec Vtmp = Vvar.Divided(Vvar.Magnitude()).Multiplied(2*(aAxis.Distance(Center1)));
612   gp_Vec vec = Vtmp;
613   gp_Vec vecA = vec.Multiplied(.1);
614
615   gp_Dir DirAxis = aAxis.Direction();
616   gp_Vec Vaxe(DirAxis);
617   gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
618   vecB.Multiply(.5);
619
620   gp_Pnt pm = P1.Translated(Vvar.Multiplied(.5));
621   gp_Pnt pOff = OffsetPnt.Translated(vecB);
622
623   //Calculation of extremas of the axis of the symbol
624   gp_Vec vecAxe = vecA.Multiplied(.7);
625
626   Prs3d_Root::NewGroup(aPresentation);
627   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
628
629   aPrims = new Graphic3d_ArrayOfPolylines(13,5);
630
631   aPrims->AddBound(2);
632   aPrims->AddVertex(pOff.Translated(vecAxe));
633   aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
634
635   //Calculation of extremas of the superior segment of the symbol
636   gp_Vec vec1 = vecAxe.Multiplied(.6);
637   vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
638   gp_Vec vec2 = vecAxe.Multiplied(.4);
639
640   aPrims->AddBound(2);
641   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
642   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
643
644   //Calculation of extremas of the inferior segment of the symbol
645   aPrims->AddBound(2);
646   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
647   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
648   
649   //--------------------------------------------------------------------------------------
650   //|                          MARKING OF THE AXIS OF SYMMETRY                           |
651   //--------------------------------------------------------------------------------------     
652   //        ____
653   //        \  / :Cursor
654   //         \/
655   //         /\
656   //        /__\
657
658   Standard_Real Dist = aAxis.Distance(Center1)/37;
659   gp_Dir aDirectionAxis = aAxis.Direction();
660   gp_Vec vs(aDirectionAxis);
661   gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
662   gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
663
664   aPrims->AddBound(5);
665   gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
666   aPrims->AddVertex(pm1);
667   pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
668   aPrims->AddVertex(pm1);
669   pm1 = pm1.Translated(vsymper.Multiplied(2));
670   aPrims->AddVertex(pm1);
671   pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
672   aPrims->AddVertex(pm1);
673   pm1 = pm1.Translated(vsymper.Multiplied(2));
674   aPrims->AddVertex(pm1);
675
676   vsym.Multiply(4);
677
678   aPrims->AddBound(2);
679   aPrims->AddVertex(pm.Translated(vsym));
680   aPrims->AddVertex(pm.Translated(vsym.Reversed()));
681
682   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
683 }
684
685 //===================================================================
686 //Function:Add
687 //Purpose: draws the representation of an axial symmetry between two vertex.
688 //===================================================================
689 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
690                                         const Handle(Prs3d_Drawer)& aDrawer,    
691                                         const gp_Pnt&  AttachmentPoint1,
692                                         const gp_Pnt&  AttachmentPoint2,
693                                         const gp_Lin&  aAxis,
694                                         const gp_Pnt&  OffsetPoint)
695 {
696   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
697   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());  
698
699   if (AttachmentPoint1.IsEqual(AttachmentPoint2,Precision::Confusion()))
700   {
701     //==============================================================
702     //  SYMMETRY WHEN THE REFERENCE POINT IS ON THE AXIS OF SYM.:
703     //==============================================================
704     //Marker of localisation of the face
705     Handle(Graphic3d_AspectMarker3d) MarkerAsp = new Graphic3d_AspectMarker3d();
706     MarkerAsp->SetType(Aspect_TOM_BALL);
707     MarkerAsp->SetScale(0.8);
708     Quantity_Color acolor;
709     Aspect_TypeOfLine atype;
710     Standard_Real awidth;
711     LA->LineAspect()->Aspect()->Values(acolor, atype, awidth);
712     MarkerAsp->SetColor(acolor);
713     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(MarkerAsp);
714     Graphic3d_Vertex V3d(AttachmentPoint1.X(),AttachmentPoint1.Y(),AttachmentPoint1.Z());
715     Prs3d_Root::CurrentGroup(aPresentation)->Marker(V3d);
716
717     //Trace of the linking segment 
718     Prs3d_Root::NewGroup(aPresentation);
719     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
720
721     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(8);
722
723         aPrims->AddVertex(AttachmentPoint1);
724     aPrims->AddVertex(OffsetPoint);
725   
726     //--------------------------------------------------------------------------------------
727     //|                                SYMBOL OF SYMMETRY                                 |
728     //--------------------------------------------------------------------------------------
729     //           -------    : Superior Segment 
730     //         -----------  : Axis
731     //           -------    : Inferior Segment 
732
733     //Calculate extremas of the axis of the symbol
734     gp_Vec VAO (AttachmentPoint1,OffsetPoint);
735     gp_Vec uVAO  = VAO.Divided(VAO.Magnitude());
736     gp_Pnt pDaxe = OffsetPoint.Translated(uVAO.Multiplied(3.));
737     gp_Pnt pFaxe = pDaxe.Translated(uVAO.Multiplied(12.));
738
739     aPrims->AddVertex(pDaxe);
740     aPrims->AddVertex(pFaxe);
741
742     //Calculate extremas of the superior segment of the symbol
743     gp_Vec nVAO  (-uVAO.Y(),uVAO.X(),uVAO.Z());
744     gp_Pnt sgP11 = pDaxe.Translated(uVAO.Multiplied(2.).Added(nVAO.Multiplied(2.)));
745     gp_Pnt sgP12 = sgP11.Translated(uVAO.Multiplied(8.));
746
747     aPrims->AddVertex(sgP11);
748     aPrims->AddVertex(sgP12);
749
750     //Calculate extremas of the inferior segment of the symbol
751     gp_Vec nVAOr = nVAO.Reversed();
752     gp_Pnt sgP21 = pDaxe.Translated(uVAO.Multiplied(2.).Added(nVAOr.Multiplied(2.)));
753     gp_Pnt sgP22 = sgP21.Translated(uVAO.Multiplied(8.));
754
755     aPrims->AddVertex(sgP21);
756     aPrims->AddVertex(sgP22);
757
758         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
759   }
760   //==============================================================
761   //  OTHER CASES                                                 :
762   //==============================================================
763
764   else {
765     gp_Pnt ProjOffsetPoint      = ElCLib::Value(ElCLib::Parameter(aAxis,OffsetPoint),aAxis);
766     gp_Pnt ProjAttachmentPoint1 = ElCLib::Value(ElCLib::Parameter(aAxis,AttachmentPoint1),aAxis);
767     gp_Vec PjAtt1_Att1(ProjAttachmentPoint1,AttachmentPoint1);
768     gp_Pnt P1 = ProjOffsetPoint.Translated(PjAtt1_Att1);
769     gp_Pnt P2 = ProjOffsetPoint.Translated(PjAtt1_Att1.Reversed());
770
771     gp_Lin L3 = gce_MakeLin(P1,P2);
772     Standard_Real parmin,parmax,parcur;
773     parmin = ElCLib::Parameter(L3,P1);
774     parmax = parmin;
775     parcur = ElCLib::Parameter(L3,P2);
776     Standard_Real dist = Abs(parmin-parcur);
777     if (parcur < parmin) parmin = parcur;
778     if (parcur > parmax) parmax = parcur;
779     parcur = ElCLib::Parameter(L3,OffsetPoint);
780     
781     Standard_Boolean outside = Standard_False;
782     if (parcur < parmin) {
783       parmin = parcur;
784       outside = Standard_True;
785     }
786     if (parcur > parmax) {
787       parmax = parcur;
788       outside = Standard_True;
789     }
790     gp_Pnt PointMin = ElCLib::Value(parmin,L3);
791     gp_Pnt PointMax = ElCLib::Value(parmax,L3);
792
793     //==== PROCESSING OF FACE ===========
794     Prs3d_Root::NewGroup(aPresentation);
795     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
796
797     Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(6);
798
799         aPrims->AddVertex(PointMin);
800     aPrims->AddVertex(PointMax);
801     
802     //==== PROCESSING OF CALL 1 =====
803     aPrims->AddVertex(AttachmentPoint1);
804     aPrims->AddVertex(P1);
805     
806     //==== PROCESSING OF CALL 2 =====
807     aPrims->AddVertex(AttachmentPoint2);
808     aPrims->AddVertex(P2);
809
810         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
811  
812     //==== ARROWS ================
813     if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) outside = Standard_True;
814     gp_Dir arrdir = L3.Direction().Reversed();
815     if (outside) arrdir.Reverse();
816     // arrow 1 ----
817     Prs3d_Arrow::Draw(aPresentation,P1,arrdir,LA->Arrow1Aspect()->Angle(),LA->Arrow1Aspect()->Length());
818   
819     // arrow 2 ----
820     Prs3d_Arrow::Draw(aPresentation,P2,arrdir.Reversed(),LA->Arrow2Aspect()->Angle(),LA->Arrow2Aspect()->Length());
821     
822     //==== POINTS ================
823     //Marker of localization of attachment points:
824     Prs3d_Root::NewGroup(aPresentation);
825     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
826
827     Handle(Graphic3d_AspectMarker3d) MarkerAspAtt = new Graphic3d_AspectMarker3d();
828     MarkerAspAtt->SetType(Aspect_TOM_BALL);
829     MarkerAspAtt->SetScale(0.8);
830     Quantity_Color color;
831     Aspect_TypeOfLine type;
832     Standard_Real width;
833     LA->LineAspect()->Aspect()->Values(color, type, width);
834     MarkerAspAtt->SetColor(color);
835     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(MarkerAspAtt);
836     Graphic3d_Vertex Vatt1(AttachmentPoint1.X(),AttachmentPoint1.Y(),AttachmentPoint1.Z());
837     Prs3d_Root::CurrentGroup(aPresentation)->Marker(Vatt1);
838
839     Prs3d_Root::NewGroup(aPresentation);
840     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
841     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(MarkerAspAtt);
842     Graphic3d_Vertex Vatt2(AttachmentPoint2.X(),AttachmentPoint2.Y(),AttachmentPoint2.Z());
843     Prs3d_Root::CurrentGroup(aPresentation)->Marker(Vatt2);
844       
845     //-------------------------------------------------------------------------------------
846     //|                                SYMBOL OF SYMMETRY                                 |
847     //-------------------------------------------------------------------------------------
848     
849     //           -------    : Superior Segment 
850     //         -----------  : Axis
851     //           -------    : Inferior Segment
852     
853     gp_Vec vec(P1,P2);
854     gp_Vec vecA = vec.Multiplied(.1);
855
856     gp_Dir DirAxis = aAxis.Direction();
857     gp_Vec Vaxe(DirAxis);
858     gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
859     vecB.Multiply(.5);
860
861     gp_Pnt pm = P1.Translated(vec.Multiplied(.5));
862     gp_Pnt pOff = OffsetPoint.Translated(vecB);
863     
864     //Calculate the extremas of the axis of the symbol
865     gp_Vec vecAxe = vecA.Multiplied(.7);
866
867     Prs3d_Root::NewGroup(aPresentation);
868     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
869
870         aPrims = new Graphic3d_ArrayOfPolylines(13,5);
871
872     aPrims->AddBound(2);
873         aPrims->AddVertex(pOff.Translated(vecAxe));
874     aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
875
876     //Calculate the extremas of the superior segment of the symbol
877     gp_Vec vec1 = vecAxe.Multiplied(.6);
878     vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
879     gp_Vec vec2 = vecAxe.Multiplied(.4);
880
881     aPrims->AddBound(2);
882     aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
883     aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
884     
885     //Calculate the extremas of the inferior segment of the symbol
886     aPrims->AddBound(2);
887     aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
888     aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
889
890     //--------------------------------------------------------------------------------------
891     //|                          MARKING OF THE AXIS OF SYMMETRY                           |
892     //--------------------------------------------------------------------------------------     
893     //        ____
894     //        \  / :Cursor
895     //         \/
896     //         /\
897     //        /__\
898     
899     Standard_Real Dist = P1.Distance(P2)/75;
900     gp_Dir aDirectionAxis = aAxis.Direction();
901     gp_Vec vs(aDirectionAxis);
902     gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
903     gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
904
905     aPrims->AddBound(5);
906     gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
907     aPrims->AddVertex(pm1);
908     pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
909     aPrims->AddVertex(pm1);
910     pm1 = pm1.Translated(vsymper.Multiplied(2));
911     aPrims->AddVertex(pm1);
912     pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
913     aPrims->AddVertex(pm1);
914     pm1 = pm1.Translated(vsymper.Multiplied(2));
915     aPrims->AddVertex(pm1);
916
917     vsym.Multiply(4);
918
919     aPrims->AddBound(2);
920     aPrims->AddVertex(pm.Translated(vsym));
921     aPrims->AddVertex(pm.Translated(vsym.Reversed()));
922
923         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
924   } 
925 }