0025418: Debug output to be limited to OCC development environment
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_CLASSI.cxx
CommitLineData
b311480e 1// Created on: 1999-01-13
2// Created by: Xuan PHAM PHU
3// Copyright (c) 1999-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <TopOpeBRepTool_CLASSI.ixx>
18#include <TopOpeBRepTool_define.hxx>
19#include <TopOpeBRepTool_EXPORT.hxx>
20#include <TopOpeBRepTool_TOOL.hxx>
21#include <TopOpeBRepTool_2d.hxx>
22#include <TopExp_Explorer.hxx>
23#include <Bnd_Array1OfBox2d.hxx>
24#include <Bnd_Box2d.hxx>
25#include <TColStd_Array2OfReal.hxx>
26#include <BndLib_Add2dCurve.hxx>
27#include <BRepAdaptor_Curve2d.hxx>
28#include <BRepClass3d_SolidExplorer.hxx>
29#include <BRepClass_FaceClassifier.hxx>
30#include <TopoDS.hxx>
31#include <BRep_Tool.hxx>
32
33#define SAME (-1)
34#define DIFF (-2)
35#define UNKNOWN ( 0)
36#define oneINtwo ( 1)
37#define twoINone ( 2)
38
39#define M_IN(st ) (st == TopAbs_IN )
40#define M_OUT(st) (st == TopAbs_OUT)
41
42//=======================================================================
43//function : TopOpeBRepTool_CLASSI
44//purpose :
45//=======================================================================
46
47TopOpeBRepTool_CLASSI::TopOpeBRepTool_CLASSI()
48{
49}
50
51//=======================================================================
52//function : Init2d
53//purpose :
54//=======================================================================
55
56void TopOpeBRepTool_CLASSI::Init2d(const TopoDS_Face& Fref)
57{
58 myFref = Fref;
59}
60
61//=======================================================================
62//function : HasInit2d
63//purpose :
64//=======================================================================
65
66Standard_Boolean TopOpeBRepTool_CLASSI::HasInit2d() const
67{
68 return (!myFref.IsNull());
69}
70
71
72
73//=======================================================================
74//function : Add2d
75//purpose :
76//=======================================================================
77
78Standard_Boolean TopOpeBRepTool_CLASSI::Add2d(const TopoDS_Shape& S)
79{
80 if (!HasInit2d()) return Standard_False;
81
82 Standard_Boolean isb = mymapsbox2d.Contains(S);
83 if (isb) return Standard_True;
84
85 Bnd_Box2d B2d;
86 TopExp_Explorer exe(S, TopAbs_EDGE);
87 for (; exe.More(); exe.Next()){
88 const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
89 Standard_Real tolE = BRep_Tool::Tolerance(E);
90
91 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,myFref);
92 if (!haspc) return Standard_False;
93 BRepAdaptor_Curve2d BC2d(E,myFref);
94 Standard_Real tol2d = BC2d.Resolution(tolE);
95 BndLib_Add2dCurve::Add(BC2d,tol2d,B2d);
96 }
97 mymapsbox2d.Add(S,B2d);
98 return Standard_True;
99}
100
101//=======================================================================
102//function : GetBox2d
103//purpose :
104//=======================================================================
105
106Standard_Boolean TopOpeBRepTool_CLASSI::GetBox2d(const TopoDS_Shape& S, Bnd_Box2d& B2d)
107{
108 Standard_Boolean isb = mymapsbox2d.Contains(S);
109 if (!isb) isb = Add2d(S);
110 if (!isb) return Standard_False;
111 B2d = mymapsbox2d.FindFromKey(S);
112 return Standard_True;
113}
114
115//=======================================================================
116//function : ClassiBnd2d
117//purpose :
118//=======================================================================
119
120Standard_Integer TopOpeBRepTool_CLASSI::ClassiBnd2d(const TopoDS_Shape& S1,const TopoDS_Shape& S2,
121 const Standard_Real tol,const Standard_Boolean chklarge)
122{
123 Bnd_Array1OfBox2d B(1,2);
124 Standard_Boolean isb = mymapsbox2d.Contains(S1);
125 if (!isb) isb = Add2d(S1);
126 if (!isb) return Standard_False;
127 B(1) = mymapsbox2d.FindFromKey(S1);
128 isb = mymapsbox2d.Contains(S2);
129 if (!isb) isb = Add2d(S2);
130 if (!isb) return Standard_False;
131 B(2) = mymapsbox2d.FindFromKey(S2);
132
133 TColStd_Array2OfReal UV(1,2, 1,4);
134// for (Standard_Integer i = 1; i <= 2; i++)
135 Standard_Integer i ;
136 for ( i = 1; i <= 2; i++)
137 // (Umin(i), Vmin(i), Umax(i), Vmax(i))
138 B(i).Get(UV(i,1), UV(i,3), UV(i,2), UV(i,4));
139
0797d9d3 140#ifdef OCCT_DEBUG
7fd59977 141 Standard_Boolean trc = Standard_False;
142 if (trc) {
143 for (Standard_Integer i = 1; i <= 2; i++)
144 cout<<"B("<<i<<") = ("<<UV(i,1)<<" "<<UV(i,3)<<" "<<UV(i,2)<<" "<<UV(i,4)<<")"<<endl;
145 }
146#endif
147
148 for (Standard_Integer k = 1; k <= 3; k+=2) {
149 for (i = 1; i <= 2; i++) {
150 Standard_Integer ii = i, jj = (i == 1) ? 2 : 1;
151 // diff = Umin<ii> - Umax<jj> : k = 1
152 // diff = Vmin<ii> - Vmax<jj> : k = 3
153 Standard_Real diff = UV(ii,k) - UV(jj,k+1);
154 // IMPORTANT : for splitted faces sharing same edge, use
155 // chklarge = True.
156 Standard_Boolean disjoint = chklarge ? (diff >= -tol) : (diff > 0.);
157 if (disjoint) return DIFF;
158 }
159 }
160
161 for (i = 1; i <= 2; i++) {
162 // comparing Bnd2d(ii) with Bnd2d(jj)
163 Standard_Integer ii = i, jj = (i == 1) ? 2 : 1;
164 Standard_Boolean smaller=Standard_True, same=Standard_True;
165
166// for (Standard_Integer k = 1; k <= 3; k += 2){
167 Standard_Integer k ;
168 for ( k = 1; k <= 3; k += 2){
169 // diff = Umin<ii> - Umin<jj> : k = 1
170 // diff = Vmin<ii> - Vmin<jj> : k = 3
171 Standard_Real diff = UV(ii,k) - UV(jj,k);
172 smaller = chklarge ? (smaller && (diff > -tol)) : (smaller && (diff > 0.));
173 same = same && (Abs(diff) <= tol);
174 }
175 for (k = 2; k <= 4; k +=2){
176 // diff = Umax<ii> - Umax<jj> : k = 2
177 // diff = Vmax<ii> - Vmax<jj> : k = 4
178 Standard_Real diff = UV(ii,k) - UV(jj,k);
179 smaller = chklarge ? (smaller && (diff < tol)) : (smaller && (diff < 0.));
180 same = same && (Abs(diff) <= tol);
181 }
182
183 if (same) return SAME;
184 if (smaller) {
185 Standard_Integer sta = (ii==1) ? oneINtwo : twoINone;
186 return sta;
187 }
188 }
189 return UNKNOWN;
190}
191
192static Standard_Integer FUN_thegreatest(const TopoDS_Face& F1, BRepClass_FaceClassifier& class2)
193// prequesitory : p2d1 IN f2, p2d2 IN f1
194// class2 for f2
195// returns oneINtwo || twoINone || UNKNOWN
196{
197 TopExp_Explorer ex1(F1, TopAbs_EDGE);
198 Standard_Real tolf1 = BRep_Tool::Tolerance(F1);
199 for (; ex1.More(); ex1.Next()){
200 const TopoDS_Edge& e1 = TopoDS::Edge(ex1.Current());
201 Standard_Real f1,l1; FUN_tool_bounds(e1,f1,l1);
202 Standard_Real x= 0.45678; Standard_Real p1 = (1-x)*f1+x+l1;
203 gp_Pnt2d uv1; Standard_Boolean ok1 = FUN_tool_paronEF(e1,p1,F1,uv1,tolf1);
204 if (!ok1) continue;
205 TopAbs_State sta12 = class2.State();
206 if (M_IN(sta12) ) return oneINtwo;
207 else if (M_OUT(sta12)) return twoINone;
208 }
209 return UNKNOWN;
210}
211
212//=======================================================================
213//function : Classip2d
214//purpose :
215//=======================================================================
216
217Standard_Integer TopOpeBRepTool_CLASSI::Classip2d(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
218 const Standard_Integer stabnd2d12)
219{
220 if (!HasInit2d()) return UNKNOWN;
221 Standard_Boolean bnd2dUNK = (stabnd2d12 == UNKNOWN)||(stabnd2d12 == SAME);
222
223 // fa1,ffi1,finite1 :
224 TopOpeBRepTool_face fa1;
225 Standard_Boolean isb1 = mymapsface.IsBound(S1);
226 if (isb1) fa1 = mymapsface.Find(S1);
227 else {
228 Standard_Boolean ok1 = fa1.Init(TopoDS::Wire(S1), myFref);
229 if (!ok1) return UNKNOWN;
230 mymapsface.Bind(S1,fa1);
231 }
232 const TopoDS_Face& ffi1 = fa1.Ffinite();
233 Standard_Boolean finite1 = fa1.Finite();
234
235 // fa2,ffi2,finite2 :
236 TopOpeBRepTool_face fa2;
237 Standard_Boolean isb2 = mymapsface.IsBound(S2);
238 if (isb2) fa2 = mymapsface.Find(S2);
239 else {
240 Standard_Boolean ok2 = fa2.Init(TopoDS::Wire(S2), myFref);
241 if (!ok2) return UNKNOWN;
242 mymapsface.Bind(S2,fa2);
243 }
244 const TopoDS_Face& ffi2 = fa2.Ffinite();
245 Standard_Boolean finite2 = fa2.Finite();
246
247 // p2d1 :
248 Standard_Real u1,v1; Standard_Boolean ok1 = BRepClass3d_SolidExplorer::FindAPointInTheFace(ffi1,u1,v1);
249 if (!ok1) return UNKNOWN;
250 gp_Pnt2d p2d1(u1,v1);
251
252 // sta12 = status(p2d1 / ffi2) :
253 // recall : ffi1 and ffi2 are built on same face
254 // => ffi1(u1,v1) = ffi2(u1,v1)
255 // ----------------------------
256 Standard_Real tol2d2 = TopOpeBRepTool_TOOL::TolUV(ffi2,BRep_Tool::Tolerance(ffi2));
257 BRepClass_FaceClassifier class2(ffi2,p2d1,tol2d2);
258 TopAbs_State sta12 = class2.State();
259
260 // staffi12 : only if !bnd2dUNK and stabnd2d12!=DIFF
261 // PREQUESITORY : the only possible situations are
262 // - ffi1 IN ffi2
263 // - ffi2 IN ffi1
264 // - ffi1 and ffi2 are distinct
265 Standard_Integer staffi12 = UNKNOWN;
266
267 Standard_Boolean try21 = Standard_False;
268 if (bnd2dUNK) {
269 try21 = Standard_True;
270 }
271 else if (stabnd2d12 == DIFF) {
272 return DIFF;
273 }
274 else {
275 if (sta12 == TopAbs_IN) {// 2 possible states : oneINtwo || twoINone
276 if (stabnd2d12 == oneINtwo) staffi12 = oneINtwo; //Bnd2d(S1) IN Bnd2d(S2)
277 else if (stabnd2d12 == twoINone) staffi12 = twoINone; //Bnd2d(S2) IN Bnd2d(S1)
278 else try21 = Standard_True;
279 }
280 else if (sta12 == TopAbs_OUT) {// 2 possible states : twoINone || DIFF
281 if (stabnd2d12 == twoINone) staffi12 = twoINone;
282 // else if (stabnd2d12 == DIFF) staffi12 = DIFF;
283 else try21 = Standard_True;
284 }
285 else return UNKNOWN; // NYIxpu140199
286 }
287
288 if (try21) {
289 // p2d2 :
290 Standard_Real u2,v2; Standard_Boolean ok2 = BRepClass3d_SolidExplorer::FindAPointInTheFace(ffi2,u2,v2);
291 if (!ok2) return UNKNOWN;
292 gp_Pnt2d p2d2(u2,v2);
293
294 // sta21 :
295 Standard_Real tol2d1 = TopOpeBRepTool_TOOL::TolUV(ffi1,BRep_Tool::Tolerance(ffi1));
296 BRepClass_FaceClassifier class1(ffi1,p2d2,tol2d1);
297 TopAbs_State sta21 = class1.State();
298
299 if (bnd2dUNK) {
300 if (M_OUT(sta12)&& M_OUT(sta21)) staffi12 = DIFF;
301 else if (M_IN(sta12) && M_OUT(sta21)) staffi12 = oneINtwo;
302 else if (M_OUT(sta12)&& M_IN(sta21) ) staffi12 = twoINone;
303 else if (M_IN(sta12) && M_IN(sta21) ) staffi12 = ::FUN_thegreatest(ffi1,class2);
304 }
305 else {
306 if (sta12 == TopAbs_IN) {// 2 possible states : oneINtwo || twoINone
307 if (sta21 == TopAbs_OUT) staffi12 = oneINtwo;
308 }
309 else if (sta12 == TopAbs_OUT) {// 2 possible states : twoINone || DIFF
310 if (sta21 == TopAbs_OUT) staffi12 = DIFF;
311 else if (sta21 == TopAbs_IN) staffi12 = twoINone;
312 }
313 else return UNKNOWN; // NYIxpu140199
314 }
315 }//try21
316
317
318 // classif(S1,S2) knowing staffi12, finite, finite2 :
319 if (staffi12 == DIFF) {
320 if (finite1 && finite2) return DIFF;
321 if (finite1 && !finite2) return twoINone;
322 if (!finite1 && finite2) return oneINtwo;
323 return oneINtwo; // !!!!!!! or twoINone
324 }
325 else if (staffi12 == oneINtwo) {
326 if (!finite1 && !finite2) return twoINone;
327 return oneINtwo;
328 }
329 else if (staffi12 == twoINone) {
330 if (!finite1 && !finite2) return oneINtwo;
331 return twoINone;
332 }
333 return UNKNOWN;
334}
335
336//=======================================================================
337//function : Getface
338//purpose :
339//=======================================================================
340
341Standard_Boolean TopOpeBRepTool_CLASSI::Getface(const TopoDS_Shape& S, TopOpeBRepTool_face& fa) const
342{
343 Standard_Boolean isb = mymapsface.IsBound(S);
344 if (!isb) return Standard_False;
345 fa = mymapsface.Find(S);
346 return Standard_True;
347}
348
349
350//=======================================================================
351//function : Classilist
352//purpose :
353//=======================================================================
354
355Standard_EXPORT void FUN_addOwlw(const TopoDS_Shape& Ow, const TopTools_ListOfShape& lw, TopTools_ListOfShape& lresu)
356{
357 Standard_Integer nw = lw.Extent();
358 if (nw == 0) lresu.Append(Ow);
359 else {
360 TopTools_ListIteratorOfListOfShape it(lw);
361 for (; it.More(); it.Next()) lresu.Append(it.Value());
362 }
363}
364
365Standard_Boolean TopOpeBRepTool_CLASSI::Classilist(const TopTools_ListOfShape& lS, TopTools_DataMapOfShapeListOfShape& mapgreasma)
366{
367 Standard_Real tolref = BRep_Tool::Tolerance(myFref);
368 Standard_Real toluv = TopOpeBRepTool_TOOL::TolUV(myFref,tolref);//nyixpu : cdliser??
369 TopTools_ListOfShape null;
370
371 TopTools_ListOfShape lw; lw.Assign(lS);
372 mapgreasma.Clear();
373 TopTools_ListIteratorOfListOfShape itw(lS);
374 for (; itw.More(); itw.Next()) mapgreasma.Bind(itw.Value(),null);
375
376 Standard_Integer nw = lw.Extent();
377 if (nw <= 1) return Standard_True;
378
379 Standard_Integer nite = 0, nitemax = Standard_Integer(nw*(nw-1)/2);
380 while (nite <= nitemax){
381 nw = lw.Extent();
382 if (nw <= 1) break;
383
384 // wi1 :
385 TopoDS_Shape wi1;
386 TopTools_ListIteratorOfListOfShape itw(lw);
387 for (; itw.More(); itw.Next()){
388 wi1 = itw.Value();
389 Standard_Boolean isb1 = mapgreasma.IsBound(wi1);
390 if (!isb1) continue; // wi1 stored as smaller shape
391 break;
392 }
393
394 while (itw.More()) {// compare wi1 with all wi(k) (k>1)
395 Standard_Boolean isb1 = mapgreasma.IsBound(wi1);
396 if (!isb1) break;
397
398 itw.Next();
399 if (!itw.More()) break;
400
401 // wi2, sta12 :
402 Standard_Integer sta12 = UNKNOWN;
403 Standard_Boolean OUTall = Standard_False;
404 TopoDS_Shape wi2;
405 for (; itw.More(); itw.Next()){
406 wi2 = itw.Value();
407 Standard_Boolean isb2 = mapgreasma.IsBound(wi2);
408 if (!isb2) continue;
409
410 Standard_Integer stabnd2d12 = ClassiBnd2d(wi1,wi2,toluv,Standard_True);
411 sta12 = Classip2d(wi1,wi2, stabnd2d12);
412 if (sta12 == DIFF) {OUTall = Standard_True; continue;}
413 break;
414 }
415
416 // mapgreasma :
417 if (sta12 == oneINtwo) {//greater = shape two
418 TopTools_ListOfShape& lwgre = mapgreasma.ChangeFind(wi2);
419 TopTools_ListOfShape lsma; FUN_addOwlw(wi1,mapgreasma.Find(wi1),lsma);
420 mapgreasma.UnBind(wi1);
421 lwgre.Append(lsma);
422 }
423 else if (sta12 == twoINone) {//greater = shape one
424 TopTools_ListOfShape& lwgre = mapgreasma.ChangeFind(wi1);
425 TopTools_ListOfShape lsma; FUN_addOwlw(wi2,mapgreasma.Find(wi2),lsma);
426 mapgreasma.UnBind(wi2);
427 lwgre.Append(lsma);
428 }
429 else if (OUTall) {
430 // nothing's done
431 }
432 else return Standard_False;
433 }//itw.More()
434
435 lw.RemoveFirst();
436 }//nite<=nmax
437 return Standard_True;
438}
439
440
441
442
443
444