0024157: Parallelization of assembly part of BO
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_WireEdgeClassifier.cxx
CommitLineData
b311480e 1// Created on: 1993-06-17
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1993-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
7fd59977 21
22#include <TopOpeBRepBuild_WireEdgeClassifier.ixx>
23
24#ifdef DRAW
25#include <DBRep.hxx>
26#endif
27
28#include <Precision.hxx>
29#include <TopoDS.hxx>
30#include <TopoDS_Vertex.hxx>
31#include <TopoDS_Edge.hxx>
32#include <TopoDS_Wire.hxx>
33#include <TopoDS_Face.hxx>
34#include <TopExp_Explorer.hxx>
35#include <BRep_Tool.hxx>
36#include <Geom2d_Curve.hxx>
37#include <BRepClass_FaceClassifier.hxx>
38#include <Standard_ProgramError.hxx>
39#include <Geom_Curve.hxx>
40#include <Geom_TrimmedCurve.hxx>
41#include <gp_Pnt.hxx>
42#include <gp_Vec2d.hxx>
43#include <BRep_Builder.hxx>
44#include <TopOpeBRepTool_2d.hxx>
45#include <TopLoc_Location.hxx>
46#include <TopExp.hxx>
47
48#include <TopOpeBRepTool_EXPORT.hxx>
49#include <TopOpeBRepTool_SC.hxx>
50#include <TopOpeBRepTool_TOOL.hxx>
51#include <TopOpeBRepTool_CurveTool.hxx>
52
53#include <TopOpeBRepBuild_Builder.hxx>
54#include <TopOpeBRepBuild_define.hxx>
55
56#ifdef DEB
57#define TSTRA TopOpeBRepDS_GettraceSTRANGE()
58static TCollection_AsciiString PRODINS("dins ");
1d0a9d4d 59extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
7fd59977 60#endif
61
62//Standard_IMPORT extern TopOpeBRepBuild_Builder* GLOBAL_PBUILDER;
63Standard_IMPORT TopOpeBRepBuild_Builder* GLOBAL_PBUILDER;
64#define MYBB ((TopOpeBRepBuild_BlockBuilder*)myBlockBuilder)
65
66
67#define SAME (-1)
68#define DIFF (-2)
69#define UNKNOWN ( 0)
70#define oneINtwo ( 1)
71#define twoINone ( 2)
72
73//=======================================================================
74//function : TopOpeBRepBuild_WireEdgeClassifier
75//purpose :
76//=======================================================================
77
78TopOpeBRepBuild_WireEdgeClassifier::TopOpeBRepBuild_WireEdgeClassifier
79(const TopoDS_Shape& F,
80 const TopOpeBRepBuild_BlockBuilder& BB) :
81TopOpeBRepBuild_CompositeClassifier(BB)
82{
83 myBCEdge.Face() = TopoDS::Face(F);
84}
85
86//=======================================================================
87//function : Compare
88//purpose :
89//=======================================================================
90
91TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::Compare
92(const Handle(TopOpeBRepBuild_Loop)& L1,
93 const Handle(TopOpeBRepBuild_Loop)& L2)
94{
95 TopAbs_State state = TopAbs_UNKNOWN;
96
97 Standard_Boolean isshape1 = L1->IsShape();
98 Standard_Boolean isshape2 = L2->IsShape();
99
100 if ( isshape2 && isshape1 ) { // L1 is Shape , L2 is Shape
101 const TopoDS_Shape& s1 = L1->Shape();
102 const TopoDS_Shape& s2 = L2->Shape();
103 state = CompareShapes(s1,s2);
104 }
105 else if ( isshape2 && !isshape1 ) { // L1 is Block , L2 is Shape
106 TopOpeBRepBuild_BlockIterator Bit1 = L1->BlockIterator();
107 Bit1.Initialize();
108 Standard_Boolean yena1 = Bit1.More();
109 while (yena1) {
110 const TopoDS_Shape& s1 = MYBB->Element(Bit1);
111 const TopoDS_Shape& s2 = L2->Shape();
112 state = CompareElementToShape(s1,s2);
113 yena1 = Standard_False;
114 if (state == TopAbs_UNKNOWN) {
115 if (Bit1.More()) Bit1.Next();
116 yena1 = Bit1.More();
117 }
118 }
119 }
120 else if ( !isshape2 && isshape1 ) { // L1 is Shape , L2 is Block
121 const TopoDS_Shape& s1 = L1->Shape();
122 ResetShape(s1);
123 TopOpeBRepBuild_BlockIterator Bit2 = L2->BlockIterator();
124 for (Bit2.Initialize(); Bit2.More(); Bit2.Next()) {
125 const TopoDS_Shape& s2 = MYBB->Element(Bit2);
126 CompareElement(s2);
127 }
128 state = State();
129 }
130 else if ( !isshape2 && !isshape1 ) { // L1 is Block , L2 is Block
131
132 if (state == TopAbs_UNKNOWN) {
133 TopOpeBRepBuild_BlockIterator Bit1 = L1->BlockIterator();
134 Bit1.Initialize();
135 Standard_Boolean yena1 = Bit1.More();
136 while (yena1) {
137 const TopoDS_Shape& s1 = MYBB->Element(Bit1);
138 ResetElement(s1);
139 TopOpeBRepBuild_BlockIterator Bit2 = L2->BlockIterator();
140 for (Bit2.Initialize(); Bit2.More(); Bit2.Next()) {
141 const TopoDS_Shape& s2 = MYBB->Element(Bit2);
142 CompareElement(s2);
143 }
144 state = State();
145 yena1 = Standard_False;
146 if (state == TopAbs_UNKNOWN) {
147 if (Bit1.More()) Bit1.Next();
148 yena1 = Bit1.More();
149 }
150 }
151 } //UNKNOWN
152
153 if (state == TopAbs_UNKNOWN) {
154#ifdef DEB
155 if (TSTRA) cout<<"TopOpeBRepBuild_Builder::WES::Compare UNKNOWN -> ShapeClassifier "<<endl;
156#endif
157 }
158
159 if (state == TopAbs_UNKNOWN) {
160 TopoDS_Shape s1 = LoopToShape(L1); if (s1.IsNull()) return state;
161 TopoDS_Shape s2 = LoopToShape(L2); if (s2.IsNull()) return state;
162 TopOpeBRepTool_ShapeClassifier& SC = FSC_GetPSC();
163 Standard_Integer samedomain = SC.SameDomain(); SC.SameDomain(1);
164 SC.SetReference(s2);
165 const TopoDS_Shape& AvS = s2;
166 state = SC.StateShapeReference(s1,AvS);
167 SC.SameDomain(samedomain);
168 } // UNKNOWN
169
170 }
171 return state;
172}
173
174//=======================================================================
175//function : LoopToShape
176//purpose :
177//=======================================================================
178
179TopoDS_Shape TopOpeBRepBuild_WireEdgeClassifier::LoopToShape(const Handle(TopOpeBRepBuild_Loop)& L)
180{
181 myShape.Nullify();
182 TopOpeBRepBuild_BlockIterator Bit = L->BlockIterator();
183 Bit.Initialize();
184 if ( !Bit.More() ) return myShape;
185
186 TopoDS_Shape aLocalShape = myBCEdge.Face();
187 const TopoDS_Face& F1 = TopoDS::Face(aLocalShape);
188// const TopoDS_Face& F1 = TopoDS::Face(myBCEdge.Face());
189 aLocalShape = F1.EmptyCopied();
190 TopoDS_Face F = TopoDS::Face(aLocalShape);
191// TopoDS_Face F = TopoDS::Face(F1.EmptyCopied());
192 BRep_Builder BB; TopoDS_Wire W; BB.MakeWire(W);
193 for (; Bit.More(); Bit.Next()) {
194 const TopoDS_Edge& E = TopoDS::Edge(MYBB->Element(Bit));
195 Standard_Real tolE; tolE = BRep_Tool::Tolerance(E);
196 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F);
197 if (!haspc) {
198 Standard_Real f,l,tolpc;Handle(Geom2d_Curve) C2D;
199 C2D = FC2D_CurveOnSurface(E,F,f,l,tolpc);
200 if (!C2D.IsNull()) {
201 Standard_Real tol = Max(tolpc,tolE);
202 BB.UpdateEdge(E,C2D,F,tol);
203 }
204 }
205 BB.Add(W,E);
206 }
207 BB.Add(F,W);
208
209 myShape = F;
210 return myShape;
211}
212
213static gp_Vec FUN_tgINE(const TopoDS_Vertex& v, const TopoDS_Vertex& vl, const TopoDS_Edge& e)
214// tg oriented INSIDE 1d(e)
215// vl : last vertex of e
216{
217 Standard_Real par = BRep_Tool::Parameter(v,e);
218 gp_Vec tg; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(par,e,tg);
219 if (!ok) return gp_Vec(0.,0.,0.); //NYIRAISE
220 if (v.IsSame(vl)) tg.Reverse();
221 return tg;
222}
223
224//=======================================================================
225//function : CompareShapes
226//purpose :
227//=======================================================================
228
229TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::CompareShapes
230(const TopoDS_Shape& B1, const TopoDS_Shape& B2)
231{
232 // evolution xpu101198 : - cto009K4, regularisation de f24,
233 // on classifie 1 wire / 1 des wires connexes.
234 // (face rectangulaire - face circulaire tangente aux bords) -
235 // WEC completement aleatoire : depend du choix de e1 dans le cas
236 // ou e1 est tangent a E. - e1 droite touche l'autre wire -
237 // on fait l'hypothese que les shapes B1 et B2 proviennent du meme shape,
238 // et que si ils ne se touchent pas, on ne passe pas par le WEC.
239 // INCOMPLET!!!
240
241#ifdef DEB
242// TopAbs_ShapeEnum t1 = B1.ShapeType();
243// TopAbs_ShapeEnum t2 = B2.ShapeType();
244#endif
245 TopAbs_State state = TopAbs_UNKNOWN;
246 TopExp_Explorer ex1(B1,TopAbs_EDGE);
247 if ( !ex1.More() ) return state;
248 for ( ; ex1.More(); ex1.Next() ) {
249 const TopoDS_Edge& e1 = TopoDS::Edge(ex1.Current());
250 TopoDS_Vertex vf1,vl1; TopExp::Vertices(e1,vf1,vl1);//xpu101198
251 Standard_Boolean e1clo = vf1.IsSame(vl1);
252 TopTools_IndexedMapOfShape mapv1; mapv1.Add(vf1); mapv1.Add(vl1);
253
254 ResetShape(e1);
255 Standard_Integer iE = 0; Standard_Boolean indy = Standard_False;
256 TopExp_Explorer Ex;
257 for(Ex.Init(B2,TopAbs_EDGE); Ex.More(); Ex.Next()) {
258// for(TopExp_Explorer Ex(B2,TopAbs_EDGE); Ex.More(); Ex.Next()) {
259 const TopoDS_Edge& E = TopoDS::Edge(Ex.Current());
260 if (E.IsSame(e1)) { state = TopAbs_UNKNOWN; break; } // eap occ416
261 TopoDS_Vertex vf,vl; TopExp::Vertices(E,vf,vl);//xpu101198
262 Standard_Boolean Eclo = vf.IsSame(vl);//xpu101198
263 Standard_Boolean hasf = mapv1.Contains(vf);//xpu101198
264 Standard_Boolean hasl = mapv1.Contains(vl);//xpu101198
265 Standard_Boolean filter = (hasf || hasl) && (!e1clo) && (!Eclo);// nyi : Eclo || e1clo
266 if (filter) {//xpu101198
267 TopoDS_Vertex vshared; if (hasf) vshared=vf; if (hasl) vshared=vl;
268 gp_Vec tg1 = FUN_tgINE(vshared,vl1,e1);
269 gp_Vec tg = FUN_tgINE(vshared,vl,E);
270 Standard_Real dot = tg1.Dot(tg);
271 Standard_Real tol = Precision::Angular()*1.e4; // nyixpu
272 Standard_Boolean undecided = (Abs(1+dot) < tol);
273 if (undecided) {indy = Standard_True;}
274 }//xpu101198
275 if (indy) {state = TopAbs_UNKNOWN; break;}
276 CompareElement(E);
277 state = State();
278 iE++;
279 } // ex(B2,EDGE)
280 if (state != TopAbs_UNKNOWN) {
281 break;
282 }
283 }// ex1
284
285 Standard_Boolean resta = (state == TopAbs_UNKNOWN);
286 resta = resta && (B2.ShapeType()==TopAbs_WIRE) && (B1.ShapeType()==TopAbs_WIRE);
287 if (resta) {
288 TopTools_IndexedMapOfShape mape1; TopExp::MapShapes(B1,TopAbs_EDGE,mape1);
289 // recall : avoid auto-intersection wires (ie B1 and B2 are disjoint)
290 TopExp_Explorer ex2(B2,TopAbs_EDGE);
291 for (; ex2.More(); ex2.Next()){
292 const TopoDS_Edge& E2 = TopoDS::Edge(ex2.Current());
293 if (mape1.Contains(E2)) continue;
294
295 const TopoDS_Face& theFace = myBCEdge.Face();
296 BRep_Builder BB;
297
298 // p2d on E2 of B2, E2 not shared by B1
299 TopoDS_Shape aLocalShape = theFace.Oriented(TopAbs_FORWARD);
300 TopoDS_Face ftmp = TopoDS::Face(aLocalShape);
301// TopoDS_Face ftmp = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD));
302 aLocalShape = ftmp.EmptyCopied();
303 TopoDS_Face F2 = TopoDS::Face(aLocalShape);
304// TopoDS_Face F2 = TopoDS::Face(ftmp.EmptyCopied());
305 BB.Add(F2,TopoDS::Wire(B2));
306
307 BRepAdaptor_Curve2d BC2d(E2,F2);
308 Standard_Real f,l; FUN_tool_bounds(E2,f,l); Standard_Real x = 0.45678; Standard_Real p2 = (1-x)*l + x*f;
309 gp_Pnt2d p2d = BC2d.Value(p2);
310
311 aLocalShape = ftmp.EmptyCopied();
312 TopoDS_Face F1 = TopoDS::Face(aLocalShape);
313// TopoDS_Face F1 = TopoDS::Face(ftmp.EmptyCopied());
314 BB.Add(F1,TopoDS::Wire(B1));
315
316 Standard_Real tolF1 = BRep_Tool::Tolerance(F1);
317 BRepClass_FaceClassifier Fclass(F1, p2d, tolF1);
318 state = Fclass.State();
319 return state;
320 } // ex2
321 }
322
323 /*if (state == TopAbs_UNKNOWN) {
324 const TopoDS_Face& F = TopoDS::Face(myBCEdge.Face());
325 Bnd_Array1OfBox2d bnd(1,2);
326 FUN_tool_mkBnd2d(B1,F,bnd(1)); FUN_tool_mkBnd2d(B2,F,bnd(2));
327 TopTools_Array1OfShape B(1,2);
328 B(1)=B1; B(2)=B2;
329// Standard_Boolean chklarge=Standard_True; Standard_Integer isma = 0; TopAbs_State osta = FUN_tool_classiBnd2d(bnd,isma,chklarge);
330// if (osta == TopAbs_OUT) return TopAbs_OUT;
331// if (osta == TopAbs_IN) {
332// if (isma == 2) return TopAbs_IN; //B2 is IN B1
333// else return TopAbs_OUT; //B2 is OUT B1 (contains B1)
334// }
335 Standard_Boolean chklarge=Standard_True; Standard_Integer sta = FUN_tool_classiBnd2d(bnd,chklarge);
336 if ((sta == SAME)||(sta == UNKNOWN)) sta = FUN_tool_classiwithp2d(B);
337 if ((sta == SAME)||(sta == UNKNOWN)) return TopAbs_UNKNOWN;
338 if (sta == DIFF) return TopAbs_OUT; // B1 OUT B2
339 Standard_Integer isma = (sta == oneINtwo) ? 1 : 2;
340 if (isma == 2) return TopAbs_IN; //B2 is IN B1
341 else return TopAbs_OUT; //B2 is OUT B1 (contains B1)
342 }*/
343 return state;
344}
345
346
347//=======================================================================
348//function : CompareElementToShape
349//purpose :
350//=======================================================================
351
352TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::CompareElementToShape
353(const TopoDS_Shape& EE,const TopoDS_Shape& B)
354{
355 // isEdge : edge E inits myPoint2d
356 ResetElement(EE);
357 TopExp_Explorer Ex;
358 for(Ex.Init(B,TopAbs_EDGE); Ex.More(); Ex.Next()) {
359 const TopoDS_Shape& E = Ex.Current();
360 CompareElement(E);
361 }
362 TopAbs_State state = State();
363 return state;
364}
365
366
367//=======================================================================
368//function : ResetShape
369//purpose :
370//=======================================================================
371
372void TopOpeBRepBuild_WireEdgeClassifier::ResetShape(const TopoDS_Shape& B)
373{
374 if (B.ShapeType() == TopAbs_EDGE) {
375 ResetElement(B);
376 }
377 else {
378 TopExp_Explorer ex(B,TopAbs_EDGE);
379 if (ex.More()) {
380 const TopoDS_Shape& E = ex.Current();
381 ResetElement(E);
382 }
383 }
384}
385
386//=======================================================================
387//function : ResetElement
388//purpose :
389//=======================================================================
390
391void TopOpeBRepBuild_WireEdgeClassifier::ResetElement(const TopoDS_Shape& EE)
392{
393 const TopoDS_Edge& E = TopoDS::Edge(EE);
394 const TopoDS_Face& F = myBCEdge.Face();
395 Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980406+
396 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980406+
397 if (!haspc) { //jyl980406+
398 Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
399 Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980406+
400 Standard_Real tol = Max(tolE,tolpc); //jyl980406+
401 BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980406+
402 } //jyl980406+
403
404 C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
405 if (C2D.IsNull()) Standard_ProgramError::Raise("WEC : ResetElement");
406
407 Standard_Real t = 0.397891143689; Standard_Real par = ((1-t)*f2 + t*l2);
408 myPoint2d = C2D->Value(par);
409
410#ifdef DEB
411 Standard_Real f3,l3; Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f3,l3);
412 gp_Pnt P3D; if (!C3D.IsNull()) P3D = C3D->Value(par);
413#endif
414
415 myFirstCompare = Standard_True;
416}
417
418
419//=======================================================================
420//function : CompareElement
421//purpose :
422//=======================================================================
423
73a97e76 424Standard_Boolean TopOpeBRepBuild_WireEdgeClassifier::CompareElement(const TopoDS_Shape& EE)
7fd59977 425{
73a97e76 426 Standard_Boolean bRet = Standard_True;
7fd59977 427 const TopoDS_Edge& E = TopoDS::Edge(EE);
428 const TopoDS_Face& F = myBCEdge.Face();
429
430 Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980402+
431 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980402+
432 if (!haspc) { //jyl980402+
433 Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
434 // C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406-
435 Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980402+
436 Standard_Real tol = Max(tolE,tolpc); //jyl980402+
437 BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980402+
438 } //jyl980402+
439
440 if (myFirstCompare) {
441 C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
442 Standard_Real t = 0.33334567; Standard_Real par = ((1-t)*f2 + t*l2);
443 gp_Pnt2d p2d = C2D->Value(par);
444
445#ifdef DEB
446 Standard_Real f3,l3; Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f3,l3);
447 gp_Pnt P3D; if (!C3D.IsNull()) P3D = C3D->Value(par);
448#endif
449
450 // NYI : p2d peut etre un point ou la courbe n'est pas C1.
451 // NYI : voir TopOpeBRepTool_ShapeClassifier_FindAPointInTheFace
452 gp_Vec2d v2d(myPoint2d,p2d);
453 gp_Lin2d l2d(myPoint2d,v2d);
454 Standard_Real dist = myPoint2d.Distance(p2d);
455 Standard_Real tol2d = Precision::PConfusion(); // NYI : a voir
456 myFPC.Reset(l2d,dist,tol2d);
457 myFirstCompare = Standard_False;
458 }
459
460 myBCEdge.Edge() = E;
461 TopAbs_Orientation Eori = E.Orientation();
462 myFPC.Compare(myBCEdge,Eori);
463#ifdef DEB
464// TopAbs_State state = myFPC.State();
465#endif
73a97e76 466 return bRet;
7fd59977 467}
468
469
470//=======================================================================
471//function : State
472//purpose :
473//=======================================================================
474
475TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::State()
476{
477 TopAbs_State state = myFPC.State();
478 return state;
479}