0024624: Lost word in license statement in source files
[occt.git] / src / AIS / AIS_PerpendicularRelation.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 #include <Standard_NotImplemented.hxx>
18
19 #include <AIS_PerpendicularRelation.ixx>
20
21 #include <AIS.hxx>
22
23 #include <BRepBuilderAPI_MakeFace.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRep_Tool.hxx>
26
27 #include <DsgPrs_PerpenPresentation.hxx>
28
29 #include <ElCLib.hxx>
30
31 #include <Geom2d_Line.hxx>
32 #include <GeomAPI.hxx>
33 #include <Geom_Line.hxx>
34 #include <Geom_Line.hxx>
35 #include <Geom_Plane.hxx>
36
37 #include <IntAna2d_AnaIntersection.hxx>
38 #include <IntAna2d_IntPoint.hxx>
39
40 #include <Precision.hxx>
41
42 #include <Select3D_SensitiveSegment.hxx>
43 #include <SelectMgr_EntityOwner.hxx>
44
45 #include <TopoDS.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Vertex.hxx>
49
50 #include <gce_MakeDir.hxx>
51
52 #include <gp_Pln.hxx>
53 #include <gp_Pnt.hxx>
54 #include <gp_Pnt2d.hxx>
55 #include <gp_Trsf.hxx>
56 #include <gp_Vec.hxx>
57 #include <Geom_Ellipse.hxx>
58
59 //=======================================================================
60 //function : Constructor
61 //purpose  : TwoEdgesPerpendicular
62 //=======================================================================
63 AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape, 
64                                                      const TopoDS_Shape& aSShape, 
65                                                      const Handle(Geom_Plane)& aPlane)
66 :AIS_Relation()
67 {
68   myFShape = aFShape;
69   mySShape = aSShape;
70   myPlane = aPlane;
71 }
72
73 //=======================================================================
74 //function : Constructor
75 //purpose  : TwoFacesPerpendicular
76 //=======================================================================
77 AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape, 
78                                                      const TopoDS_Shape& aSShape)
79 :AIS_Relation()
80 {
81   myFShape = aFShape;
82   mySShape = aSShape;
83 }
84
85 //=======================================================================
86 //function : Compute
87 //purpose  : 
88 //=======================================================================
89 void AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, 
90                                         const Handle(Prs3d_Presentation)& aPresentation, 
91                                         const Standard_Integer)
92 {
93   aPresentation->Clear();
94
95   if (myFShape.ShapeType() == mySShape.ShapeType()) {
96     switch (myFShape.ShapeType()) {
97     case TopAbs_FACE :
98       {
99         // cas perpendiculaire entre deux faces
100         ComputeTwoFacesPerpendicular(aPresentation);
101       }
102       break;
103     case TopAbs_EDGE :
104       {
105         // cas perpendiculaire entre deux edges
106         ComputeTwoEdgesPerpendicular(aPresentation);
107       }
108       break;
109     default:
110       break;
111     }
112   }
113   // Cas pas traite - Edge/Face
114 }
115
116 //=======================================================================
117 //function : Compute
118 //purpose  : to avoid warning
119 //=======================================================================
120 void AIS_PerpendicularRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
121                                         const Handle(Prs3d_Presentation)& aPresentation)
122 {
123 // Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
124  PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
125 }
126
127 void AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
128 {
129 // Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
130  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
131 }
132
133 //=======================================================================
134 //function : ComputeSelection
135 //purpose  : 
136 //=======================================================================
137 void AIS_PerpendicularRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, 
138                                                  const Standard_Integer)
139 {
140   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
141   const gp_Pnt& pos = myPosition;
142   Handle(Select3D_SensitiveSegment) seg;
143   Standard_Boolean ok1(Standard_False),ok2(Standard_False);
144
145   if (!myFAttach.IsEqual(pos,Precision::Confusion())) {
146     seg = new Select3D_SensitiveSegment(own,
147                                         myFAttach,
148                                         pos);
149     aSelection->Add(seg);
150     ok1 = Standard_True;
151  }
152   if (!mySAttach.IsEqual(myPosition,Precision::Confusion())) {
153     seg = new Select3D_SensitiveSegment(own,
154                                         mySAttach,
155                                         pos);
156     aSelection->Add(seg);
157     ok2 = Standard_True;
158   }
159
160   if (ok1 && ok2) {
161     gp_Vec vec1(gce_MakeDir(pos,myFAttach));
162     gp_Vec vec2(gce_MakeDir(pos,mySAttach));
163     Standard_Real dist1(pos.Distance(myFAttach));
164     Standard_Real dist2(pos.Distance(mySAttach));
165     vec1 *= dist1;
166     vec1 *= .2;
167     vec2 *= dist2;
168     vec2 *= .2;
169     
170     gp_Pnt pAx11 = pos.Translated(vec1);
171     gp_Pnt pAx22 = pos.Translated(vec2);
172     gp_Pnt p_symb = pAx22.Translated(vec1);
173     seg = new Select3D_SensitiveSegment(own,pAx11,p_symb);
174     aSelection->Add(seg);
175     seg = new Select3D_SensitiveSegment(own,p_symb,pAx22);
176     aSelection->Add(seg);
177   }
178 }
179
180 //=======================================================================
181 //function : ComputeTwoFacesPerpendicular
182 //purpose  : 
183 //=======================================================================
184 void AIS_PerpendicularRelation::ComputeTwoFacesPerpendicular
185   (const Handle(Prs3d_Presentation)& /*aPresentation*/)
186 {
187 }
188
189 //=======================================================================
190 //function : ComputeTwoEdgesPerpendicular
191 //purpose  : 
192 //=======================================================================
193 void AIS_PerpendicularRelation::ComputeTwoEdgesPerpendicular(const Handle(Prs3d_Presentation)& aPresentation)
194 {
195   // 3d lines
196   Handle(Geom_Curve) geom1,geom2;
197   gp_Pnt pint3d,p1,p2,pAx1,pAx2,ptat11,ptat12,ptat21,ptat22;
198   Standard_Boolean isInfinite1,isInfinite2;
199   Handle(Geom_Curve) extCurv;
200   if ( !AIS::ComputeGeometry(TopoDS::Edge(myFShape),TopoDS::Edge(mySShape),
201                             myExtShape,
202                             geom1,geom2,
203                             ptat11,ptat12,ptat21,ptat22,
204                             extCurv,
205                             isInfinite1,isInfinite2,
206                             myPlane) ) return;
207
208   Standard_Boolean interOut1(Standard_False),interOut2(Standard_False);
209   
210   Handle(Geom_Line) geom_lin1;
211   Handle(Geom_Line) geom_lin2;
212   if ( geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)) )
213     {
214       const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom1;
215       // construct lines through focuses
216       gp_Ax1 elAx = geom_el->XAxis();
217       gp_Lin ll (elAx);
218       geom_lin1 = new Geom_Line(ll);
219       Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
220       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
221       ptat11 = geom_el->Focus1().Translated(transvec);
222       ptat12 = geom_el->Focus2().Translated(-transvec);
223       interOut1 = Standard_True;
224     }
225   else if ( geom1->IsInstance(STANDARD_TYPE(Geom_Line)) )
226     {
227       geom_lin1 = (Handle(Geom_Line)&) geom1;
228     }
229   else return;
230
231   if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
232     {
233       const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom2;
234       // construct lines through focuses
235       gp_Ax1 elAx = geom_el->XAxis();
236       gp_Lin ll (elAx);
237       geom_lin2 = new Geom_Line(ll);
238       Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
239       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
240       ptat21 = geom_el->Focus1().Translated(transvec);
241       ptat22 = geom_el->Focus2().Translated(-transvec);
242       interOut2 = Standard_True;
243     }
244   else if ( geom2->IsInstance(STANDARD_TYPE(Geom_Line)) )
245     {
246       geom_lin2 = (Handle(Geom_Line)&) geom2;
247     }
248   else return;
249
250   // current face
251   BRepBuilderAPI_MakeFace makeface (myPlane->Pln());
252   TopoDS_Face face (makeface.Face());  
253   BRepAdaptor_Surface adp (makeface.Face());
254   
255   // 2d lines => projection of 3d on current plane
256   Handle(Geom2d_Curve) aGeom2dCurve = GeomAPI::To2d(geom_lin1,myPlane->Pln());
257   Handle(Geom2d_Line) lin1_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
258   aGeom2dCurve = GeomAPI::To2d(geom_lin2,myPlane->Pln());
259   Handle(Geom2d_Line) lin2_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
260   IntAna2d_AnaIntersection inter(lin1_2d->Lin2d(),lin2_2d->Lin2d());
261   if (!inter.IsDone()) return;
262   if (!inter.NbPoints()) return;
263   
264   gp_Pnt2d pint(inter.Point(1).Value());
265   pint3d = adp.Value(pint.X(),pint.Y());
266
267   myPosition = pint3d;
268   // recherche points attache
269   Standard_Real par1,par2,curpar,pmin,pmax;//,dist,sign;
270   Standard_Real length(0.);
271   
272   if ( isInfinite1 && isInfinite2 )
273     {
274       Standard_Real curpar1 = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
275       Standard_Real curpar2 = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
276       par1 = par2 = 50.;    
277       p1 = p2 = pint3d;
278       myFAttach = ElCLib::Value(curpar1+par1,geom_lin1->Lin());
279       mySAttach = ElCLib::Value(curpar2+par2,geom_lin2->Lin());    
280     }
281   else
282     {
283       Standard_Boolean lengthComputed (Standard_False);
284       if ( !isInfinite1 )
285         {
286           curpar = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
287           par1 = ElCLib::Parameter(geom_lin1->Lin(),ptat11);
288           par2 = ElCLib::Parameter(geom_lin1->Lin(),ptat12);
289           pmin = Min(par1,par2);
290           pmax = Max(par1,par2);
291       
292           if ( myPosition.SquareDistance(ptat11) > myPosition.SquareDistance(ptat12) )
293             p1 = ptat11;
294           else
295             p1 = ptat12;
296           if ( (curpar < pmin) || (curpar > pmax) )
297             {
298               interOut1 = Standard_True;
299             }
300           if ( !isInfinite2 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
301           else length = 2.*ptat11.Distance(ptat12)/5.;
302           lengthComputed = Standard_True;
303           gp_Vec vec1 (gce_MakeDir(myPosition,p1));
304           vec1.Multiply(length);
305           pAx1 = myPosition.Translated(vec1);
306           myFAttach = pAx1;
307         }
308       if ( !isInfinite2 )
309         {
310           curpar = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
311           par1 = ElCLib::Parameter(geom_lin2->Lin(),ptat21);
312           par2 = ElCLib::Parameter(geom_lin2->Lin(),ptat22);
313           pmin = Min(par1,par2);
314           pmax = Max(par1,par2);
315           
316           if ( myPosition.SquareDistance(ptat21) > myPosition.SquareDistance(ptat22) ) p2 = ptat21;
317           else p2 = ptat22;
318           if ( (curpar < pmin) || (curpar > pmax) )
319             {
320               interOut2 = Standard_True;
321             }
322           gp_Vec vec2 (gce_MakeDir(myPosition,p2));
323           if ( !lengthComputed )
324             {
325               if ( !isInfinite1 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
326               else length = 2.*ptat21.Distance(ptat22)/5.;
327             }
328           vec2.Multiply(length);
329           pAx2 = myPosition.Translated(vec2);
330           mySAttach = pAx2;
331         }
332       if ( isInfinite1 )
333         {
334           p1 = myPosition;
335           gp_Vec vec1(geom_lin1->Lin().Direction());
336           vec1.Multiply(length);
337           myFAttach = myPosition.Translated(vec1);
338         }
339       if ( isInfinite2 )
340         {
341           p2 = myPosition;
342           gp_Vec vec2(geom_lin2->Lin().Direction());
343           vec2.Multiply(length);
344           mySAttach = myPosition.Translated(vec2);      
345         }
346     }
347   DsgPrs_PerpenPresentation::Add(aPresentation,myDrawer,
348                                  myFAttach,mySAttach,
349                                  p1,p2,
350                                  myPosition,
351                                  interOut1,interOut2);
352
353   if ( (myExtShape != 0) && !extCurv.IsNull()) {
354     gp_Pnt pf,pl;
355     if ( myExtShape == 1 ) {
356       if (!isInfinite1) {
357         pf = ptat11; 
358         pl = ptat12;
359       }
360       aPresentation->SetInfiniteState(isInfinite1);
361       ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
362     }
363     else {
364       if (!isInfinite2) {
365         pf = ptat21; 
366         pl = ptat22;
367       }
368       aPresentation->SetInfiniteState(isInfinite2);
369       ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
370     }
371   }
372 }