0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepCheck / BRepCheck_Face.cxx
CommitLineData
b311480e 1// Created on: 1995-12-15
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-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
7fd59977 17
42cf5bc1 18#include <Bnd_Box2d.hxx>
19#include <BndLib_Add2dCurve.hxx>
7fd59977 20#include <BRep_Builder.hxx>
42cf5bc1 21#include <BRep_TFace.hxx>
7fd59977 22#include <BRep_Tool.hxx>
42cf5bc1 23#include <BRepAdaptor_HSurface.hxx>
24#include <BRepCheck.hxx>
25#include <BRepCheck_Face.hxx>
26#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
27#include <BRepCheck_ListOfStatus.hxx>
7fd59977 28#include <BRepClass_FaceClassifier.hxx>
42cf5bc1 29#include <BRepTopAdaptor_FClass2d.hxx>
7fd59977 30#include <Geom2d_Curve.hxx>
42cf5bc1 31#include <Geom2dAdaptor_Curve.hxx>
32#include <Geom2dInt_GInter.hxx>
b3cb7aa2 33#include <Geom_Curve.hxx>
42cf5bc1 34#include <gp_Pnt2d.hxx>
7fd59977 35#include <GProp_GProps.hxx>
7fd59977 36#include <IntRes2d_Domain.hxx>
42cf5bc1 37#include <IntRes2d_IntersectionPoint.hxx>
38#include <IntRes2d_IntersectionSegment.hxx>
39#include <NCollection_DataMap.hxx>
7fd59977 40#include <Precision.hxx>
42cf5bc1 41#include <Standard_Type.hxx>
42#include <TColgp_SequenceOfPnt.hxx>
43#include <TopAbs_State.hxx>
44#include <TopExp.hxx>
45#include <TopExp_Explorer.hxx>
7fd59977 46#include <TopoDS.hxx>
42cf5bc1 47#include <TopoDS_Face.hxx>
48#include <TopoDS_Shape.hxx>
49#include <TopoDS_Vertex.hxx>
7fd59977 50#include <TopoDS_Wire.hxx>
42cf5bc1 51#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52#include <TopTools_DataMapOfShapeListOfShape.hxx>
53#include <TopTools_ListIteratorOfListOfShape.hxx>
54#include <TopTools_ListOfShape.hxx>
7fd59977 55#include <TopTools_MapOfShape.hxx>
7c8090aa 56#include <TopTools_OrientedShapeMapHasher.hxx>
42cf5bc1 57#include <TopTools_SequenceOfShape.hxx>
7c8090aa 58
42cf5bc1 59//#include <BRepAdaptor_Curve2d.hxx>
60//#include <Geom2dInt_GInter.hxx>
7c8090aa 61typedef NCollection_DataMap<TopoDS_Shape, Bnd_Box2d, TopTools_OrientedShapeMapHasher> DataMapOfShapeBox2d;
7fd59977 62
63static Standard_Boolean Intersect(const TopoDS_Wire&,
64 const TopoDS_Wire&,
7c8090aa 65 const TopoDS_Face&,
66 const DataMapOfShapeBox2d&);
7fd59977 67
68
69static Standard_Boolean IsInside(const TopoDS_Wire& wir,
70 const Standard_Boolean Inside,
71 const BRepTopAdaptor_FClass2d& FClass2d,
72 const TopoDS_Face& F);
73
74static Standard_Boolean CheckThin(const TopoDS_Shape& w,
75 const TopoDS_Shape& f);
76
77//=======================================================================
78//function : BRepCheck_Face
79//purpose :
80//=======================================================================
81
82BRepCheck_Face::BRepCheck_Face (const TopoDS_Face& F)
83{
84 Init(F);
85 myIntdone = Standard_False;
86 myImbdone = Standard_False;
87 myOridone = Standard_False;
88 myGctrl = Standard_True;
89}
90
91//=======================================================================
92//function : Minimum
93//purpose :
94//=======================================================================
95
96void BRepCheck_Face::Minimum()
97{
98 if (!myMin) {
99 BRepCheck_ListOfStatus thelist;
100 myMap.Bind(myShape, thelist);
101 BRepCheck_ListOfStatus& lst = myMap(myShape);
102
103 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &myShape.TShape());
104 if (TF->Surface().IsNull()) {
105 BRepCheck::Add(lst,BRepCheck_NoSurface);
106 }
107 else {
108 // Flag natural restriction???
109 }
110 if (lst.IsEmpty()) {
111 lst.Append(BRepCheck_NoError);
112 }
113 myMin = Standard_True;
114 }
115}
116
117
118//=======================================================================
119//function : InContext
120//purpose :
121//=======================================================================
122
123void BRepCheck_Face::InContext(const TopoDS_Shape& S)
124{
125 if (myMap.IsBound(S)) {
126 return;
127 }
128 BRepCheck_ListOfStatus thelist;
129 myMap.Bind(S, thelist);
130
131 BRepCheck_ListOfStatus& lst = myMap(S);
132
133 TopExp_Explorer exp(S,TopAbs_FACE);
134 for (; exp.More(); exp.Next()) {
135 if (exp.Current().IsSame(myShape)) {
136 break;
137 }
138 }
139 if (!exp.More()) {
140 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
141 return;
142 }
143
144 if (lst.IsEmpty()) {
145 lst.Append(BRepCheck_NoError);
146 }
147}
148
149
150//=======================================================================
151//function : Blind
152//purpose :
153//=======================================================================
154
155void BRepCheck_Face::Blind()
156{
157 if (!myBlind) {
0d969553 158 // nothing more than in the minimum
7fd59977 159 myBlind = Standard_True;
160 }
161}
162
163
164//=======================================================================
165//function : IntersectWires
166//purpose :
167//=======================================================================
168
169BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
170{
171 if (myIntdone) {
172 if (Update) {
173 BRepCheck::Add(myMap(myShape),myIntres);
174 }
175 return myIntres;
176 }
177
178 myIntdone = Standard_True;
179 myIntres = BRepCheck_NoError;
180 // This method has to be called by an analyzer. It is assumed that
181 // each edge has a correct 2d representation on the face.
182
183 TopExp_Explorer exp1,exp2;
184
0d969553 185 // the wires are mapped
7fd59977 186 exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
187 TopTools_ListOfShape theListOfShape;
188 while (exp1.More()) {
189 if (!myMapImb.IsBound(exp1.Current())) {
190 myMapImb.Bind(exp1.Current(), theListOfShape);
191 }
0d969553 192 else { // the same wire is met twice...
7fd59977 193 myIntres = BRepCheck_RedundantWire;
194 if (Update) {
195 BRepCheck::Add(myMap(myShape),myIntres);
196 }
197 return myIntres;
198 }
199 exp1.Next();
200 }
7c8090aa 201
202 Geom2dAdaptor_Curve aC;
203 Standard_Real aFirst, aLast;
204 DataMapOfShapeBox2d aMapShapeBox2d;
205 for (exp1.Init (myShape, TopAbs_WIRE); exp1.More(); exp1.Next())
206 {
207 const TopoDS_Wire& aWire = TopoDS::Wire (exp1.Current());
208 // create 2d boxes for all edges from wire
209 Bnd_Box2d aBoxW;
210 for (exp2.Init (aWire, TopAbs_EDGE); exp2.More(); exp2.Next())
211 {
212 const TopoDS_Edge& anEdge = TopoDS::Edge (exp2.Current());
213 aC.Load (BRep_Tool::CurveOnSurface (anEdge, TopoDS::Face (myShape), aFirst, aLast));
214 // To avoid exeption in Segment if C1 is BSpline
215 if (aC.FirstParameter() > aFirst)
216 {
217 aFirst = aC.FirstParameter();
218 }
219 if (aC.LastParameter() < aLast)
220 {
221 aLast = aC.LastParameter();
222 }
223 Bnd_Box2d aBoxE;
224 BndLib_Add2dCurve::Add (aC, aFirst, aLast, 0., aBoxE);
225 aMapShapeBox2d.Bind (anEdge, aBoxE);
226 aBoxW.Add (aBoxE);
227 }
228 aMapShapeBox2d.Bind (aWire, aBoxW);
229 }
230
7fd59977 231 Standard_Integer Nbwire, Index,Indexbis;
232 Nbwire = myMapImb.Extent();
233
234 Index = 1;
235 while (Index < Nbwire) {
236 for (exp1.Init(myShape,TopAbs_WIRE),Indexbis = 0;
237 exp1.More();exp1.Next()) {
238 Indexbis++;
239 if (Indexbis == Index) {
240 break;
241 }
242 }
243 TopoDS_Wire wir1 = TopoDS::Wire(exp1.Current());
7c8090aa 244 // to reduce the number of calls Intersect(wir1,wir2)
245 Bnd_Box2d aBox1, aBox2;
246 if (aMapShapeBox2d.IsBound (wir1))
247 {
248 aBox1 = aMapShapeBox2d (wir1);
249 }
7fd59977 250 exp1.Next();
251 for (; exp1.More(); exp1.Next()) {
252 const TopoDS_Wire& wir2 = TopoDS::Wire(exp1.Current());
7c8090aa 253 if (aMapShapeBox2d.IsBound (wir2))
254 {
255 aBox2 = aMapShapeBox2d (wir2);
256 }
257 if (!aBox1.IsVoid() && !aBox2.IsVoid() && aBox1.IsOut (aBox2))
258 {
259 continue;
260 }
261 if (Intersect(wir1,wir2,TopoDS::Face(myShape), aMapShapeBox2d)) {
7fd59977 262 myIntres = BRepCheck_IntersectingWires;
263 if (Update) {
264 BRepCheck::Add(myMap(myShape),myIntres);
265 }
266 return myIntres;
267 }
268 }
269 Index++;
270 }
271 if (Update) {
272 BRepCheck::Add(myMap(myShape),myIntres);
273 }
274 return myIntres;
275}
276
277
278//=======================================================================
279//function : ClassifyWires
280//purpose :
281//=======================================================================
282
283BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
284{
285 // It is assumed that each wire does not intersect any other one.
286 if (myImbdone) {
287 if (Update) {
288 BRepCheck::Add(myMap(myShape),myImbres);
289 }
290 return myImbres;
291 }
292
293 myImbdone = Standard_True;
294 myImbres = IntersectWires();
295 if (myImbres != BRepCheck_NoError) {
296 if (Update) {
297 BRepCheck::Add(myMap(myShape),myImbres);
298 }
299 return myImbres;
300 }
301
302 Standard_Integer Nbwire = myMapImb.Extent();
303 if (Nbwire < 1) {
304 if (Update) {
305 BRepCheck::Add(myMap(myShape),myImbres);
306 }
307 return myImbres;
308 }
309
310 BRep_Builder B;
311 TopExp_Explorer exp1,exp2;
312 TopTools_ListOfShape theListOfShape;
313 for (exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
314 exp1.More();exp1.Next()) {
315
316 const TopoDS_Wire& wir1 = TopoDS::Wire(exp1.Current());
317 TopoDS_Shape aLocalShape = myShape.EmptyCopied();
318 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
319// TopoDS_Face newFace = TopoDS::Face(myShape.EmptyCopied());
6e6cd5d9 320
7fd59977 321 newFace.Orientation(TopAbs_FORWARD);
322 B.Add(newFace,wir1);
323
324 BRepTopAdaptor_FClass2d FClass2d(newFace,Precision::PConfusion());
325 Standard_Boolean WireBienOriente = Standard_False;
326 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
327 WireBienOriente=Standard_True;
0d969553 328 // the given wire defines a hole
7fd59977 329 myMapImb.UnBind(wir1);
330 myMapImb.Bind(wir1.Reversed(), theListOfShape);
331 }
332
333 for (exp2.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
334 exp2.More();exp2.Next()) {
335 const TopoDS_Wire& wir2 = TopoDS::Wire(exp2.Current());
336 if (!wir2.IsSame(wir1)) {
337
338 if (IsInside(wir2,WireBienOriente,FClass2d,newFace)) {
339 myMapImb(wir1).Append(wir2);
340 }
341 }
342 }
343 }
0d969553
Y
344 // It is required to have 1 wire that contains all others, and the others should not
345 // contain anything (case solid ended) or
346 // the wires do not contain anything : in this case the wires should be
347 // holes in an infinite face.
7fd59977 348 TopoDS_Wire Wext;
349 for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
350 itm.More();
351 itm.Next()) {
352 if (!itm.Value().IsEmpty()) {
353 if (Wext.IsNull()) {
354 Wext = TopoDS::Wire(itm.Key());
355 }
356 else {
357 myImbres = BRepCheck_InvalidImbricationOfWires;
358 if (Update) {
359 BRepCheck::Add(myMap(myShape),myImbres);
360 }
361 return myImbres;
362 }
363 }
364 }
365
366 if (!Wext.IsNull()) {
367 // verifies that the list contains nbwire-1 elements
368 if (myMapImb(Wext).Extent() != Nbwire-1) {
369 myImbres = BRepCheck_InvalidImbricationOfWires;
370 if (Update) {
371 BRepCheck::Add(myMap(myShape),myImbres);
372 }
373 return myImbres;
374 }
375 }
0d969553 376 // quit without errors
7fd59977 377 if (Update) {
378 BRepCheck::Add(myMap(myShape),myImbres);
379 }
380 return myImbres;
381
382}
383
384
385//=======================================================================
386//function : OrientationOfWires
387//purpose :
388//=======================================================================
389
390BRepCheck_Status BRepCheck_Face::OrientationOfWires
391 (const Standard_Boolean Update)
392{
393 // WARNING : it is assumed that the edges of a wire are correctly oriented
394
395
396 Standard_Boolean Infinite = myShape.Infinite();
397
398 if (myOridone) {
399 if (Update) {
400 BRepCheck::Add(myMap(myShape),myOrires);
401 }
402 return myOrires;
403 }
404
405 myOridone = Standard_True;
406 myOrires = ClassifyWires();
407 if (myOrires != BRepCheck_NoError) {
408 if (Update) {
409 BRepCheck::Add(myMap(myShape),myOrires);
410 }
411 return myOrires;
412 }
413
414 Standard_Integer Nbwire = myMapImb.Extent();
415 TopoDS_Wire Wext;
416 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
417 if (Nbwire == 1) {
418 if (!Infinite) {
419 Wext = TopoDS::Wire(itm.Key());
420 }
421 }
422 else {
423 for (;itm.More();itm.Next()) {
424 if (!itm.Value().IsEmpty()) {
425 Wext = TopoDS::Wire(itm.Key());
426 }
427 }
428 }
429
430 if (Wext.IsNull() && !Infinite) {
431 if (Nbwire>0) myOrires = BRepCheck_InvalidImbricationOfWires;
432 if (Update) {
433 BRepCheck::Add(myMap(myShape),myOrires);
434 }
435 return myOrires;
436 }
437
438 // BRep_Builder B;
439 TopExp_Explorer exp(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
440 for (; exp.More(); exp.Next()) {
441 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
442 if (!Wext.IsNull() && wir.IsSame(Wext)) {
443 if (wir.Orientation() != Wext.Orientation()) {
0d969553 444 //the exterior wire defines a hole
7fd59977 445 if( CheckThin(wir,myShape.Oriented(TopAbs_FORWARD)) )
446 return myOrires;
447 myOrires = BRepCheck_BadOrientationOfSubshape;
448 if (Update) {
449 BRepCheck::Add(myMap(myShape),myOrires);
450 }
451 return myOrires;
452 }
453 }
454 else {
455 for (itm.Reset(); itm.More(); itm.Next()) {
456 if (itm.Key().IsSame(wir)) {
457 break;
458 }
459 }
0d969553 460 // No control on More()
7fd59977 461 if (itm.Key().Orientation() == wir.Orientation()) {
0d969553 462 // the given wire does not define a hole
7fd59977 463 myOrires = BRepCheck_BadOrientationOfSubshape;
464 if (Update) {
465 BRepCheck::Add(myMap(myShape),myOrires);
466 }
467 return myOrires;
468 }
469 }
470 }
0d969553 471 // quit withour error
7fd59977 472 if (Update) {
473 BRepCheck::Add(myMap(myShape),myOrires);
474 }
475 return myOrires;
476}
477
478
479//=======================================================================
480//function : SetUnorientable
481//purpose :
482//=======================================================================
483
484void BRepCheck_Face::SetUnorientable()
485{
486 BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
487}
488
52d45841 489//=======================================================================
490//function : SetStatus
491//purpose :
492//=======================================================================
493
494void BRepCheck_Face::SetStatus(const BRepCheck_Status theStatus)
495{
496 BRepCheck::Add(myMap(myShape),theStatus);
497}
7fd59977 498
499//=======================================================================
500//function : IsUnorientable
501//purpose :
502//=======================================================================
503
504Standard_Boolean BRepCheck_Face::IsUnorientable() const
505{
506 if (myOridone) {
507 return (myOrires != BRepCheck_NoError);
508 }
509 for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
510 itl.More();
511 itl.Next()) {
512 if (itl.Value() == BRepCheck_UnorientableShape) {
513 return Standard_True;
514 }
515 }
516 return Standard_False;
517}
518
519//=======================================================================
520//function : GeometricControls
521//purpose :
522//=======================================================================
523
524void BRepCheck_Face::GeometricControls(const Standard_Boolean B)
525{
526 if (myGctrl != B) {
527 if (B) {
528 myIntdone = Standard_False;
529 myImbdone = Standard_False;
530 myOridone = Standard_False;
531 }
532 myGctrl = B;
533 }
534}
535
536
537//=======================================================================
538//function : GeometricControls
539//purpose :
540//=======================================================================
541
542Standard_Boolean BRepCheck_Face::GeometricControls() const
543{
544 return myGctrl;
545}
546
547
548//=======================================================================
549//function : Intersect
550//purpose :
551//=======================================================================
552
553static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
554 const TopoDS_Wire& wir2,
7c8090aa 555 const TopoDS_Face& F,
556 const DataMapOfShapeBox2d& theMapEdgeBox)
7fd59977 557{
558 Standard_Real Inter2dTol = 1.e-10;
559 TopExp_Explorer exp1,exp2;
560// BRepAdaptor_Curve2d cur1,cur2;
561
562 //Find common vertices of two wires - non-manifold case
563 TopTools_MapOfShape MapW1;
564 TopTools_SequenceOfShape CommonVertices;
565 for (exp1.Init( wir1, TopAbs_VERTEX ); exp1.More(); exp1.Next())
566 MapW1.Add( exp1.Current() );
567 for (exp2.Init( wir2, TopAbs_VERTEX ); exp2.More(); exp2.Next())
568 {
569 TopoDS_Shape V = exp2.Current();
570 if (MapW1.Contains( V ))
571 CommonVertices.Append( V );
572 }
573
574 // MSV 03.04.2002: create pure surface adaptor to avoid UVBounds computation
575 // due to performance problem
576 BRepAdaptor_Surface Surf(F,Standard_False);
577
578 TColgp_SequenceOfPnt PntSeq;
579 Standard_Integer i;
580 for (i = 1; i <= CommonVertices.Length(); i++)
581 {
582 TopoDS_Vertex V = TopoDS::Vertex( CommonVertices(i) );
583 gp_Pnt2d P2d = BRep_Tool::Parameters( V, F );
584 gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
585 PntSeq.Append( P );
586 }
587
588 Geom2dAdaptor_Curve C1,C2;
589 gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
590 Standard_Real first1,last1,first2,last2;
591 Geom2dInt_GInter Inter;
592 IntRes2d_Domain myDomain1,myDomain2;
593 Bnd_Box2d Box1, Box2;
594
595 for (exp1.Init(wir1,TopAbs_EDGE); exp1.More(); exp1.Next())
596 {
597 const TopoDS_Edge& edg1 = TopoDS::Edge(exp1.Current());
598 // cur1.Initialize(edg1,F);
599 C1.Load( BRep_Tool::CurveOnSurface(edg1,F,first1,last1) );
600 // To avoid exeption in Segment if C1 is BSpline - IFV
601 if(C1.FirstParameter() > first1) first1 = C1.FirstParameter();
602 if(C1.LastParameter() < last1 ) last1 = C1.LastParameter();
603
7fd59977 604 Box1.SetVoid();
7c8090aa 605 if (theMapEdgeBox.IsBound (edg1))
606 {
607 Box1 = theMapEdgeBox (edg1);
608 }
609 if (Box1.IsVoid())
610 {
611 BndLib_Add2dCurve::Add( C1, first1, last1, 0., Box1 );
612 }
7fd59977 613 for (exp2.Init(wir2,TopAbs_EDGE); exp2.More(); exp2.Next())
614 {
615 const TopoDS_Edge& edg2 = TopoDS::Edge(exp2.Current());
616 if (!edg1.IsSame(edg2))
617 {
618 //cur2.Initialize(edg2,F);
619 C2.Load( BRep_Tool::CurveOnSurface(edg2,F,first2,last2) );
620 // To avoid exeption in Segment if C2 is BSpline - IFV
621 if(C2.FirstParameter() > first2) first2 = C2.FirstParameter();
622 if(C2.LastParameter() < last2 ) last2 = C2.LastParameter();
623
7c8090aa 624 Box2.SetVoid();
625 if (theMapEdgeBox.IsBound (edg2))
626 {
627 Box2 = theMapEdgeBox (edg2);
628 }
629 if (Box2.IsVoid())
630 {
631 BndLib_Add2dCurve::Add( C2, first2, last2, 0., Box2 );
632 }
7fd59977 633 if (! Box1.IsOut( Box2 ))
634 {
7c8090aa 635 BRep_Tool::UVPoints(edg1,F,pfirst1,plast1);
636 myDomain1.SetValues( pfirst1, first1, Inter2dTol, plast1, last1, Inter2dTol );
7fd59977 637 BRep_Tool::UVPoints(edg2,F,pfirst2,plast2);
638 myDomain2.SetValues( pfirst2, first2, Inter2dTol, plast2, last2, Inter2dTol );
639 Inter.Perform( C1, myDomain1, C2, myDomain2, Inter2dTol, Inter2dTol );
640 if (!Inter.IsDone())
641 return Standard_True;
642 if (Inter.NbSegments() > 0)
643 {
644 if (PntSeq.IsEmpty())
645 return Standard_True;
646 else
647 {
648 Standard_Integer NbCoinc = 0;
649 for (i = 1; i <= Inter.NbSegments(); i++)
650 {
651 if (!Inter.Segment(i).HasFirstPoint() || !Inter.Segment(i).HasLastPoint())
652 return Standard_True;
653 gp_Pnt2d FirstP2d = Inter.Segment(i).FirstPoint().Value();
654 gp_Pnt2d LastP2d = Inter.Segment(i).LastPoint().Value();
655 gp_Pnt FirstP = Surf.Value( FirstP2d.X(), FirstP2d.Y() );
656 gp_Pnt LastP = Surf.Value( LastP2d.X(), LastP2d.Y() );
657 for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
658 {
659 Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
660 if (FirstP.IsEqual( PntSeq(j), tolv ) || LastP.IsEqual( PntSeq(j), tolv ))
661 {
662 NbCoinc++;
663 break;
664 }
665 }
666 }
667 if (NbCoinc == Inter.NbSegments())
668 return Standard_False;
669 return Standard_True;
670 }
671 }
672 if (Inter.NbPoints() > 0)
673 {
674 if (PntSeq.IsEmpty())
675 return Standard_True;
676 else
677 {
678 Standard_Integer NbCoinc = 0;
679 for (i = 1; i <= Inter.NbPoints(); i++)
680 {
681 gp_Pnt2d P2d = Inter.Point(i).Value();
682 gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
683 for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
684 {
685 Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
686 if (P.IsEqual( PntSeq(j), tolv ))
687 {
688 NbCoinc++;
689 break;
690 }
691 }
692 }
693 if (NbCoinc == Inter.NbPoints())
694 return Standard_False;
695 return Standard_True;
696 }
697 }
698 }
699 }
700 }
701 }
702 return Standard_False;
703}
704
705
706//=======================================================================
707//function : IsInside
708//purpose :
709//=======================================================================
710
b3cb7aa2 711static Standard_Boolean IsInside(const TopoDS_Wire& theWire,
7fd59977 712 const Standard_Boolean WireBienOriente,
713 const BRepTopAdaptor_FClass2d& FClass2d,
b3cb7aa2 714 const TopoDS_Face& theFace)
7fd59977 715{
b3cb7aa2 716 Standard_Real aParameter, aFirst, aLast;
717
718 TopExp_Explorer anExplorer(theWire, TopAbs_EDGE);
719 for( ; anExplorer.More(); anExplorer.Next() )
720 {
721 const TopoDS_Edge& anEdge = TopoDS::Edge( anExplorer.Current() );
722 Handle(Geom2d_Curve) aCurve2D =
723 BRep_Tool::CurveOnSurface( anEdge, theFace, aFirst, aLast );
724
725 // Selects the parameter of point on the curve
726 if( !Precision::IsNegativeInfinite(aFirst) &&
727 !Precision::IsPositiveInfinite(aLast) )
728 {
729 aParameter = (aFirst + aLast) * 0.5;
7fd59977 730
b3cb7aa2 731 // Edge is skipped if its parametric range is too small
732 if( Abs(aParameter - aFirst) < Precision::PConfusion() )
733 {
734 continue;
735 }
7fd59977 736
b3cb7aa2 737 //Edge is skipped if its length is too small
738 Standard_Real aFirst3D, aLast3D;
739 Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst3D, aLast3D );
740 if ( aCurve.IsNull() )
741 {
742 continue;
743 }
744
745 gp_Pnt aPoints[2];
746 // Compute start point of edge
747 aCurve->D0( aFirst, aPoints[0] );
748 // Compute middle point of edge
749 aCurve->D0( (aFirst3D+aLast3D)/2., aPoints[1] );
750 if( aPoints[0].Distance(aPoints[1]) < Precision::Confusion() )
751 {
752 continue;
753 }
7fd59977 754 }
b3cb7aa2 755 else
756 {
757 if( Precision::IsNegativeInfinite(aFirst) &&
758 Precision::IsPositiveInfinite(aLast) )
759 {
760 aParameter = 0.;
7fd59977 761 }
b3cb7aa2 762 else if( Precision::IsNegativeInfinite(aFirst) )
763 {
764 aParameter = aLast - 1.;
7fd59977 765 }
b3cb7aa2 766 else
767 {
768 aParameter = aFirst + 1.;
7fd59977 769 }
770 }
771
b3cb7aa2 772 // Find point on curve (edge)
773 gp_Pnt2d aPoint2D(aCurve2D->Value(aParameter));
774 // Compute the topological position of a point relative to face
775 TopAbs_State aState = FClass2d.Perform(aPoint2D, Standard_False);
776
777 if( WireBienOriente )
778 {
779 return aState == TopAbs_OUT;
7fd59977 780 }
b3cb7aa2 781 else
782 {
783 return aState == TopAbs_IN;
7fd59977 784 }
7fd59977 785 }
786 return Standard_False;
787}
7fd59977 788Standard_Boolean CheckThin(const TopoDS_Shape& w, const TopoDS_Shape& f)
789{
790 TopoDS_Face aF = TopoDS::Face(f);
791 TopoDS_Wire aW = TopoDS::Wire(w);
792
793 Standard_Integer nbE = 0;
794 TopTools_ListOfShape lE;
795 TopExp_Explorer exp(aW,TopAbs_EDGE);
796 for(; exp.More(); exp.Next()) {
797 const TopoDS_Shape& s = exp.Current();
798 lE.Append(s);
799 nbE++;
800 }
801
802 if( nbE != 2 ) return Standard_False;
803 TopoDS_Edge e1 = TopoDS::Edge(lE.First());
804 TopoDS_Edge e2 = TopoDS::Edge(lE.Last());
805
806 TopoDS_Vertex v1, v2, v3, v4;
807 TopExp::Vertices(e1,v1,v2);
808 TopExp::Vertices(e2,v3,v4);
809
810 if( v1.IsNull() || v2.IsNull() ||
811 v3.IsNull() || v4.IsNull() ) return Standard_False;
812
813 if( v1.IsSame(v2) || v3.IsSame(v4) )
814 return Standard_False;
815
816 Standard_Boolean sF = Standard_False, sL = Standard_False;
817 if( v1.IsSame(v3) || v1.IsSame(v4) ) sF = Standard_True;
818 if( v2.IsSame(v3) || v2.IsSame(v4) ) sL = Standard_True;
819
820 if( !sF || !sL ) return Standard_False;
821
822 TopAbs_Orientation e1or = e1.Orientation();
823 TopAbs_Orientation e2or = e2.Orientation();
824
825 Standard_Real f1 = 0., l1 = 0., f2 = 0., l2 = 0.;
826 Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,aF,f1,l1);
827 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,aF,f2,l2);
828
829 if( pc1.IsNull() || pc2.IsNull() ) return Standard_False;
830
831 Standard_Real d1 = Abs(l1-f1)/100.;
832 Standard_Real d2 = Abs(l2-f2)/100.;
833 Standard_Real m1 = (l1+f1)*0.5;
834 Standard_Real m2 = (l2+f2)*0.5;
835
836 gp_Pnt2d p1f(pc1->Value(m1-d1));
837 gp_Pnt2d p1l(pc1->Value(m1+d1));
838 gp_Pnt2d p2f(pc2->Value(m2-d2));
839 gp_Pnt2d p2l(pc2->Value(m2+d2));
840
841 gp_Vec2d vc1(p1f,p1l);
842 gp_Vec2d vc2(p2f,p2l);
843
844 if( (vc1*vc2) >= 0. && e1or == e2or ) return Standard_False;
845
846 return Standard_True;
847}