0024239: Eliminate GCC compiler warning (multi-line comment)
[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_ArrayOfPoints.hxx>
48 #include <Graphic3d_Vertex.hxx>
49
50 #include <Prs3d_Arrow.hxx>
51 #include <Prs3d_ArrowAspect.hxx>
52 #include <Prs3d_LineAspect.hxx>
53 #include <Prs3d_LengthAspect.hxx>
54
55 #include <TCollection_AsciiString.hxx>
56
57 #include <Geom2d_Line.hxx>
58
59 #include <GeomAPI.hxx>
60
61 #include <IntAna2d_AnaIntersection.hxx>
62
63
64 //===================================================================
65 //Function:Add
66 //Purpose: draws the representation of an axial symmetry between two segments.
67 //===================================================================
68 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
69                                         const Handle(Prs3d_Drawer)& aDrawer,    
70                                         const gp_Pnt& AttachmentPoint1,
71                                         const gp_Pnt& AttachmentPoint2,
72                                         const gp_Dir& aDirection1,
73                                         const gp_Lin& aAxis,
74                                         const gp_Pnt& OffsetPoint)
75
76   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
77   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
78
79   gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(aAxis,OffsetPoint),aAxis);
80   gp_Pnt PjAttachPnt1    = ElCLib::Value(ElCLib::Parameter(aAxis,AttachmentPoint1),aAxis);
81   gp_Dir aDirectionAxis  = aAxis.Direction();
82   Standard_Real h = fabs(ProjOffsetPoint.Distance(PjAttachPnt1)/cos(aDirectionAxis.Angle(aDirection1)));
83   
84   gp_Vec VL1(aDirection1);
85   gp_Vec VLa(PjAttachPnt1,ProjOffsetPoint);
86   Standard_Real scal;
87   scal = VL1.Dot(VLa);
88   if (scal < 0) VL1.Reverse();
89   VL1.Multiply(h);
90
91   gp_Pnt P1,P2;
92
93   //===================================
94   // SYMETRY OF EDGE PERPEND. TO THE AXIS    
95   //   ____        :        ____
96   // edge2 |       : -=-   | edge 1
97   //       |<------:------>|
98   //               :        
99   //===================================
100
101   if (VLa.Dot(VL1) == 0) {
102     P1 = AttachmentPoint1.Translated(VLa);
103     gp_Vec VPntat2Axe(PjAttachPnt1,AttachmentPoint2);  
104     P2 = ProjOffsetPoint.Translated(VPntat2Axe);
105   }
106   else {
107     P1 = AttachmentPoint1.Translated(VL1);
108     gp_Vec VPntat1Axe(P1,ProjOffsetPoint);
109     P2 = ProjOffsetPoint.Translated(VPntat1Axe);
110   }
111
112   gp_Lin L3 = gce_MakeLin(P1,P2);
113   Standard_Real parmin,parmax,parcur;
114   parmin = ElCLib::Parameter(L3,P1);
115   parmax = parmin;
116   parcur = ElCLib::Parameter(L3,P2);
117   Standard_Real dist = Abs(parmin-parcur);
118   if (parcur < parmin) parmin = parcur;
119   if (parcur > parmax) parmax = parcur;
120   parcur = ElCLib::Parameter(L3,OffsetPoint);
121   gp_Pnt offp = ElCLib::Value(parcur,L3);
122
123   Standard_Boolean outside = Standard_False;
124   if (parcur < parmin) {
125     parmin = parcur;
126     outside = Standard_True;
127   }
128   if (parcur > parmax) {
129     parmax = parcur;
130     outside = Standard_True;
131   }
132
133   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
134   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
135
136   Quantity_Length X,Y,Z;
137   Standard_Real D1(aAxis.Distance(AttachmentPoint1)),coeff(.5);
138   gp_Pnt pint,Pj_P1,P1Previous = P1;
139   
140   /*=======================================================
141    TO AVOID CROSSING
142           P1  -=- P2                P2  -=- P1         
143             \<-->/                    |<-->|
144              \  /                     |    |
145               \/                      |    | 
146               /\                      |    |
147              /  \                     |    |
148    Pattach2 /____\ Pattach1 Pattach2 /______\ Pattach1
149            /  NO \                  /   YES  \  
150   =======================================================*/
151
152   Standard_Boolean Cross = Standard_False;
153   gp_Vec Attch1_PjAttch1(AttachmentPoint1,PjAttachPnt1);
154   gp_Vec v(P1,ProjOffsetPoint);
155   if (v.IsOpposite((Attch1_PjAttch1),Precision::Confusion())){
156     Cross = Standard_True;
157     gp_Pnt PntTempo;
158     PntTempo = P1;
159     P1       = P2;
160     P2       = PntTempo;
161   }  
162   /*===================================
163    FRACTURES OF TRAITS OF CALL    
164           /             \               
165          /               \      
166          |      -=-      |
167          |<------------->| 
168   ===================================*/
169
170   gp_Vec        Vfix;
171   Standard_Real alpha,b;
172
173   if(aAxis.Distance(P1) > D1*(1 + coeff) && !Cross){
174
175     //==== PROCESSING OF FACE ===========
176     Prs3d_Root::NewGroup(aPresentation);
177     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
178
179     Pj_P1 = ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis);
180     gp_Vec Vp(Pj_P1,P1);
181     Vfix = Vp.Divided(Vp.Magnitude()).Multiplied(D1*(1 + coeff));
182     P1 = Pj_P1.Translated(Vfix);
183     P2 = Pj_P1.Translated(Vfix.Reversed());
184
185     //=================================
186     // LISTING AT THE EXTERIOR
187     //                        -=-
188     //      ->|----------|<------
189     //        |          |
190     //=================================
191     
192     L3 = gce_MakeLin(P1,P2);
193     parmin = ElCLib::Parameter(L3,P1);
194     parmax = parmin;
195     parcur = ElCLib::Parameter(L3,P2);
196     dist = Abs(parmin-parcur);
197     if (parcur < parmin) parmin = parcur;
198     if (parcur > parmax) parmax = parcur;
199     parcur = ElCLib::Parameter(L3,OffsetPoint);
200     offp = ElCLib::Value(parcur,L3);  
201     outside = Standard_False;
202     if (parcur < parmin) {
203       parmin = parcur;
204       outside = Standard_True;
205     }
206     if (parcur > parmax) {
207       parmax = parcur;
208       outside = Standard_True;
209     }    
210     PointMin = ElCLib::Value(parmin,L3);
211     PointMax = ElCLib::Value(parmax,L3);
212
213     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(8,3);
214
215     aPrims->AddBound(2);
216     aPrims->AddVertex(PointMin);
217     aPrims->AddVertex(PointMax);
218     
219     //==== PROCESSING OF CALL 1 =====
220     alpha = aDirectionAxis.Angle(aDirection1);
221     b = (coeff*D1)/sin(alpha);
222     gp_Vec Vpint(AttachmentPoint1,P1Previous);
223     pint = AttachmentPoint1.Translated(Vpint.Divided(Vpint.Magnitude()).Multiplied(b));
224
225     aPrims->AddBound(3);
226     aPrims->AddVertex(AttachmentPoint1);
227     aPrims->AddVertex(pint);
228     aPrims->AddVertex(P1);
229
230     //==== PROCESSING OF CALL 2 =====
231     gp_Pnt Pj_pint  = ElCLib::Value(ElCLib::Parameter(aAxis,pint),aAxis);
232     gp_Vec V_int(pint, Pj_pint);
233     gp_Pnt Sym_pint = Pj_pint.Translated(V_int);
234
235     aPrims->AddBound(3);
236     aPrims->AddVertex(AttachmentPoint2);
237     aPrims->AddVertex(Sym_pint);
238     aPrims->AddVertex(P2);
239
240         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
241   }
242
243   /*===================================
244    FRACTURES OF PROCESSING OF CALL    
245                 -=-    
246            |<--------->| 
247            |           |   
248           /             \       
249          /               \       
250   ===================================*/
251   else if (aAxis.Distance(P1) < D1*(1 - coeff) || Cross) {
252
253     //------ PROCESSING OF FACE ------------
254     Prs3d_Root::NewGroup(aPresentation);
255     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
256
257     Pj_P1 = ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis);
258     gp_Vec VpInf(Pj_P1,P1);
259     Vfix = VpInf.Divided(VpInf.Magnitude()).Multiplied(D1*(1 - coeff));
260     Pj_P1.Translated(Vfix).Coord(X,Y,Z);
261     P1.SetCoord(X,Y,Z);
262     Pj_P1.Translated(Vfix.Reversed()).Coord(X,Y,Z);
263     P2.SetCoord(X,Y,Z);
264
265     //=================================
266     // LISTING AT THE EXTERIOR
267     //                        -=-
268     //      ->|----------|<------
269     //        |          |
270     //=================================
271     L3 = gce_MakeLin(P1,P2);
272     parmin = ElCLib::Parameter(L3,P1);
273     parmax = parmin;
274     parcur = ElCLib::Parameter(L3,P2);
275     dist = Abs(parmin-parcur);
276     if (parcur < parmin) parmin = parcur;
277     if (parcur > parmax) parmax = parcur;
278     parcur = ElCLib::Parameter(L3,OffsetPoint);
279     offp = ElCLib::Value(parcur,L3);  
280     outside = Standard_False;
281     if (parcur < parmin) {
282       parmin = parcur;
283       outside = Standard_True;
284     }
285     if (parcur > parmax) {
286       parmax = parcur;
287       outside = Standard_True;
288     }    
289     PointMin = ElCLib::Value(parmin,L3);
290     PointMax = ElCLib::Value(parmax,L3);
291
292     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(8,3);
293
294     aPrims->AddBound(2);
295         aPrims->AddVertex(PointMin);
296     aPrims->AddVertex(PointMax);
297     
298     //==== PROCESSING OF CALL 1 =====
299     alpha = aDirectionAxis.Angle(aDirection1);
300     b = (coeff*D1)/sin(alpha);
301     gp_Vec Vpint(AttachmentPoint1,P1Previous);
302     pint = AttachmentPoint1.Translated(Vpint.Divided(Vpint.Magnitude()).Multiplied(b));
303
304     aPrims->AddBound(3);
305     aPrims->AddVertex(AttachmentPoint1);
306     aPrims->AddVertex(pint);
307     aPrims->AddVertex(P1);
308     
309     //==== PROCESSING OF CALL 2 =====
310     gp_Pnt Pj_pint  = ElCLib::Value(ElCLib::Parameter(aAxis,pint),aAxis);
311     gp_Vec V_int(pint, Pj_pint);
312     gp_Pnt Sym_pint = Pj_pint.Translated(V_int);
313
314     aPrims->AddBound(3);
315     aPrims->AddVertex(AttachmentPoint2);
316     aPrims->AddVertex(Sym_pint);
317     aPrims->AddVertex(P2);
318
319         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
320   }
321   else {
322     
323     //==== PROCESSING OF FACE ===========
324     Prs3d_Root::NewGroup(aPresentation);
325     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
326
327     Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(6);
328
329         aPrims->AddVertex(PointMin);
330     aPrims->AddVertex(PointMax);
331     
332     //==== PROCESSING OF CALL 1 =====
333     aPrims->AddVertex(AttachmentPoint1);
334     aPrims->AddVertex(P1);
335
336     //==== PROCESSING OF CALL 2 =====
337     aPrims->AddVertex(AttachmentPoint2);
338     aPrims->AddVertex(P2);
339
340         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
341   }
342
343   //==== ARROWS ================
344   Prs3d_Root::NewGroup(aPresentation);
345   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
346   
347   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) outside = Standard_True;
348   gp_Dir arrdir = L3.Direction().Reversed();
349   if (outside) arrdir.Reverse();
350   // arrow 1 ----
351   Prs3d_Arrow::Draw(aPresentation,P1,arrdir,LA->Arrow1Aspect()->Angle(),LA->Arrow1Aspect()->Length());
352   
353   // arrow 2 ----
354   Prs3d_Arrow::Draw(aPresentation,P2,arrdir.Reversed(),LA->Arrow2Aspect()->Angle(),LA->Arrow2Aspect()->Length());
355
356   //-------------------------------------------------------------------------------------
357   //|                                SYMBOL OF SYMMETRY                                 |
358   //-------------------------------------------------------------------------------------
359
360   //           -------    : Superior Segment 
361   //         -----------  : Axis
362   //           -------    : Inferior Segment 
363   
364   gp_Vec Vvar(P1,P2);
365   gp_Vec vec;
366   gp_Vec Vtmp = Vvar.Divided(Vvar.Magnitude()).Multiplied((aAxis.Distance(AttachmentPoint1)+
367                                                            aAxis.Distance(AttachmentPoint2)));
368   vec.SetCoord(Vtmp.X(),Vtmp.Y(),Vtmp.Z());
369   gp_Vec vecA = vec.Multiplied(.1);
370
371   gp_Dir DirAxis = aAxis.Direction();
372   gp_Vec Vaxe(DirAxis);
373   gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
374   vecB.Multiply(.5);
375
376   gp_Pnt pm,pOff;
377   if (VLa.Dot(VL1) == 0) {
378     gp_Vec Vper(P1,ElCLib::Value(ElCLib::Parameter(aAxis,P1),aAxis));
379     pm = P1.Translated(Vper);
380   }
381   else {
382     pm = P1.Translated(Vvar.Multiplied(.5));
383   }
384   pOff = OffsetPoint.Translated(vecB);
385   
386   //Calculate the extremities of the symbol axis
387   gp_Vec vecAxe = vecA.Multiplied(.7);
388
389   Prs3d_Root::NewGroup(aPresentation);
390   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
391
392   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(13,5);
393
394   aPrims->AddBound(2);
395   aPrims->AddVertex(pOff.Translated(vecAxe));
396   aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
397
398   //Calculate the extremities of the superior segment of the symbol
399   gp_Vec vec1 = vecAxe.Multiplied(.6);
400   vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
401   gp_Vec vec2 = vecAxe.Multiplied(.4);
402
403   aPrims->AddBound(2);
404   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
405   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
406
407   //Calculate the extremities of the inferior segment of the symbol
408   aPrims->AddBound(2);
409   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
410   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
411
412   /*--------------------------------------------------------------------------------------
413   |                          MARKING OF THE SYMMETRY AXIS                             |
414   --------------------------------------------------------------------------------------     
415           ____
416           \  / :Cursor
417            \/
418            /\
419           /__\
420 */
421   Standard_Real Dist = (aAxis.Distance(AttachmentPoint1)+aAxis.Distance(AttachmentPoint2))/75;
422   gp_Vec vs(aDirectionAxis);
423   gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
424   gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
425   
426   aPrims->AddBound(5);
427   gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
428   aPrims->AddVertex(pm1);
429   pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
430   aPrims->AddVertex(pm1);
431   pm1 = pm1.Translated(vsymper.Multiplied(2));
432   aPrims->AddVertex(pm1);
433   pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
434   aPrims->AddVertex(pm1);
435   pm1 = pm1.Translated(vsymper.Multiplied(2));
436   aPrims->AddVertex(pm1);
437
438   vsym.Multiply(4);
439
440   aPrims->AddBound(2);
441   aPrims->AddVertex(pm.Translated(vsym));
442   aPrims->AddVertex(pm.Translated(vsym.Reversed()));
443
444   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
445 }
446   
447 //===================================================================
448 //Function:Add
449 //Purpose: draws the representation of an axial symmetry between two arcs.
450 //===================================================================
451 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
452                                         const Handle(Prs3d_Drawer)& aDrawer,    
453                                         const gp_Pnt&  AttachmentPoint1,
454                                         const gp_Pnt&  AttachmentPoint2,
455                                         const gp_Circ& aCircle1,
456                                         const gp_Lin&  aAxis,
457                                         const gp_Pnt&  OffsetPoint)
458 {
459   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
460   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());  
461
462   gp_Pnt OffsetPnt(OffsetPoint.X(),OffsetPoint.Y(),OffsetPoint.Z());
463   gp_Pnt Center1 = aCircle1.Location();
464   gp_Pnt ProjOffsetPoint = ElCLib::Value(ElCLib::Parameter(aAxis,OffsetPnt),aAxis);
465   gp_Pnt ProjCenter1     = ElCLib::Value(ElCLib::Parameter(aAxis,Center1),aAxis);
466   gp_Vec Vp(ProjCenter1,Center1);
467   if (Vp.Magnitude() <= Precision::Confusion()) Vp = gp_Vec(aAxis.Direction())^aCircle1.Position().Direction();
468
469   Standard_Real Dt,R,h;
470   Dt = ProjCenter1.Distance(ProjOffsetPoint);
471   R  = aCircle1.Radius();
472   if (Dt > .999*R) {
473     Dt = .999*R;
474     gp_Vec Vout(ProjCenter1,ProjOffsetPoint);
475     ProjOffsetPoint = ProjCenter1.Translated(Vout.Divided(Vout.Magnitude()).Multiplied(Dt));
476     OffsetPnt = ProjOffsetPoint;
477   }
478   h  = Sqrt(R*R - Dt*Dt);
479   gp_Pnt P1 = ProjOffsetPoint.Translated(Vp.Added(Vp.Divided(Vp.Magnitude()).Multiplied(h)));
480   gp_Vec v(P1,ProjOffsetPoint);
481   gp_Pnt P2 = ProjOffsetPoint.Translated(v);
482
483   gp_Lin L3 = gce_MakeLin(P1,P2);
484   Standard_Real parmin,parmax,parcur;
485   parmin = ElCLib::Parameter(L3,P1);
486   parmax = parmin;
487   parcur = ElCLib::Parameter(L3,P2);
488   Standard_Real dist = Abs(parmin-parcur);
489   if (parcur < parmin) parmin = parcur;
490   if (parcur > parmax) parmax = parcur;
491   parcur = ElCLib::Parameter(L3,OffsetPnt);
492
493   Standard_Boolean outside = Standard_False;
494   if (parcur < parmin) {
495     parmin = parcur;
496     outside = Standard_True;
497   }
498   if (parcur > parmax) {
499     parmax = parcur;
500     outside = Standard_True;
501   }
502   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
503   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
504
505   //==== PROCESSING OF FACE ===========
506   Handle(Graphic3d_ArrayOfPrimitives) aPrims = new Graphic3d_ArrayOfSegments(2);
507   aPrims->AddVertex(PointMin);
508   aPrims->AddVertex(PointMax);
509   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
510
511   //==== PROCESSING OF CALL 1 =====
512   Standard_Integer nbp = 10;
513   Standard_Real ParamP1       = ElCLib::Parameter(aCircle1,P1);
514   Standard_Real ParamPAttach1 = ElCLib::Parameter(aCircle1,AttachmentPoint1);
515   Standard_Real alpha,Dalpha,alphaIter;
516
517   alpha = fabs(ParamP1 - ParamPAttach1);
518   if(ParamP1 < ParamPAttach1){
519     if(alpha > M_PI){
520       alpha  = (2.*M_PI) - alpha;
521       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
522       Dalpha = alpha/(nbp - 1);
523     }
524     else{
525       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
526       Dalpha = -alpha/(nbp - 1);
527     }
528   }
529   else{
530     if(alpha > M_PI){
531       alpha  = (2.*M_PI) - alpha;
532       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
533       Dalpha = -alpha/(nbp - 1);
534     }
535     else{
536       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
537       Dalpha = alpha/(nbp - 1);
538     }
539   }
540
541   aPrims = new Graphic3d_ArrayOfPolylines(nbp);
542   aPrims->AddVertex(AttachmentPoint1);
543   alphaIter = Dalpha;
544   gp_Pnt PntIter;
545   Standard_Integer i;
546   for(i = 2; i <= nbp; i++, alphaIter += Dalpha)
547     aPrims->AddVertex(ElCLib::Value(ParamPAttach1 + alphaIter,aCircle1));
548   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
549   
550   //==== PROCESSING OF CALL 2 =====
551   gp_Pnt Center2 = ProjCenter1.Translated(Vp.Reversed());
552   gp_Dir DirC2 = aCircle1.Axis().Direction();
553   gp_Ax2 AxeC2(Center2,DirC2);
554   gp_Circ aCircle2(AxeC2,aCircle1.Radius());
555   Standard_Real ParamP2       = ElCLib::Parameter(aCircle2,P2);
556   Standard_Real ParamPAttach2 = ElCLib::Parameter(aCircle2,AttachmentPoint2);
557
558   alpha = fabs(ParamP2 - ParamPAttach2);
559   if (alpha <= Precision::Confusion()) alpha = 1.e-5;
560   if(ParamP2 < ParamPAttach2){
561     if(alpha > M_PI){
562       alpha  = (2*M_PI) - alpha;
563       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
564       Dalpha = alpha/(nbp - 1);
565     }
566     else{
567       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
568       Dalpha = -alpha/(nbp - 1);
569     }
570   }
571   else{
572     if(alpha > M_PI){
573       alpha  = (2*M_PI) - alpha;
574       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
575       Dalpha = -alpha/(nbp - 1);
576     }
577     else{
578       nbp    = (Standard_Integer ) IntegerPart(alpha/(alpha*.02));
579       Dalpha = alpha/(nbp - 1);
580     }
581   }
582
583   aPrims = new Graphic3d_ArrayOfPolylines(nbp);
584   aPrims->AddVertex(AttachmentPoint2);
585   alphaIter = Dalpha;
586   for(i = 2; i <= nbp; i++, alphaIter += Dalpha)
587     aPrims->AddVertex(ElCLib::Value(ParamPAttach2 + alphaIter,aCircle2));
588   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
589
590   //==== ARROWS ================
591   Prs3d_Root::NewGroup(aPresentation);
592   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
593   
594   if (dist < (LA->Arrow1Aspect()->Length()+LA->Arrow2Aspect()->Length())) outside = Standard_True;
595   gp_Dir arrdir = L3.Direction().Reversed();
596   if (outside) arrdir.Reverse();
597   // arrow 1 ----
598   Prs3d_Arrow::Draw(aPresentation,P1,arrdir,LA->Arrow1Aspect()->Angle(),LA->Arrow1Aspect()->Length());
599   
600   // arrow 2 ----
601   Prs3d_Arrow::Draw(aPresentation,P2,arrdir.Reversed(),LA->Arrow2Aspect()->Angle(),LA->Arrow2Aspect()->Length());
602
603   //-------------------------------------------------------------------------------------
604   //|                                SYMBOL OF SYMMETRY                                 |
605   //-------------------------------------------------------------------------------------
606
607   //           -------    : Superior Segment
608   //         -----------  : Axis
609   //           -------    : Inferior Segment 
610   
611   gp_Vec Vvar(P1,P2);
612   gp_Vec Vtmp = Vvar.Divided(Vvar.Magnitude()).Multiplied(2*(aAxis.Distance(Center1)));
613   gp_Vec vec = Vtmp;
614   gp_Vec vecA = vec.Multiplied(.1);
615
616   gp_Dir DirAxis = aAxis.Direction();
617   gp_Vec Vaxe(DirAxis);
618   gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
619   vecB.Multiply(.5);
620
621   gp_Pnt pm = P1.Translated(Vvar.Multiplied(.5));
622   gp_Pnt pOff = OffsetPnt.Translated(vecB);
623
624   //Calculation of extremas of the axis of the symbol
625   gp_Vec vecAxe = vecA.Multiplied(.7);
626
627   Prs3d_Root::NewGroup(aPresentation);
628   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
629
630   aPrims = new Graphic3d_ArrayOfPolylines(13,5);
631
632   aPrims->AddBound(2);
633   aPrims->AddVertex(pOff.Translated(vecAxe));
634   aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
635
636   //Calculation of extremas of the superior segment of the symbol
637   gp_Vec vec1 = vecAxe.Multiplied(.6);
638   vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
639   gp_Vec vec2 = vecAxe.Multiplied(.4);
640
641   aPrims->AddBound(2);
642   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
643   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
644
645   //Calculation of extremas of the inferior segment of the symbol
646   aPrims->AddBound(2);
647   aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
648   aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
649   
650 /*--------------------------------------------------------------------------------------
651   |                          MARKING OF THE AXIS OF SYMMETRY                           |
652   --------------------------------------------------------------------------------------     
653           ____
654           \  / :Cursor
655            \/
656            /\
657           /__\
658 */
659   Standard_Real Dist = aAxis.Distance(Center1)/37;
660   gp_Dir aDirectionAxis = aAxis.Direction();
661   gp_Vec vs(aDirectionAxis);
662   gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
663   gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
664
665   aPrims->AddBound(5);
666   gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
667   aPrims->AddVertex(pm1);
668   pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
669   aPrims->AddVertex(pm1);
670   pm1 = pm1.Translated(vsymper.Multiplied(2));
671   aPrims->AddVertex(pm1);
672   pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
673   aPrims->AddVertex(pm1);
674   pm1 = pm1.Translated(vsymper.Multiplied(2));
675   aPrims->AddVertex(pm1);
676
677   vsym.Multiply(4);
678
679   aPrims->AddBound(2);
680   aPrims->AddVertex(pm.Translated(vsym));
681   aPrims->AddVertex(pm.Translated(vsym.Reversed()));
682
683   Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
684 }
685
686 //===================================================================
687 //Function:Add
688 //Purpose: draws the representation of an axial symmetry between two vertex.
689 //===================================================================
690 void DsgPrs_SymmetricPresentation::Add (const Handle(Prs3d_Presentation)& aPresentation,
691                                         const Handle(Prs3d_Drawer)& aDrawer,    
692                                         const gp_Pnt&  AttachmentPoint1,
693                                         const gp_Pnt&  AttachmentPoint2,
694                                         const gp_Lin&  aAxis,
695                                         const gp_Pnt&  OffsetPoint)
696 {
697   Handle(Prs3d_LengthAspect) LA = aDrawer->LengthAspect();
698   Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());  
699
700   if (AttachmentPoint1.IsEqual(AttachmentPoint2,Precision::Confusion()))
701   {
702     //==============================================================
703     //  SYMMETRY WHEN THE REFERENCE POINT IS ON THE AXIS OF SYM.:
704     //==============================================================
705     //Marker of localisation of the face
706     Quantity_Color aColor;
707     Aspect_TypeOfLine aType;
708     Standard_Real aWidth;
709     LA->LineAspect()->Aspect()->Values(aColor, aType, aWidth);
710     Handle(Graphic3d_AspectMarker3d) aMarkerAsp = new Graphic3d_AspectMarker3d (Aspect_TOM_O, aColor, 1.0);
711     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect (aMarkerAsp);
712     Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
713     anArrayOfPoints->AddVertex (AttachmentPoint1.X(), AttachmentPoint1.Y(), AttachmentPoint1.Z());
714     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
715
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     Quantity_Color aColor;
828     Aspect_TypeOfLine aType;
829     Standard_Real aWidth;
830     LA->LineAspect()->Aspect()->Values (aColor, aType, aWidth);
831     Handle(Graphic3d_AspectMarker3d) aMarkerAspAtt = new Graphic3d_AspectMarker3d (Aspect_TOM_O, aColor, 1.0);
832     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect (aMarkerAspAtt);
833     Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints1 = new Graphic3d_ArrayOfPoints (1);
834     anArrayOfPoints1->AddVertex (AttachmentPoint1.X(), AttachmentPoint1.Y(), AttachmentPoint1.Z());
835     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints1);
836
837     Prs3d_Root::NewGroup(aPresentation);
838     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
839     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect (aMarkerAspAtt);
840     Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints2 = new Graphic3d_ArrayOfPoints (1);
841     anArrayOfPoints2->AddVertex (AttachmentPoint2.X(), AttachmentPoint2.Y(), AttachmentPoint2.Z());
842     Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints2);
843       
844     //-------------------------------------------------------------------------------------
845     //|                                SYMBOL OF SYMMETRY                                 |
846     //-------------------------------------------------------------------------------------
847     
848     //           -------    : Superior Segment 
849     //         -----------  : Axis
850     //           -------    : Inferior Segment
851     
852     gp_Vec vec(P1,P2);
853     gp_Vec vecA = vec.Multiplied(.1);
854
855     gp_Dir DirAxis = aAxis.Direction();
856     gp_Vec Vaxe(DirAxis);
857     gp_Vec vecB = Vaxe.Multiplied(vecA.Magnitude());
858     vecB.Multiply(.5);
859
860     gp_Pnt pm = P1.Translated(vec.Multiplied(.5));
861     gp_Pnt pOff = OffsetPoint.Translated(vecB);
862     
863     //Calculate the extremas of the axis of the symbol
864     gp_Vec vecAxe = vecA.Multiplied(.7);
865
866     Prs3d_Root::NewGroup(aPresentation);
867     Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
868
869         aPrims = new Graphic3d_ArrayOfPolylines(13,5);
870
871     aPrims->AddBound(2);
872         aPrims->AddVertex(pOff.Translated(vecAxe));
873     aPrims->AddVertex(pOff.Translated(vecAxe.Reversed()));
874
875     //Calculate the extremas of the superior segment of the symbol
876     gp_Vec vec1 = vecAxe.Multiplied(.6);
877     vecAxe = Vaxe.Multiplied(vecAxe.Magnitude());
878     gp_Vec vec2 = vecAxe.Multiplied(.4);
879
880     aPrims->AddBound(2);
881     aPrims->AddVertex(pOff.Translated(vec1.Added(vec2)));
882     aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2)));
883     
884     //Calculate the extremas of the inferior segment of the symbol
885     aPrims->AddBound(2);
886     aPrims->AddVertex(pOff.Translated(vec1.Added(vec2.Reversed())));
887     aPrims->AddVertex(pOff.Translated(vec1.Reversed().Added(vec2.Reversed())));
888
889     /*--------------------------------------------------------------------------------------
890     |                          MARKING OF THE AXIS OF SYMMETRY                           |
891     --------------------------------------------------------------------------------------     
892             ____
893             \  / :Cursor
894              \/
895              /\
896             /__\
897     */
898     Standard_Real Dist = P1.Distance(P2)/75;
899     gp_Dir aDirectionAxis = aAxis.Direction();
900     gp_Vec vs(aDirectionAxis);
901     gp_Vec vsym(vs.Divided(vs.Magnitude()).Multiplied(Dist).XYZ());
902     gp_Vec vsymper(vsym.Y(),-vsym.X(),vsym.Z());
903
904     aPrims->AddBound(5);
905     gp_Pnt pm1 = pm.Translated(vsym.Added(vsymper));
906     aPrims->AddVertex(pm1);
907     pm1 = pm1.Translated(vsym.Reversed().Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
908     aPrims->AddVertex(pm1);
909     pm1 = pm1.Translated(vsymper.Multiplied(2));
910     aPrims->AddVertex(pm1);
911     pm1 = pm1.Translated(vsym.Multiplied(2).Added(vsymper.Reversed().Multiplied(2)));
912     aPrims->AddVertex(pm1);
913     pm1 = pm1.Translated(vsymper.Multiplied(2));
914     aPrims->AddVertex(pm1);
915
916     vsym.Multiply(4);
917
918     aPrims->AddBound(2);
919     aPrims->AddVertex(pm.Translated(vsym));
920     aPrims->AddVertex(pm.Translated(vsym.Reversed()));
921
922         Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray(aPrims);
923   } 
924 }