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