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