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