Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_ParallelRelation.cxx
1 // File:        AIS_ParallelRelation.cdl
2 // Created:     Tue Dec  5 15:09:04 1996
3 // Author:      Jean-Pierre COMBE/Odile Olivier
4 //              <ODL>
5
6 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
7 //                      if any in all dimensions.
8
9 #include <AIS_ParallelRelation.ixx>
10
11 #include <Standard_NotImplemented.hxx>
12 #include <Standard_DomainError.hxx>
13
14 #include <Precision.hxx>
15
16 #include <TCollection_AsciiString.hxx>
17 #include <TCollection_ExtendedString.hxx>
18
19 #include <DsgPrs_LengthPresentation.hxx>
20
21 #include <Prs3d_Drawer.hxx>
22 #include <Prs3d_ArrowAspect.hxx>
23 #include <Prs3d_LengthAspect.hxx>
24
25 #include <AIS.hxx>
26 #include <AIS_Drawer.hxx>
27
28 #include <SelectMgr_EntityOwner.hxx>
29 #include <Select3D_SensitiveSegment.hxx>
30 #include <Select3D_SensitiveBox.hxx>
31
32 #include <TopoDS.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepAdaptor_Surface.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37
38 #include <gp_Lin.hxx>
39 #include <gp_Pnt.hxx>
40 #include <ElCLib.hxx>
41 #include <gp_Pln.hxx>
42 #include <gp_Dir.hxx>
43 #include <gp_Ax1.hxx>
44 #include <gp_Ax2.hxx>
45
46 #include <gce_MakeLin.hxx>
47
48 #include <Geom_Plane.hxx>
49 #include <Geom_Line.hxx>
50 #include <Geom_Ellipse.hxx>
51
52 //=======================================================================
53 //function : Constructor
54 //purpose  : 
55 //=======================================================================
56 AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, 
57                                            const TopoDS_Shape& aSShape, 
58                                            const Handle(Geom_Plane)& aPlane)
59 {
60   myFShape = aFShape;
61   mySShape = aSShape;
62   myPlane = aPlane;
63   myAutomaticPosition = Standard_True;
64   myArrowSize = 0.01;
65   mySymbolPrs = DsgPrs_AS_BOTHAR;
66 }
67
68 //=======================================================================
69 //function : Constructor
70 //purpose  : 
71 //=======================================================================
72 AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, 
73                                            const TopoDS_Shape& aSShape, 
74                                            const Handle(Geom_Plane)& aPlane, 
75                                            const gp_Pnt& aPosition,
76                                            const DsgPrs_ArrowSide aSymbolPrs, 
77                                            const Standard_Real anArrowSize)
78 {
79   myFShape = aFShape;
80   mySShape = aSShape;
81   myPlane = aPlane;
82   myAutomaticPosition = Standard_False;
83 #ifdef BUC60915
84   SetArrowSize( anArrowSize );
85 #else
86   myArrowSize = anArrowSize;
87 #endif
88   myPosition = aPosition;
89   mySymbolPrs = aSymbolPrs;
90 }
91
92 //=======================================================================
93 //function : Compute
94 //purpose  : 
95 //=======================================================================
96 void AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, 
97                                    const Handle(Prs3d_Presentation)& aPresentation, 
98                                    const Standard_Integer)
99 {
100   aPresentation->Clear();
101
102   switch (myFShape.ShapeType())
103     {
104     case TopAbs_FACE :
105       {
106         // cas longueur entre deux faces
107         ComputeTwoFacesParallel(aPresentation);
108       }
109       break;
110     case TopAbs_EDGE :
111       {
112         // cas longueur entre deux edges
113         ComputeTwoEdgesParallel(aPresentation);
114       }
115       break;
116     default:
117       break;
118     }
119 }
120
121 //=======================================================================
122 //function : Compute
123 //purpose  : to avoid warning
124 //=======================================================================
125 void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
126                                    const Handle(Prs3d_Presentation)& aPresentation)
127 {
128 // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
129   PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
130 }
131
132 //=======================================================================
133 //function : Compute
134 //purpose  : to avoid warning
135 //=======================================================================
136 void AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d, 
137                                    const Handle(Graphic2d_GraphicObject)& aGraphicObject,
138                                    const Standard_Integer anInteger)
139 {
140 // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
141   PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
142 }
143
144 void AIS_ParallelRelation::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
145 {
146 // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
147   PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
148 }
149
150 //=======================================================================
151 //function : ComputeSelection
152 //purpose  : 
153 //=======================================================================
154 void AIS_ParallelRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, 
155                                             const Standard_Integer)
156 {
157   gp_Lin L1 (myFAttach,myDirAttach);
158   gp_Lin L2 (mySAttach,myDirAttach);
159   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
160   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
161   
162   gp_Lin L3;
163   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
164
165   if (!Proj1.IsEqual(Proj2,Precision::Confusion()))
166     {
167       L3 = gce_MakeLin(Proj1,Proj2);
168     }
169   else
170     {
171       L3 = gce_MakeLin(Proj1,myDirAttach);
172       Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
173       Handle(Select3D_SensitiveBox) box =
174         new Select3D_SensitiveBox(own,
175                                   myPosition.X(),
176                                   myPosition.Y(),
177                                   myPosition.Z(),
178                                   myPosition.X()+size,
179                                   myPosition.Y()+size,
180                                   myPosition.Z()+size);
181       aSelection->Add(box);
182     }
183   Standard_Real parmin,parmax,parcur;
184   parmin = ElCLib::Parameter(L3,Proj1);
185   parmax = parmin;
186   
187   parcur = ElCLib::Parameter(L3,Proj2);
188   parmin = Min(parmin,parcur);
189   parmax = Max(parmax,parcur);
190   
191   parcur = ElCLib::Parameter(L3,myPosition);
192   parmin = Min(parmin,parcur);
193   parmax = Max(parmax,parcur);
194   
195   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
196   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
197
198   Handle(Select3D_SensitiveSegment) seg;
199   
200   if (!PointMin.IsEqual(PointMax,Precision::Confusion()))
201     {
202       seg = new Select3D_SensitiveSegment(own,
203                                           PointMin,
204                                           PointMax);
205       aSelection->Add(seg);
206     }
207   if (!myFAttach.IsEqual(Proj1,Precision::Confusion()))
208     {
209       seg = new Select3D_SensitiveSegment(own, myFAttach, Proj1);
210       aSelection->Add(seg);
211     }
212   if (!mySAttach.IsEqual(Proj2,Precision::Confusion()))
213     {
214       seg = new Select3D_SensitiveSegment(own, mySAttach, Proj2);
215       aSelection->Add(seg);
216     }
217 }
218
219 //=======================================================================
220 //function : ComputeTwoFacesParallel
221 //purpose  : 
222 //=======================================================================
223 void AIS_ParallelRelation::ComputeTwoFacesParallel(const Handle(Prs3d_Presentation)&)
224 {
225   Standard_NotImplemented::Raise("AIS_ParallelRelation::ComputeTwoFacesParallel not implemented");
226 }
227
228 //=======================================================================
229 //function : ComputeTwoEdgesParallel
230 //purpose  : 
231 //=======================================================================
232 void AIS_ParallelRelation::ComputeTwoEdgesParallel(const Handle(Prs3d_Presentation)& aPresentation)
233 {
234   TopoDS_Edge E1 = TopoDS::Edge(myFShape);
235   TopoDS_Edge E2 = TopoDS::Edge(mySShape);
236
237   gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
238   Handle(Geom_Curve) geom1,geom2;
239   Standard_Boolean isInfinite1,isInfinite2;
240   Handle(Geom_Curve) extCurv;
241   if (!AIS::ComputeGeometry(E1,E2,myExtShape,
242                             geom1,geom2,
243                             ptat11,ptat12,ptat21,ptat22,
244                             extCurv,
245                             isInfinite1,isInfinite2,
246                             myPlane))
247     {
248       return;
249     }
250
251   aPresentation->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape != 0));
252
253   gp_Lin l1;
254   gp_Lin l2;
255   Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
256
257   if (geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
258     {
259       const Handle(Geom_Ellipse)& geom_el1 = (Handle(Geom_Ellipse)&) geom1;
260       // construct lines through focuses
261       gp_Ax1 elAx = geom_el1->XAxis();
262       l1 = gp_Lin(elAx);
263       Standard_Real focex = geom_el1->MajorRadius() - geom_el1->Focal()/2.0;
264       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
265       ptat11 = geom_el1->Focus1().Translated(transvec);
266       ptat12 = geom_el1->Focus2().Translated(-transvec);
267       isEl1 = Standard_True;
268     }
269   else if (geom1->IsInstance(STANDARD_TYPE(Geom_Line)))
270     {
271       const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
272       l1 = geom_lin1->Lin();
273     }
274   else return;
275
276   if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
277     {
278       const Handle(Geom_Ellipse)& geom_el2 = (Handle(Geom_Ellipse)&) geom2;
279       // construct lines through focuses
280       gp_Ax1 elAx = geom_el2->XAxis();
281       l2 = gp_Lin(elAx);
282       Standard_Real focex = geom_el2->MajorRadius() - geom_el2->Focal()/2.0;
283       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
284       ptat21 = geom_el2->Focus1().Translated(transvec);
285       ptat22 = geom_el2->Focus2().Translated(-transvec);
286       isEl2 = Standard_True;
287     }
288   else if (geom2->IsInstance(STANDARD_TYPE(Geom_Line)))
289     {
290       const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
291       l2 = geom_lin2->Lin();
292     }
293   else return;
294
295   const Handle(Geom_Line)& geom_lin1 = new Geom_Line(l1);
296   const Handle(Geom_Line)& geom_lin2 = new Geom_Line(l2);
297
298   myDirAttach = l1.Direction();
299   // size
300 #ifdef BUC60915
301   if( !myArrowSizeIsDefined ) {
302 #endif
303     Standard_Real arrSize1 (myArrowSize), arrSize2 (myArrowSize);
304     if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/50.;
305     if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/50.;
306     myArrowSize = Max(myArrowSize,Max(arrSize1,arrSize2));
307 //  myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
308 #ifdef BUC60915
309   }
310 #endif
311
312   if ( myAutomaticPosition )
313     {    
314       gp_Pnt curpos;
315       if ( !isInfinite1 )
316         {
317           gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
318           curpos.SetXYZ((ptat11.XYZ() + p2.XYZ())/2.);
319         }
320       else if ( !isInfinite2 )
321         {
322           gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
323           curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
324         }
325       else
326         {
327           curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
328         }
329       // offset pour eviter confusion Edge et Dimension
330       gp_Vec offset (myDirAttach);
331       offset = offset*myArrowSize*(-10.);
332       curpos.Translate(offset);
333       myPosition = curpos;
334     }
335
336   // recherche points attache
337   if (!isInfinite1)
338     {
339       if ( isEl1 )
340         {
341           if (myPosition.Distance(ptat11) < myPosition.Distance(ptat12)) myFAttach = ptat12;
342           else myFAttach = ptat11;
343         }
344       else
345         {
346           if (myPosition.Distance(ptat11) > myPosition.Distance(ptat12)) myFAttach = ptat12;
347           else myFAttach = ptat11;
348         }
349     }
350   else
351     {
352       myFAttach = ElCLib::Value(ElCLib::Parameter(l1,myPosition),l1);
353     }
354   
355   if (!isInfinite2)
356     {
357       if ( isEl2 )
358         {
359           if (myPosition.Distance(ptat21) < myPosition.Distance(ptat22)) mySAttach = ptat22;
360           else mySAttach = ptat21;
361         }
362       else
363         {
364           if (myPosition.Distance(ptat21) > myPosition.Distance(ptat22)) mySAttach = ptat22;
365           else mySAttach = ptat21;
366         }
367     }
368   else
369     {
370       mySAttach = ElCLib::Value(ElCLib::Parameter(l2,myPosition),l2);
371     }
372   TCollection_ExtendedString aText (" //");
373   
374   if (l1.Distance(l2) <= Precision::Confusion())
375     {
376       myArrowSize = 0.;
377     }
378   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
379   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
380   arr->SetLength(myArrowSize);
381   arr = la->Arrow2Aspect();
382   arr->SetLength(myArrowSize);
383   if ( myExtShape == 1)
384     mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
385   else if ( myExtShape == 2)
386     mySymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
387
388   DsgPrs_LengthPresentation::Add(aPresentation,
389                                  myDrawer,
390                                  aText,
391                                  myFAttach,
392                                  mySAttach,
393                                  myDirAttach,
394                                  myPosition,
395                                  mySymbolPrs);
396   if ( (myExtShape != 0) &&  !extCurv.IsNull())
397     {
398       gp_Pnt pf, pl;
399       if ( myExtShape == 1 )
400         {
401           if (!isInfinite1)
402             {
403               pf = ptat11; 
404               pl = ptat12;
405             }
406           ComputeProjEdgePresentation(aPresentation,E1,geom_lin1,pf,pl);
407         }
408       else
409         {
410           if (!isInfinite2)
411             {
412               pf = ptat21; 
413               pl = ptat22;
414             }
415           ComputeProjEdgePresentation(aPresentation,E2,geom_lin2,pf,pl);
416         }
417     }
418 }