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