1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <TopoDS_Shape.hxx>
19 #include <TopOpeBRepBuild_BlockBuilder.hxx>
20 #include <TopOpeBRepBuild_Loop.hxx>
21 #include <TopOpeBRepBuild_WireEdgeClassifier.hxx>
27 #include <Precision.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Wire.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <BRep_Tool.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <BRepClass_FaceClassifier.hxx>
37 #include <Standard_ProgramError.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_TrimmedCurve.hxx>
41 #include <gp_Vec2d.hxx>
42 #include <BRep_Builder.hxx>
43 #include <TopOpeBRepTool_2d.hxx>
44 #include <TopLoc_Location.hxx>
47 #include <TopOpeBRepTool_EXPORT.hxx>
48 #include <TopOpeBRepTool_SC.hxx>
49 #include <TopOpeBRepTool_TOOL.hxx>
50 #include <TopOpeBRepTool_CurveTool.hxx>
52 #include <TopOpeBRepBuild_Builder.hxx>
53 #include <TopOpeBRepBuild_define.hxx>
56 static TCollection_AsciiString PRODINS("dins ");
59 //Standard_IMPORT extern TopOpeBRepBuild_Builder* GLOBAL_PBUILDER;
60 Standard_IMPORT TopOpeBRepBuild_Builder* GLOBAL_PBUILDER;
61 #define MYBB ((TopOpeBRepBuild_BlockBuilder*)myBlockBuilder)
70 //=======================================================================
71 //function : TopOpeBRepBuild_WireEdgeClassifier
73 //=======================================================================
75 TopOpeBRepBuild_WireEdgeClassifier::TopOpeBRepBuild_WireEdgeClassifier
76 (const TopoDS_Shape& F,
77 const TopOpeBRepBuild_BlockBuilder& BB) :
78 TopOpeBRepBuild_CompositeClassifier(BB)
80 myBCEdge.Face() = TopoDS::Face(F);
83 //=======================================================================
86 //=======================================================================
88 TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::Compare
89 (const Handle(TopOpeBRepBuild_Loop)& L1,
90 const Handle(TopOpeBRepBuild_Loop)& L2)
92 TopAbs_State state = TopAbs_UNKNOWN;
94 Standard_Boolean isshape1 = L1->IsShape();
95 Standard_Boolean isshape2 = L2->IsShape();
97 if ( isshape2 && isshape1 ) { // L1 is Shape , L2 is Shape
98 const TopoDS_Shape& s1 = L1->Shape();
99 const TopoDS_Shape& s2 = L2->Shape();
100 state = CompareShapes(s1,s2);
102 else if ( isshape2 && !isshape1 ) { // L1 is Block , L2 is Shape
103 TopOpeBRepBuild_BlockIterator Bit1 = L1->BlockIterator();
105 Standard_Boolean yena1 = Bit1.More();
107 const TopoDS_Shape& s1 = MYBB->Element(Bit1);
108 const TopoDS_Shape& s2 = L2->Shape();
109 state = CompareElementToShape(s1,s2);
110 yena1 = Standard_False;
111 if (state == TopAbs_UNKNOWN) {
112 if (Bit1.More()) Bit1.Next();
117 else if ( !isshape2 && isshape1 ) { // L1 is Shape , L2 is Block
118 const TopoDS_Shape& s1 = L1->Shape();
120 TopOpeBRepBuild_BlockIterator Bit2 = L2->BlockIterator();
121 for (Bit2.Initialize(); Bit2.More(); Bit2.Next()) {
122 const TopoDS_Shape& s2 = MYBB->Element(Bit2);
127 else if ( !isshape2 && !isshape1 ) { // L1 is Block , L2 is Block
129 if (state == TopAbs_UNKNOWN) {
130 TopOpeBRepBuild_BlockIterator Bit1 = L1->BlockIterator();
132 Standard_Boolean yena1 = Bit1.More();
134 const TopoDS_Shape& s1 = MYBB->Element(Bit1);
136 TopOpeBRepBuild_BlockIterator Bit2 = L2->BlockIterator();
137 for (Bit2.Initialize(); Bit2.More(); Bit2.Next()) {
138 const TopoDS_Shape& s2 = MYBB->Element(Bit2);
142 yena1 = Standard_False;
143 if (state == TopAbs_UNKNOWN) {
144 if (Bit1.More()) Bit1.Next();
150 if (state == TopAbs_UNKNOWN) {
151 TopoDS_Shape s1 = LoopToShape(L1); if (s1.IsNull()) return state;
152 TopoDS_Shape s2 = LoopToShape(L2); if (s2.IsNull()) return state;
153 TopOpeBRepTool_ShapeClassifier& SC = FSC_GetPSC();
154 Standard_Integer samedomain = SC.SameDomain(); SC.SameDomain(1);
156 const TopoDS_Shape& AvS = s2;
157 state = SC.StateShapeReference(s1,AvS);
158 SC.SameDomain(samedomain);
165 //=======================================================================
166 //function : LoopToShape
168 //=======================================================================
170 TopoDS_Shape TopOpeBRepBuild_WireEdgeClassifier::LoopToShape(const Handle(TopOpeBRepBuild_Loop)& L)
173 TopOpeBRepBuild_BlockIterator Bit = L->BlockIterator();
175 if ( !Bit.More() ) return myShape;
177 TopoDS_Shape aLocalShape = myBCEdge.Face();
178 const TopoDS_Face& F1 = TopoDS::Face(aLocalShape);
179 // const TopoDS_Face& F1 = TopoDS::Face(myBCEdge.Face());
180 aLocalShape = F1.EmptyCopied();
181 TopoDS_Face F = TopoDS::Face(aLocalShape);
182 // TopoDS_Face F = TopoDS::Face(F1.EmptyCopied());
183 BRep_Builder BB; TopoDS_Wire W; BB.MakeWire(W);
184 for (; Bit.More(); Bit.Next()) {
185 const TopoDS_Edge& E = TopoDS::Edge(MYBB->Element(Bit));
186 Standard_Real tolE; tolE = BRep_Tool::Tolerance(E);
187 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F);
189 Standard_Real f,l,tolpc;Handle(Geom2d_Curve) C2D;
190 C2D = FC2D_CurveOnSurface(E,F,f,l,tolpc);
192 Standard_Real tol = Max(tolpc,tolE);
193 BB.UpdateEdge(E,C2D,F,tol);
204 static gp_Vec FUN_tgINE(const TopoDS_Vertex& v, const TopoDS_Vertex& vl, const TopoDS_Edge& e)
205 // tg oriented INSIDE 1d(e)
206 // vl : last vertex of e
208 Standard_Real par = BRep_Tool::Parameter(v,e);
209 gp_Vec tg; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(par,e,tg);
210 if (!ok) return gp_Vec(0.,0.,0.); //NYIRAISE
211 if (v.IsSame(vl)) tg.Reverse();
215 //=======================================================================
216 //function : CompareShapes
218 //=======================================================================
220 TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::CompareShapes
221 (const TopoDS_Shape& B1, const TopoDS_Shape& B2)
223 // evolution xpu101198 : - cto009K4, regularisation de f24,
224 // on classifie 1 wire / 1 des wires connexes.
225 // (face rectangulaire - face circulaire tangente aux bords) -
226 // WEC completement aleatoire : depend du choix de e1 dans le cas
227 // ou e1 est tangent a E. - e1 droite touche l'autre wire -
228 // on fait l'hypothese que les shapes B1 et B2 proviennent du meme shape,
229 // et que si ils ne se touchent pas, on ne passe pas par le WEC.
233 // TopAbs_ShapeEnum t1 = B1.ShapeType();
234 // TopAbs_ShapeEnum t2 = B2.ShapeType();
236 TopAbs_State state = TopAbs_UNKNOWN;
237 TopExp_Explorer ex1(B1,TopAbs_EDGE);
238 if ( !ex1.More() ) return state;
239 for ( ; ex1.More(); ex1.Next() ) {
240 const TopoDS_Edge& e1 = TopoDS::Edge(ex1.Current());
241 TopoDS_Vertex vf1,vl1; TopExp::Vertices(e1,vf1,vl1);//xpu101198
242 Standard_Boolean e1clo = vf1.IsSame(vl1);
243 TopTools_IndexedMapOfShape mapv1; mapv1.Add(vf1); mapv1.Add(vl1);
246 Standard_Integer iE = 0; Standard_Boolean indy = Standard_False;
248 for(Ex.Init(B2,TopAbs_EDGE); Ex.More(); Ex.Next()) {
249 // for(TopExp_Explorer Ex(B2,TopAbs_EDGE); Ex.More(); Ex.Next()) {
250 const TopoDS_Edge& E = TopoDS::Edge(Ex.Current());
251 if (E.IsSame(e1)) { state = TopAbs_UNKNOWN; break; } // eap occ416
252 TopoDS_Vertex vf,vl; TopExp::Vertices(E,vf,vl);//xpu101198
253 Standard_Boolean Eclo = vf.IsSame(vl);//xpu101198
254 Standard_Boolean hasf = mapv1.Contains(vf);//xpu101198
255 Standard_Boolean hasl = mapv1.Contains(vl);//xpu101198
256 Standard_Boolean filter = (hasf || hasl) && (!e1clo) && (!Eclo);// nyi : Eclo || e1clo
257 if (filter) {//xpu101198
258 TopoDS_Vertex vshared; if (hasf) vshared=vf; if (hasl) vshared=vl;
259 gp_Vec tg1 = FUN_tgINE(vshared,vl1,e1);
260 gp_Vec tg = FUN_tgINE(vshared,vl,E);
261 Standard_Real dot = tg1.Dot(tg);
262 Standard_Real tol = Precision::Angular()*1.e4; // nyixpu
263 Standard_Boolean undecided = (Abs(1+dot) < tol);
264 if (undecided) {indy = Standard_True;}
266 if (indy) {state = TopAbs_UNKNOWN; break;}
271 if (state != TopAbs_UNKNOWN) {
276 Standard_Boolean resta = (state == TopAbs_UNKNOWN);
277 resta = resta && (B2.ShapeType()==TopAbs_WIRE) && (B1.ShapeType()==TopAbs_WIRE);
279 TopTools_IndexedMapOfShape mape1; TopExp::MapShapes(B1,TopAbs_EDGE,mape1);
280 // recall : avoid auto-intersection wires (ie B1 and B2 are disjoint)
281 TopExp_Explorer ex2(B2,TopAbs_EDGE);
282 for (; ex2.More(); ex2.Next()){
283 const TopoDS_Edge& E2 = TopoDS::Edge(ex2.Current());
284 if (mape1.Contains(E2)) continue;
286 const TopoDS_Face& theFace = myBCEdge.Face();
289 // p2d on E2 of B2, E2 not shared by B1
290 TopoDS_Shape aLocalShape = theFace.Oriented(TopAbs_FORWARD);
291 TopoDS_Face ftmp = TopoDS::Face(aLocalShape);
292 // TopoDS_Face ftmp = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD));
293 aLocalShape = ftmp.EmptyCopied();
294 TopoDS_Face F2 = TopoDS::Face(aLocalShape);
295 // TopoDS_Face F2 = TopoDS::Face(ftmp.EmptyCopied());
296 BB.Add(F2,TopoDS::Wire(B2));
298 BRepAdaptor_Curve2d BC2d(E2,F2);
299 Standard_Real f,l; FUN_tool_bounds(E2,f,l); Standard_Real x = 0.45678; Standard_Real p2 = (1-x)*l + x*f;
300 gp_Pnt2d p2d = BC2d.Value(p2);
302 aLocalShape = ftmp.EmptyCopied();
303 TopoDS_Face F1 = TopoDS::Face(aLocalShape);
304 // TopoDS_Face F1 = TopoDS::Face(ftmp.EmptyCopied());
305 BB.Add(F1,TopoDS::Wire(B1));
307 Standard_Real tolF1 = BRep_Tool::Tolerance(F1);
308 BRepClass_FaceClassifier Fclass(F1, p2d, tolF1);
309 state = Fclass.State();
314 /*if (state == TopAbs_UNKNOWN) {
315 const TopoDS_Face& F = TopoDS::Face(myBCEdge.Face());
316 Bnd_Array1OfBox2d bnd(1,2);
317 FUN_tool_mkBnd2d(B1,F,bnd(1)); FUN_tool_mkBnd2d(B2,F,bnd(2));
318 TopTools_Array1OfShape B(1,2);
320 // Standard_Boolean chklarge=Standard_True; Standard_Integer isma = 0; TopAbs_State osta = FUN_tool_classiBnd2d(bnd,isma,chklarge);
321 // if (osta == TopAbs_OUT) return TopAbs_OUT;
322 // if (osta == TopAbs_IN) {
323 // if (isma == 2) return TopAbs_IN; //B2 is IN B1
324 // else return TopAbs_OUT; //B2 is OUT B1 (contains B1)
326 Standard_Boolean chklarge=Standard_True; Standard_Integer sta = FUN_tool_classiBnd2d(bnd,chklarge);
327 if ((sta == SAME)||(sta == UNKNOWN)) sta = FUN_tool_classiwithp2d(B);
328 if ((sta == SAME)||(sta == UNKNOWN)) return TopAbs_UNKNOWN;
329 if (sta == DIFF) return TopAbs_OUT; // B1 OUT B2
330 Standard_Integer isma = (sta == oneINtwo) ? 1 : 2;
331 if (isma == 2) return TopAbs_IN; //B2 is IN B1
332 else return TopAbs_OUT; //B2 is OUT B1 (contains B1)
338 //=======================================================================
339 //function : CompareElementToShape
341 //=======================================================================
343 TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::CompareElementToShape
344 (const TopoDS_Shape& EE,const TopoDS_Shape& B)
346 // isEdge : edge E inits myPoint2d
349 for(Ex.Init(B,TopAbs_EDGE); Ex.More(); Ex.Next()) {
350 const TopoDS_Shape& E = Ex.Current();
353 TopAbs_State state = State();
358 //=======================================================================
359 //function : ResetShape
361 //=======================================================================
363 void TopOpeBRepBuild_WireEdgeClassifier::ResetShape(const TopoDS_Shape& B)
365 if (B.ShapeType() == TopAbs_EDGE) {
369 TopExp_Explorer ex(B,TopAbs_EDGE);
371 const TopoDS_Shape& E = ex.Current();
377 //=======================================================================
378 //function : ResetElement
380 //=======================================================================
382 void TopOpeBRepBuild_WireEdgeClassifier::ResetElement(const TopoDS_Shape& EE)
384 const TopoDS_Edge& E = TopoDS::Edge(EE);
385 const TopoDS_Face& F = myBCEdge.Face();
386 Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980406+
387 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980406+
388 if (!haspc) { //jyl980406+
389 Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
390 Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980406+
391 Standard_Real tol = Max(tolE,tolpc); //jyl980406+
392 BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980406+
395 C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
396 if (C2D.IsNull()) Standard_ProgramError::Raise("WEC : ResetElement");
398 Standard_Real t = 0.397891143689; Standard_Real par = ((1-t)*f2 + t*l2);
399 myPoint2d = C2D->Value(par);
402 Standard_Real f3,l3; Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f3,l3);
403 gp_Pnt P3D; if (!C3D.IsNull()) P3D = C3D->Value(par);
406 myFirstCompare = Standard_True;
410 //=======================================================================
411 //function : CompareElement
413 //=======================================================================
415 Standard_Boolean TopOpeBRepBuild_WireEdgeClassifier::CompareElement(const TopoDS_Shape& EE)
417 Standard_Boolean bRet = Standard_True;
418 const TopoDS_Edge& E = TopoDS::Edge(EE);
419 const TopoDS_Face& F = myBCEdge.Face();
421 Standard_Real f2,l2,tolpc;Handle(Geom2d_Curve) C2D; //jyl980402+
422 Standard_Boolean haspc = FC2D_HasCurveOnSurface(E,F); //jyl980402+
423 if (!haspc) { //jyl980402+
424 Standard_Boolean trim3d = Standard_True; C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406+
425 // C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc,trim3d); //jyl980406-
426 Standard_Real tolE = BRep_Tool::Tolerance(E); //jyl980402+
427 Standard_Real tol = Max(tolE,tolpc); //jyl980402+
428 BRep_Builder BB; BB.UpdateEdge(E,C2D,F,tol); //jyl980402+
431 if (myFirstCompare) {
432 C2D = FC2D_CurveOnSurface(E,F,f2,l2,tolpc);
433 Standard_Real t = 0.33334567; Standard_Real par = ((1-t)*f2 + t*l2);
434 gp_Pnt2d p2d = C2D->Value(par);
437 Standard_Real f3,l3; Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f3,l3);
438 gp_Pnt P3D; if (!C3D.IsNull()) P3D = C3D->Value(par);
441 // NYI : p2d peut etre un point ou la courbe n'est pas C1.
442 // NYI : voir TopOpeBRepTool_ShapeClassifier_FindAPointInTheFace
443 gp_Vec2d v2d(myPoint2d,p2d);
444 gp_Lin2d l2d(myPoint2d,v2d);
445 Standard_Real dist = myPoint2d.Distance(p2d);
446 Standard_Real tol2d = Precision::PConfusion(); // NYI : a voir
447 myFPC.Reset(l2d,dist,tol2d);
448 myFirstCompare = Standard_False;
452 TopAbs_Orientation Eori = E.Orientation();
453 myFPC.Compare(myBCEdge,Eori);
455 // TopAbs_State state = myFPC.State();
461 //=======================================================================
464 //=======================================================================
466 TopAbs_State TopOpeBRepBuild_WireEdgeClassifier::State()
468 TopAbs_State state = myFPC.State();