0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / LocOpe / LocOpe.cxx
1 // Created on: 1996-04-02
2 // Created by: Jacques GOUSSARD
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 <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Curve2d.hxx>
21 #include <BRepAdaptor_HCurve2d.hxx>
22 #include <BRepAdaptor_HSurface.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2dInt_GInter.hxx>
25 #include <Geom_Curve.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <LocOpe.hxx>
28 #include <Precision.hxx>
29 #include <TopExp.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopoDS.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Shape.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Wire.hxx>
37 #include <TopTools_MapOfShape.hxx>
38
39 #define NECHANT 10
40
41
42 //=======================================================================
43 //function : Closed
44 //purpose  : 
45 //=======================================================================
46
47 Standard_Boolean LocOpe::Closed(const TopoDS_Wire& W,
48                                 const TopoDS_Face& F)
49 {
50   TopoDS_Vertex Vf,Vl;
51   TopExp::Vertices(W,Vf,Vl);
52   if (!Vf.IsSame(Vl)) {
53     return Standard_False;
54   }
55
56   // On recherche l`edge contenant Vf FORWARD
57
58   TopExp_Explorer exp,exp2;
59   for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
60        exp.More();exp.Next()) {
61     for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
62       if (exp2.Current().IsSame(Vf) && 
63           exp2.Current().Orientation() == TopAbs_FORWARD) {
64         break;
65       }
66     }
67     if (exp2.More()) {
68       break;
69     }
70   }
71   TopoDS_Edge Ef = TopoDS::Edge(exp.Current());
72   
73   // On recherche l`edge contenant Vl REVERSED
74
75   for (exp.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
76        exp.More();exp.Next()) {
77     for (exp2.Init(exp.Current(),TopAbs_VERTEX);exp2.More();exp2.Next()) {
78       if (exp2.Current().IsSame(Vl) && 
79           exp2.Current().Orientation() == TopAbs_REVERSED) {
80         break;
81       }
82     }
83     if (exp2.More()) {
84       break;
85     }
86   }
87   TopoDS_Edge El = TopoDS::Edge(exp.Current());
88   
89   Standard_Real f,l;
90   gp_Pnt2d pf,pl;
91   Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(Ef,F,f,l);
92   if (Ef.Orientation() == TopAbs_FORWARD) {
93     pf = C2d->Value(f);
94   }
95   else {
96     pf = C2d->Value(l);
97   }
98   C2d = BRep_Tool::CurveOnSurface(El,F,f,l);
99   if (El.Orientation() == TopAbs_FORWARD) {
100     pl = C2d->Value(l);
101   }
102   else {
103     pl = C2d->Value(f);
104   }
105
106   if (pf.Distance(pl) <= Precision::PConfusion(Precision::Confusion())) {
107     return Standard_True;
108   }
109   return Standard_False;
110 }
111
112
113 //=======================================================================
114 //function : Closed
115 //purpose  : 
116 //=======================================================================
117
118 Standard_Boolean LocOpe::Closed(const TopoDS_Edge& E,
119                                 const TopoDS_Face& F)
120 {
121   BRep_Builder B;
122   TopoDS_Wire W;
123   B.MakeWire(W);
124   B.Add(W,E.Oriented(TopAbs_FORWARD));
125   return LocOpe::Closed(W,F);
126 }
127
128
129
130 //=======================================================================
131 //function : Closed
132 //purpose  : 
133 //=======================================================================
134
135 Standard_Boolean LocOpe::TgtFaces(const TopoDS_Edge& E,
136                                   const TopoDS_Face& F1,
137                                   const TopoDS_Face& F2)
138 {
139   BRepAdaptor_Surface bs(F1, Standard_False);
140   Standard_Real u;
141   Standard_Real ta = 0.0001;
142
143   TopoDS_Edge e = E;
144
145   Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface(F1);
146   Handle(BRepAdaptor_HSurface) HS2 = new BRepAdaptor_HSurface(F2);
147   e.Orientation(TopAbs_FORWARD);
148   Handle(BRepAdaptor_HCurve2d) HC2d = new BRepAdaptor_HCurve2d();
149   Handle(BRepAdaptor_HCurve2d) HC2d2 = new BRepAdaptor_HCurve2d();
150   HC2d->ChangeCurve2d().Initialize(e,F1);
151   HC2d2->ChangeCurve2d().Initialize(e,F2);
152   
153
154 //  Adaptor3d_CurveOnSurface C1(HC2d,HS1);
155
156   Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED);
157   Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED);
158   Standard_Real f,l,eps,angmin = M_PI,angmax = -M_PI,ang;
159   BRep_Tool::Range(e,f,l);
160
161   eps = (l - f)/100.;
162   f += eps; // pour eviter de faire des calculs sur les 
163   l -= eps; // pointes des carreaux pointus.
164   gp_Pnt2d p;
165   gp_Pnt pp1;
166   gp_Vec du,dv;
167   gp_Vec d1,d2;
168
169   Standard_Real uu, vv;
170
171   Standard_Integer i;
172   for(i = 0; i <= 20; i++){
173     u = f + (l-f)*i/20;
174     HC2d->D0(u,p);
175     HS1->D1(p.X(),p.Y(),pp1,du,dv);
176     d1 = (du.Crossed(dv)).Normalized();
177     if(rev1) d1.Reverse();
178     HC2d2->D0(u,p);
179     p.Coord(uu,vv);
180     HS2->D1(uu,vv,pp1,du,dv);
181     d2 = (du.Crossed(dv)).Normalized();
182     if(rev2) d2.Reverse();
183     ang = d1.Angle(d2);
184     if(ang <= angmin) angmin = ang;
185     if(ang >= angmax) angmax = ang;
186   }
187   return (angmax<=ta);
188 }
189
190
191 //=======================================================================
192 //function : SampleEdges
193 //purpose  : 
194 //=======================================================================
195
196 void LocOpe::SampleEdges(const TopoDS_Shape& theShape,
197                          TColgp_SequenceOfPnt& theSeq)
198 {
199   theSeq.Clear();
200   TopTools_MapOfShape theMap;
201   
202   TopExp_Explorer exp(theShape,TopAbs_EDGE);
203   TopLoc_Location Loc;
204   Handle(Geom_Curve) C;
205   Standard_Real f,l,prm;
206   Standard_Integer i;
207
208   // Computes points on edge, but does not take the extremities into account
209   for (; exp.More(); exp.Next()) {
210     const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
211     if (!theMap.Add(edg)) {
212       continue;
213     }
214     if (!BRep_Tool::Degenerated(edg)) {
215       C = BRep_Tool::Curve(edg,Loc,f,l);
216       C = Handle(Geom_Curve)::
217         DownCast(C->Transformed(Loc.Transformation()));
218       Standard_Real delta = (l - f)/NECHANT*0.123456;
219       for (i=1; i<NECHANT; i++) {
220         prm = delta + ((NECHANT-i)*f+i*l)/NECHANT;
221         theSeq.Append(C->Value(prm));
222       }
223     }
224   }
225
226   // Adds every vertex
227   for (exp.Init(theShape,TopAbs_VERTEX); exp.More(); exp.Next()) {
228     if (theMap.Add(exp.Current())) {
229       theSeq.Append(BRep_Tool::Pnt(TopoDS::Vertex(exp.Current())));
230     }
231   }
232 }
233
234
235
236
237
238 /*
239 Standard_Boolean LocOpe::IsInside(const TopoDS_Face& F1,
240                                   const TopoDS_Face& F2)
241 {
242   Standard_Boolean Result = Standard_True;
243
244   TopExp_Explorer exp1, exp2;
245
246   for(exp1.Init(F1, TopAbs_EDGE); exp1.More(); exp1.Next())  {
247     TopoDS_Edge e1 = TopoDS::Edge(exp1.Current());
248     BRepAdaptor_Curve2d C1(e1, F1); 
249     for(exp2.Init(F2, TopAbs_EDGE); exp2.More(); exp2.Next())  {
250       TopoDS_Edge e2 = TopoDS::Edge(exp2.Current());
251       BRepAdaptor_Curve2d C2(e2, F2); 
252       Geom2dInt_GInter C;
253       C.Perform(C1, C2, Precision::Confusion(), Precision::Confusion());
254       if(!C.IsEmpty()) Result = Standard_False;
255       if(Result == Standard_False) {
256         for(exp3.Init(e2, TopAbs_VERTEX); exp3.More(); exp3.Next())  {
257           
258         }
259       }
260     }
261     if(Result == Standard_False) break;
262   }
263   return Result;
264 }
265
266 */
267
268
269