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