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