0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / TopOpeBRep / TopOpeBRep_FacesIntersector.cxx
CommitLineData
b311480e 1// Created on: 1993-11-18
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1993-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
42cf5bc1 17
18#include <Bnd_Box.hxx>
19#include <BRepAdaptor_HSurface.hxx>
20#include <BRepTopAdaptor_TopolTool.hxx>
21#include <TopoDS_Shape.hxx>
22#include <TopOpeBRep_FacesIntersector.hxx>
23#include <TopOpeBRep_LineInter.hxx>
7fd59977 24
25#ifdef DRAW
26#include <TopOpeBRep_DRAW.hxx>
27#endif
28
29#include <IntPatch_LineConstructor.hxx>
30#include <TopOpeBRep_TypeLineCurve.hxx>
31#include <TopoDS.hxx>
32#include <TopoDS_Face.hxx>
33#include <TopoDS_Edge.hxx>
34#include <BRep_Tool.hxx>
35#include <TopExp_Explorer.hxx>
36#include <TopOpeBRepTool_ShapeTool.hxx>
37#include <Precision.hxx>
38#include <Geom_Curve.hxx>
39#include <Standard_ProgramError.hxx>
40#include <TCollection_AsciiString.hxx>
41#include <Standard_CString.hxx>
42#include <BRepTools.hxx>
43#include <TopOpeBRepTool_tol.hxx>
44
45Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7;
46
0797d9d3 47#ifdef OCCT_DEBUG
7fd59977 48#include <TopAbs.hxx>
1d0a9d4d 49extern Standard_Boolean TopOpeBRep_GettraceFI();
50extern Standard_Boolean TopOpeBRep_GettraceFITOL();
51extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
7fd59977 52
1d0a9d4d 53Standard_Integer SAVFFi1 = 0;
54Standard_Integer SAVFFi2 = 0;
7fd59977 55static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2)
56{
57 TCollection_AsciiString an1("SAVA");if (SAVFFi1) an1=an1+SAVFFi1;
58 TCollection_AsciiString an2("SAVB");if (SAVFFi2) an2=an2+SAVFFi2;
59 Standard_CString n1=an1.ToCString();Standard_CString n2=an2.ToCString();
60#ifdef DRAW
04232180 61 std::cout<<"FaceIntersector : set "<<n1<<","<<n2<<std::endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2);
7fd59977 62#endif
04232180 63 std::cout<<"FaceIntersector : write "<<n1<<","<<n2<<std::endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2);
7fd59977 64}
65
1d0a9d4d 66extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
7fd59977 67#include <TopOpeBRepTool_KRO.hxx>
68Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face");
69
70#endif
71
72// NYI
73// NYI : IntPatch_Intersection : TolArc,TolTang exact definition
74// NYI
75
76
77// modified by NIZHNY-MKK Mon Apr 2 12:14:32 2001.BEGIN
78#include <IntPatch_WLine.hxx>
79#include <IntPatch_RLine.hxx>
80#include <IntPatch_Point.hxx>
81#include <Adaptor3d_HSurface.hxx>
82#include <Adaptor3d_TopolTool.hxx>
83#include <Adaptor3d_HVertex.hxx>
84#include <Adaptor2d_HCurve2d.hxx>
85#include <Geom2dInt_TheProjPCurOfGInter.hxx>
86
87static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
88 const Standard_Integer theRank,
89 const Handle(Adaptor3d_HSurface)& theSurface,
90 const Handle(Adaptor3d_TopolTool)& theDomain,
91 const Standard_Real theTolArc);
92
93static
94Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
95 const Handle(Adaptor2d_HCurve2d)& theArc,
96 const Standard_Integer theRank);
97
98static
99Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
100 const Standard_Integer theRank,
101 const Handle(Adaptor3d_HSurface)& theSurface,
102 const Handle(Adaptor3d_TopolTool)& theDomain,
103 const Standard_Real theTolArc);
104
105static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
106 const Handle(Adaptor3d_HSurface)& theSurface1,
107 const Handle(Adaptor3d_TopolTool)& theDomain1,
108 const Handle(Adaptor3d_HSurface)& theSurface2,
109 const Handle(Adaptor3d_TopolTool)& theDomain2,
110 const Standard_Real theTolArc);
111// modified by NIZHNY-MKK Mon Apr 2 12:14:38 2001.END
112
113// modified by NIZHNY-OFV Fri Mar 29 12:37:21 2002.BEGIN
114#include <TColgp_SequenceOfPnt.hxx>
115#include <TopExp.hxx>
116#include <TColStd_SequenceOfReal.hxx>
117#include <Extrema_ExtPS.hxx>
118#include <Extrema_ExtPC.hxx>
119#include <Extrema_POnSurf.hxx>
120#include <GeomAdaptor_Curve.hxx>
121static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
122 const Handle(Adaptor3d_HSurface)& theSurface1,
123 const Handle(Adaptor3d_TopolTool)& theDomain1,
124 const Handle(Adaptor3d_HSurface)& theSurface2,
125 const Handle(Adaptor3d_TopolTool)& theDomain2,
126 const Standard_Real theTolArc);
127//------------------------------------------------------------------------------------------------
128static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
129 const Standard_Integer& theRankS,
130 const Handle(Adaptor3d_HSurface)& theSurfaceObj,
131 const Handle(Adaptor3d_TopolTool)& theDomainObj,
132 const Handle(Adaptor3d_HSurface)& theSurfaceTool,
133 const gp_Pnt& theTestPoint,
134 Standard_Real& theVrtxTol,
135 Handle(IntSurf_LineOn2S)& theLineOn2S,
136 Standard_Real& theFirst,
137 Standard_Real& theLast);
138//------------------------------------------------------------------------------------------------
139static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
140 const Adaptor3d_Surface& theTestSurface,
141 const Standard_Real& theTol);
142//-------------------------------------------------------------------------------------------------
143static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
144 const Adaptor3d_Surface& theTestSurface,
145 const Standard_Real& theTol,
146 Extrema_POnSurf& theResultPoint);
147//-------------------------------------------------------------------------------------------------------------------------
148static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
149 const Standard_Real& theVrtxTol,
150 const Handle(IntSurf_LineOn2S)& theLineOn2S);
151//---------------------------------------------------------------------------------------------------------------------------
152// modified by NIZHNY-OFV Fri Mar 29 12:41:02 2002.END
153
154//=======================================================================
155//function : TopOpeBRep_FacesIntersector
156//purpose :
157//=======================================================================
158TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector ()
159{
160 ResetIntersection();
161 myTol1 = myTol2 = Precision::Confusion();
162 myForceTolerances = Standard_False;
163 mySurface1 = new BRepAdaptor_HSurface();
164 mySurface2 = new BRepAdaptor_HSurface();
165 myDomain1 = new BRepTopAdaptor_TopolTool();
166 myDomain2 = new BRepTopAdaptor_TopolTool();
167}
168
169//=======================================================================
170//function : Perform
171//purpose :
172//=======================================================================
173void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2,
174 const Bnd_Box& B1,const Bnd_Box& B2)
175{
0797d9d3 176#ifdef OCCT_DEBUG
7fd59977 177 if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2));
178#endif
179
180 ResetIntersection();
181 if (!myForceTolerances) ShapeTolerances(F1,F2);
182
183 myFace1 = TopoDS::Face(F1); myFace1.Orientation(TopAbs_FORWARD);
184 myFace2 = TopoDS::Face(F2); myFace2.Orientation(TopAbs_FORWARD);
185 BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1);
186 BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2);
187 mySurfaceType1 = S1.GetType();
188 mySurfaceType2 = S2.GetType();
543a9964 189 const Handle(Adaptor3d_HSurface)& aSurf1 = mySurface1; // to avoid ambiguity
190 myDomain1->Initialize(aSurf1);
191 const Handle(Adaptor3d_HSurface)& aSurf2 = mySurface2; // to avoid ambiguity
192 myDomain2->Initialize(aSurf2);
7fd59977 193
0797d9d3 194#ifdef OCCT_DEBUG
7fd59977 195 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start();
196#endif
197
198 Standard_Real Deflection=0.01,MaxUV=0.01;
199 if (!myForceTolerances) {
200 FTOL_FaceTolerances3d(B1,B2,myFace1,myFace2,S1,S2,
201 myTol1,myTol2,Deflection,MaxUV);
202 myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
203 myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
204 }
205
206 Standard_Real tol1 = myTol1;
207 Standard_Real tol2 = myTol2;
208 GLOBAL_tolFF = Max(tol1,tol2);
209
0797d9d3 210#ifdef OCCT_DEBUG
7fd59977 211 if (TopOpeBRep_GettraceFITOL()) {
04232180 212 std::cout<<"FacesIntersector : Perform tol1 = "<<tol1<<std::endl;
213 std::cout<<" tol2 = "<<tol2<<std::endl;
214 std::cout<<" defl = "<<Deflection<<" MaxUV = "<<MaxUV<<std::endl;
7fd59977 215 }
216#endif
217
218 myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection);
d4b867e6 219 myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,
4e14c88f 220 myTol1,myTol2,Standard_True,Standard_True,
221 Standard_False);
7fd59977 222
0797d9d3 223#ifdef OCCT_DEBUG
7fd59977 224 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop();
225#endif
226
227 //xpu180998 : cto900Q1
228 Standard_Boolean done = myIntersector.IsDone();
229 if (!done) return;
230
231 PrepareLines();
232 myIntersectionDone = Standard_True;
233
234 // mySurfacesSameOriented : a mettre dans IntPatch NYI
235 if ( SameDomain() ) {
236 mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
237 }
238
239 // build the map of edges found as RESTRICTION
240 for (InitLine(); MoreLine(); NextLine()) {
241 TopOpeBRep_LineInter& L = CurrentLine();
242 if (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) {
7fd59977 243 const TopoDS_Shape& E = L.Arc();
244 myEdgeRestrictionMap.Add(E);
245 }
246 }
247
0797d9d3 248#ifdef OCCT_DEBUG
04232180 249 if (TopOpeBRep_GettraceFI()) std::cout<<"Perform : isempty "<<IsEmpty()<<std::endl;
7fd59977 250#endif
251}
252
253//=======================================================================
254//function : Perform
255//purpose :
256//=======================================================================
257
258void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
259{
260 Bnd_Box B1,B2;
261 Perform(F1,F2,B1,B2);
262}
263
264
265//=======================================================================
266//function : IsEmpty
267//purpose :
268//=======================================================================
269
270Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty ()
271{
272 if ( ! myIntersectionDone ) return Standard_False;
273 Standard_Boolean done = myIntersector.IsDone();
274 Standard_Boolean empty = myIntersector.IsEmpty();
275 if ( !done || empty ) return Standard_True;
276 else {
277 // ElemIntersector is done and is not empty
278 // returns True if at least one VPoint is found
279 empty = Standard_True;
280 for ( InitLine(); MoreLine(); NextLine() ) {
281 empty = (CurrentLine().NbVPoint() == 0);
282 if ( ! empty ) break;
283 }
284 return empty;
285 }
286}
287
288//=======================================================================
289//function : IsDone
290//purpose :
291//=======================================================================
292
293Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const
294{
295 return myIntersectionDone;
296}
297
298//=======================================================================
299//function : SameDomain
300//purpose :
301//=======================================================================
302
303Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const
304{
305 if (!myIntersectionDone)
9775fa61 306 throw Standard_ProgramError("FacesIntersector : bad SameDomain");
7fd59977 307
308 Standard_Boolean sd = myIntersector.TangentFaces();
6e6cd5d9 309
310 //Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane);
311
7fd59977 312// if (!plpl) return Standard_False;
313 return sd;
314}
315
316
317//=======================================================================
318//function : Face
319//purpose :
320//=======================================================================
321
322const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face
323(const Standard_Integer Index) const
324{
325 if ( Index == 1 ) return myFace1;
326 else if ( Index == 2 ) return myFace2;
9775fa61 327 else throw Standard_ProgramError("TopOpeBRep_FacesIntersector::Face");
7fd59977 328}
329
330
331//=======================================================================
332//function : SurfacesSameOriented
333//purpose :
334//=======================================================================
335
336Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const
337{
338 if ( SameDomain() ) {
339 return mySurfacesSameOriented;
340 }
9775fa61 341 throw Standard_ProgramError("FacesIntersector : bad SurfacesSameOriented");
7fd59977 342}
343
344//=======================================================================
345//function : IsRestriction
346//purpose :
347//=======================================================================
348
349Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction
350 (const TopoDS_Shape& E) const
351{
352 Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E);
353 return isrest;
354}
355
356//=======================================================================
357//function : Restrictions
358//purpose :
359//=======================================================================
360
361const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions
362 () const
363{
364 return myEdgeRestrictionMap;
365}
366
367//=======================================================================
368//function : PrepareLines
369//purpose :
370//=======================================================================
371
372void TopOpeBRep_FacesIntersector::PrepareLines()
373{
374 myLineNb = 0;
375 Standard_Integer n = myIntersector.NbLines();
376 myHAL = new TopOpeBRep_HArray1OfLineInter(0,n);
377 BRepAdaptor_Surface& S1 = *((BRepAdaptor_Surface*)&(mySurface1->Surface()));
378 BRepAdaptor_Surface& S2 = *((BRepAdaptor_Surface*)&(mySurface2->Surface()));
379
380 // modified by NIZHNY-MKK Mon Apr 2 12:14:58 2001.BEGIN
381 if(n==0)
382 return;
383 // modified by NIZHNY-MKK Mon Apr 2 12:15:09 2001.END
384
385 Standard_Boolean newV = Standard_True;
386
387 if (!newV) {
388 /*for ( Standard_Integer i=1; i<=n; i++) {
389 TopOpeBRep_LineInter& LI = myHAL->ChangeValue(i);
390 const Handle(IntPatch_Line)& L = myIntersector.Line(i);
391 LI.SetLine(L,S1,S2);
392 LI.Index(i);
393 myLineNb++;;
394 }*/}
395
396 if (newV) {
397 //-- lbr
398
399 // modified by NIZHNY-MKK Mon Apr 2 12:16:04 2001
400 IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines;
401
402 Standard_Integer i ;
403// Standard_Integer nbl=0;
404 IntPatch_LineConstructor **Ptr =
405 (IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *));
406 for( i=1;i<=n;i++) {
407 Ptr[i-1]=new IntPatch_LineConstructor(2);
408 Ptr[i-1]->Perform(myIntersector.SequenceOfLine(),
409 myIntersector.Line(i),
410 mySurface1,myDomain1,
411 mySurface2,myDomain2,
412 myTol1);
413 // modified by NIZHNY-MKK Mon Apr 2 12:16:26 2001.BEGIN
414 aSeqOfLines.Clear();
415 for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) {
416 aSeqOfLines.Append(Ptr[i-1]->Line(k));
417 }
418
419 TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
420
421 for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) {
422 aSeqOfResultLines.Append(aSeqOfLines.Value(j));
423 }
424 delete Ptr[i-1];
425 // nbl+=Ptr[i-1]->NbLines();
426 // modified by NIZHNY-MKK Mon Apr 2 12:16:31 2001.END
427 }
428
429 // modified by NIZHNY-MKK Mon Apr 2 12:17:22 2001.BEGIN
430 // myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl);
431 myLineNb = aSeqOfResultLines.Length();
432
433 //Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
434 MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
435 myLineNb = aSeqOfResultLines.Length();
436
437
438 if(myLineNb > 0) {
439 myHAL = new TopOpeBRep_HArray1OfLineInter(1, myLineNb);
440 for(Standard_Integer index = 1; index <= myLineNb; index++) {
441 TopOpeBRep_LineInter& LI = myHAL->ChangeValue(index);
442 const Handle(IntPatch_Line)& L = aSeqOfResultLines.Value(index);
443 LI.SetLine(L,S1,S2);
444 LI.Index(index);
445 }
446 }
447
448 // nbl=1;
449 // for(i=1;i<=n;i++) {
450 // for(Standard_Integer k=1;k<=Ptr[i-1]->NbLines();k++) {
451 // TopOpeBRep_LineInter& LI = myHAL->ChangeValue(nbl);
452 // const Handle(IntPatch_Line)& L = Ptr[i-1]->Line(k);
453 // LI.SetLine(L,S1,S2);
454 // LI.Index(nbl);
455 // myLineNb++;
456 // nbl++;
457 // }
458 // delete Ptr[i-1];
459 // }
460 // modified by NIZHNY-MKK Mon Apr 2 12:17:57 2001.END
461 free(Ptr);
462 }
463}
464
465//=======================================================================
466//function : Lines
467//purpose :
468//=======================================================================
469
470Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines()
471{
472 return myHAL;
473}
474
475//=======================================================================
476//function : NbLines
477//purpose :
478//=======================================================================
479
480Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const
481{
482 return myLineNb;
483}
484
485//=======================================================================
486//function : InitLine
487//purpose :
488//=======================================================================
489
490void TopOpeBRep_FacesIntersector::InitLine()
491{
492 myLineIndex = 1;
493 FindLine();
494}
495
496//=======================================================================
497//function : FindLine
498//purpose :
499//=======================================================================
500
501void TopOpeBRep_FacesIntersector::FindLine()
502{
503 myLineFound = Standard_False;
504 if ( ! myIntersectionDone ) return;
505
506 while (myLineIndex <= myLineNb) {
507 const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex);
508 myLineFound = L.OK();
509 if (myLineFound) break;
510 else myLineIndex++;
511 }
512}
513
514//=======================================================================
515//function : MoreLine
516//purpose :
517//=======================================================================
518
519Standard_Boolean TopOpeBRep_FacesIntersector::MoreLine()const
520{
521 return myLineFound;
522}
523
524
525//=======================================================================
526//function : NextLine
527//purpose :
528//=======================================================================
529
530void TopOpeBRep_FacesIntersector::NextLine()
531{
532 myLineIndex++;
533 FindLine();
534}
535
536//=======================================================================
537//function : CurrentLine
538//purpose :
539//=======================================================================
540
541TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine()
542{
543 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex);
544 return TLI;
545}
546
547
548//=======================================================================
549//function : CurrentLineIndex
550//purpose :
551//=======================================================================
552
553Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const
554{
555 return myLineIndex;
556}
557
558//=======================================================================
559//function : Line
560//purpose :
561//=======================================================================
562
563TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL)
564{
565 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL);
566 return TLI;
567}
568
569//=======================================================================
570//function : ResetIntersection
571//purpose :
572//=======================================================================
573
574void TopOpeBRep_FacesIntersector::ResetIntersection()
575{
576 myIntersectionDone = Standard_False;
577 myLineIndex = 1;
578 myLineNb = 0;
579 myEdgeRestrictionMap.Clear();
580 myLineFound = Standard_False;
581}
582
583
584//=======================================================================
585//function : ForceTolerances
586//purpose :
587//=======================================================================
588
589void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1,
590 const Standard_Real Tol2)
591{
592 myTol1 = Tol1;
593 myTol2 = Tol2;
594 myForceTolerances = Standard_True;
0797d9d3 595#ifdef OCCT_DEBUG
7fd59977 596 if (TopOpeBRep_GettraceFITOL())
04232180 597 std::cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<std::endl;
7fd59977 598#endif
599}
600
601//=======================================================================
602//function : GetTolerances
603//purpose :
604//=======================================================================
605
606void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1,
607 Standard_Real& Tol2) const
608{
609 Tol1 = myTol1;
610 Tol2 = myTol2;
611}
612
613//=======================================================================
614//function : ShapeTolerances
615//purpose : (private)
616//=======================================================================
617
0797d9d3 618#ifdef OCCT_DEBUG
7fd59977 619void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1,
620 const TopoDS_Shape& S2)
621#else
622void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& ,
623 const TopoDS_Shape& )
624#endif
625{
626// myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
627 myTol1 = Precision::Confusion();
628 myTol2 = myTol1;
629 myForceTolerances = Standard_False;
0797d9d3 630#ifdef OCCT_DEBUG
7fd59977 631 if (TopOpeBRep_GettraceFITOL()) {
04232180 632 std::cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),std::cout);
633 std::cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),std::cout);
634 std::cout<<" : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<std::endl;
7fd59977 635 }
636#endif
637}
638
639//=======================================================================
640//function : ToleranceMax
641//purpose : (private)
642//=======================================================================
643
644Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax
645(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
646{
647 TopExp_Explorer e(S,T);
648 if ( ! e.More() ) return Precision::Intersection();
649 else {
650 Standard_Real tol = RealFirst();
651 for (; e.More(); e.Next())
652 tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
653 return tol;
654 }
655}
656
657
658// modified by NIZHNY-MKK Mon Apr 2 12:18:30 2001.BEGIN
659// ================================================================================================
660// static function: TestWLineAlongRestriction
661// purpose:
662// ================================================================================================
663static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
664 const Standard_Integer theRank,
665 const Handle(Adaptor3d_HSurface)& theSurface,
666 const Handle(Adaptor3d_TopolTool)& theDomain,
667 const Standard_Real theTolArc) {
668
669 Standard_Boolean result = Standard_False;
670 Standard_Integer NbPnts = theWLine->NbPnts();
671 Standard_Integer along = 0;
672
673 for(Standard_Integer i=1; i<=NbPnts; i++) {
674 const IntSurf_PntOn2S& Pmid = theWLine->Point(i);
675 Standard_Real u=0., v=0.;
676 if(theRank==1) Pmid.ParametersOnS1(u, v);
677 else Pmid.ParametersOnS2(u, v);
678 //------------------------------------------
679 gp_Pnt ap;
680 gp_Vec ad1u, ad1v;
681 //Standard_Real nad1u, nad1v, tolu, tolv;
682
683 theSurface->D1(u, v, ap, ad1u, ad1v);
684 //nad1u=ad1u.Magnitude();
685 //nad1v=ad1v.Magnitude();
686 //if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
687 //if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
688 //if(tolu>tolv) tolu=tolv;
689 //------------------------------------------
690
691 //if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) {
692 // along++;
693 //}
694
695 if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++;
696 //if(along!=i) break;
697 }
698 if(along==NbPnts) result = Standard_True;
699 return result;
700}
701
702
703// ================================================================================================
704// static function: BuildRLineBasedOnWLine
705// purpose:
706// ================================================================================================
707static
708Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
709 const Handle(Adaptor2d_HCurve2d)& theArc,
710 const Standard_Integer theRank) {
711 Handle(IntPatch_RLine) anRLine;
712
713 if((theRank != 1) && (theRank != 2))
714 return anRLine;
715
716 gp_Pnt2d aPOnLine;
717 Standard_Real u=0., v=0.;
718 Standard_Integer nbvtx = theWLine->NbVertex();
719 const IntPatch_Point& Vtx1 = theWLine->Vertex(1);
720 const IntPatch_Point& Vtx2 = theWLine->Vertex(nbvtx);
721
722 if(theRank == 1) {
723 Vtx1.ParametersOnS1(u, v);
724 }
725 else {
726 Vtx1.ParametersOnS2(u, v);
727 }
728
729 aPOnLine = gp_Pnt2d(u, v);
730 Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
731
732 if(theRank == 1) {
733 Vtx2.ParametersOnS1(u, v);
734 }
735 else {
736 Vtx2.ParametersOnS2(u, v);
737 }
738 aPOnLine = gp_Pnt2d(u, v);
739 Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
740
741 Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance();
742
743 if(Abs(par1 - par2) < theArc->Resolution(tol))
744 return anRLine;
745
746 Standard_Boolean IsOnFirst = (theRank == 1);
7fd59977 747
748 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
749 const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve();
750 IntSurf_Transition TransitionUndecided;
751
752 anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2());
753
754 if(IsOnFirst) {
755 anRLine->SetArcOnS1(theArc);
756 }
757 else {
758 anRLine->SetArcOnS2(theArc);
759 }
760
761 Standard_Integer k = 0;
762 if(par1 < par2) {
763
764 for(k = 1; k <= Lori->NbPoints(); k++) {
765 aLineOn2S->Add(Lori->Value(k));
766 }
767 anRLine->Add(aLineOn2S);
768 IntPatch_Point VtxFirst = Vtx1;
769
770 VtxFirst.SetArc(IsOnFirst, //-- On First
771 theArc,
772 par1,
773 TransitionUndecided,
774 TransitionUndecided);
775 VtxFirst.SetParameter(par1);
776 anRLine->AddVertex(VtxFirst);
777
778 for(k = 2; k < nbvtx; k++) {
779 IntPatch_Point Vtx = theWLine->Vertex(k);
780 if(theRank == 1) {
781 Vtx.ParametersOnS1(u, v);
782 }
783 else {
784 Vtx.ParametersOnS2(u, v);
785 }
786 gp_Pnt2d atmpPoint(u, v);
787 Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
788 Vtx.SetParameter(apar);
789 anRLine->AddVertex(Vtx);
790 }
791
792 IntPatch_Point VtxLast = Vtx2;
793 VtxLast.SetArc(IsOnFirst, //-- On First
794 theArc,
795 par2,
796 TransitionUndecided,
797 TransitionUndecided);
798 VtxLast.SetParameter(par2);
799 anRLine->AddVertex(VtxLast);
800 anRLine->SetFirstPoint(1);
801 anRLine->SetLastPoint(nbvtx);
802 anRLine->ComputeVertexParameters(Precision::Confusion());
803 }
804 else {
805
806 for(k = Lori->NbPoints(); k >= 1; k--) {
807 aLineOn2S->Add(Lori->Value(k));
808 }
809 anRLine->Add(aLineOn2S);
810
811 IntPatch_Point VtxFirst = Vtx2;
812 VtxFirst.SetArc(IsOnFirst, //-- On First
813 theArc,
814 par2,
815 TransitionUndecided,
816 TransitionUndecided);
817 VtxFirst.SetParameter(par2);
818 anRLine->AddVertex(VtxFirst);
819
820 for(k = nbvtx - 1; k >= 2; k--) {
821 IntPatch_Point Vtx = theWLine->Vertex(k);
822 Vtx.ReverseTransition();
823 if(theRank == 1) {
824 Vtx.ParametersOnS1(u, v);
825 }
826 else {
827 Vtx.ParametersOnS2(u, v);
828 }
829 gp_Pnt2d atmpPoint(u, v);
830 Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
831 Vtx.SetParameter(apar);
832 anRLine->AddVertex(Vtx);
833 }
834 IntPatch_Point VtxLast = Vtx1;
835 VtxLast.SetArc(IsOnFirst, //-- On First
836 theArc,
837 par1,
838 TransitionUndecided,
839 TransitionUndecided);
840 VtxLast.SetParameter(par1);
841 anRLine->AddVertex(VtxLast);
842 anRLine->SetFirstPoint(1);
843 anRLine->SetLastPoint(nbvtx);
844 anRLine->ComputeVertexParameters(Precision::Confusion());
845 }
846
847 return anRLine;
848}
849
850// ================================================================================================
851// static function: BuildRLine
852// purpose: build rline based on group of wlines
853// return null handle if it is not possible to build rline
854// ================================================================================================
855static
856Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
857 const Standard_Integer theRank,
858 const Handle(Adaptor3d_HSurface)& theSurface,
859 const Handle(Adaptor3d_TopolTool)& theDomain,
860 const Standard_Real theTolArc) {
861 Handle(IntPatch_RLine) anRLine;
862 const Handle(IntPatch_WLine)& aWLine1 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(1)));
863 const Handle(IntPatch_WLine)& aWLine2 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(theSeqOfWLine.Length())));
864 const IntPatch_Point& P1 = aWLine1->Vertex(1);
865 const IntPatch_Point& P2 = aWLine2->Vertex(aWLine2->NbVertex());
866 const Handle(Adaptor3d_HVertex)& aV1 = (theRank==1) ? P1.VertexOnS1() : P1.VertexOnS2();
867 const Handle(Adaptor3d_HVertex)& aV2 = (theRank==1) ? P2.VertexOnS1() : P2.VertexOnS2();
868
869 // avoid closed and degenerated edges
870 if(aV1->IsSame(aV2))
871 return anRLine;
872
873 for(theDomain->Init(); theDomain->More(); theDomain->Next()) {
874 theDomain->Initialize(theDomain->Value());
875 Standard_Boolean foundVertex1 = Standard_False;
876 Standard_Boolean foundVertex2 = Standard_False;
877
878 for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) {
879
880 if(!foundVertex1 && aV1->IsSame(theDomain->Vertex()))
881 foundVertex1 = Standard_True;
882 if(!foundVertex2 && aV2->IsSame(theDomain->Vertex()))
883 foundVertex2 = Standard_True;
884 }
885
886 if(foundVertex1 && foundVertex2) {
887 Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0);
888
889 for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) {
890 const Handle(IntPatch_WLine)& aWLine =
891 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i)));
892
893 Standard_Integer indexpnt = aWLine->NbPnts()/2;
894 if(indexpnt < 1)
895 buildrline = Standard_False;
896 else {
897 Standard_Real u = RealLast(), v = RealLast();
898 const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt);
899 if(theRank==1) {
900 POn2S.ParametersOnS1(u, v);
901 }
902 else {
903 POn2S.ParametersOnS2(u, v);
904 }
905 gp_Pnt2d aPOnArc, aPOnLine(u, v);
906 Standard_Real par = Geom2dInt_TheProjPCurOfGInter::FindParameter(theDomain->Value()->Curve2d(), aPOnLine, 1e-7);
907 aPOnArc = theDomain->Value()->Value(par);
908 gp_Pnt ap;
909 gp_Vec ad1u, ad1v;
910 Standard_Real nad1u, nad1v, tolu, tolv;
911
912 theSurface->D1(u, v, ap, ad1u, ad1v);
913 nad1u=ad1u.Magnitude();
914 nad1v=ad1v.Magnitude();
915 if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
916 if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
917 Standard_Real aTolerance = (tolu > tolv) ? tolv : tolu;
918
919 if(aPOnArc.Distance(aPOnLine) > aTolerance) {
920 buildrline = Standard_False;
921 }
922 }
923 } //end for
924
925 if(buildrline) {
926 IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided;
927
928 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
929
930 for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) {
931 const Handle(IntPatch_WLine)& atmpWLine =
932 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j)));
933
934 const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve();
935
936 if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) {
937 trans1 = atmpWLine->TransitionOnS1();
938 }
939 if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) {
940 trans2 = atmpWLine->TransitionOnS2();
941 }
942
943 Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine();
944 Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine();
945
946 for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) {
947 aLineOn2S->Add(Lori->Value(k));
948 }
949 }
950
951 Handle(IntPatch_WLine) emulatedWLine =
952 new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2);
953
954 IntPatch_Point aFirstVertex = P1;
955 IntPatch_Point aLastVertex = P2;
956 aFirstVertex.SetParameter(1);
957 aLastVertex.SetParameter(aLineOn2S->NbPoints());
958
959 emulatedWLine->AddVertex(aFirstVertex);
960 Standard_Integer apointindex = 0;
961
962 for(apointindex = 2; apointindex <= aWLine1->NbVertex(); apointindex++) {
963 IntPatch_Point aPoint = aWLine1->Vertex(apointindex);
964 Standard_Real aTolerance = (aPoint.Tolerance() > P1.Tolerance()) ? aPoint.Tolerance() : P1.Tolerance();
965 if(aPoint.Value().IsEqual(P1.Value(), aTolerance)) {
966 aPoint.SetParameter(1);
967 emulatedWLine->AddVertex(aPoint);
968 }
969 }
970
971 for(apointindex = 1; apointindex < aWLine2->NbVertex(); apointindex++) {
972 IntPatch_Point aPoint = aWLine2->Vertex(apointindex);
973 Standard_Real aTolerance = (aPoint.Tolerance() > P2.Tolerance()) ? aPoint.Tolerance() : P2.Tolerance();
974 if(aPoint.Value().IsEqual(P2.Value(), aTolerance)) {
975 aPoint.SetParameter(aLineOn2S->NbPoints());
976 emulatedWLine->AddVertex(aPoint);
977 }
978 }
979
980 emulatedWLine->AddVertex(aLastVertex);
981
982 anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank);
983
984 break;
985 }
986 }
987 } //end for
988
989 return anRLine;
990}
991
992// ================================================================================================
993// static function: TestWLinesToAnArc
994// purpose: test if possible to replace group of wlines by rline and replace in the sequence slin
995// ================================================================================================
996static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
997 const Handle(Adaptor3d_HSurface)& theSurface1,
998 const Handle(Adaptor3d_TopolTool)& theDomain1,
999 const Handle(Adaptor3d_HSurface)& theSurface2,
1000 const Handle(Adaptor3d_TopolTool)& theDomain2,
1001 const Standard_Real theTolArc) {
1002
1003 IntPatch_SequenceOfLine aSeqOfWLine;
1004 IntPatch_SequenceOfLine aSeqOfRLine;
1005 for(Standard_Integer rank = 1; rank <= 2; rank++) {
1006 for(Standard_Integer i=1; i<=slin.Length(); i++) {
1007 if(slin.Value(i)->ArcType()!=IntPatch_Walking)
1008 continue;
1009 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (slin.Value(i)));
1010 Standard_Integer nbvtx = aWLine->NbVertex();
1011 const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
1012 const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
1013 Standard_Boolean isvertex = Standard_False, wlineWasAppended = Standard_False;
1014
1015
1016 if(rank==1)
1017 isvertex = Vtx1.IsVertexOnS1();
1018 else
1019 isvertex = Vtx1.IsVertexOnS2();
1020
1021 if(isvertex) {
1022 Standard_Boolean appendwline = Standard_True;
1023 if(rank==1) {
1024 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1025 appendwline = Standard_False;
1026 }
1027 }
1028 if(rank==2) {
1029 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1030 appendwline = Standard_False;
1031 }
1032 }
1033 wlineWasAppended = appendwline;
1034 if(appendwline)
1035 aSeqOfWLine.Append(aWLine);
1036 }
1037 else {
1038 if(aSeqOfWLine.Length()==0)
1039 continue;
1040 const Handle(IntPatch_WLine)& aLastWLine =
1041 *((Handle(IntPatch_WLine) *)& (aSeqOfWLine.Value(aSeqOfWLine.Length())));
1042 const IntPatch_Point& aLastPoint = aLastWLine->Vertex(aLastWLine->NbVertex());
1043 Standard_Real aTolerance = (aLastPoint.Tolerance() > Vtx1.Tolerance()) ? aLastPoint.Tolerance() : Vtx1.Tolerance();
1044 if(aLastPoint.Value().IsEqual(Vtx1.Value(), aTolerance)) {
1045 Standard_Boolean appendwline = Standard_True;
1046 if(rank==1) {
1047 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1048 appendwline = Standard_False;
1049 }
1050 }
1051 if(rank==2) {
1052 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1053 appendwline = Standard_False;
1054 }
1055 }
1056 wlineWasAppended = appendwline;
1057 if(appendwline)
1058 aSeqOfWLine.Append(aWLine);
1059 }
1060 else {
1061 aSeqOfWLine.Clear();
1062 }
1063 }
1064
1065 isvertex = Standard_False;
1066 if(rank==1)
1067 isvertex = Vtx2.IsVertexOnS1();
1068 else
1069 isvertex = Vtx2.IsVertexOnS2();
1070
1071 if(wlineWasAppended && isvertex) {
1072 // build rline based on sequence of wlines.
1073 Handle(IntPatch_RLine) anRLine;
1074 if(rank==1) {
1075 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc);
1076 }
1077 else {
1078 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc);
1079 }
1080
1081 if(!anRLine.IsNull()) {
1082 aSeqOfRLine.Append(anRLine);
1083 for(Standard_Integer k=1; k<=aSeqOfWLine.Length(); k++) {
1084 for(Standard_Integer j=1; j<=slin.Length(); j++) {
1085 if(aSeqOfWLine(k)==slin(j)) {
1086 slin.Remove(j);
1087 break;
1088 }
1089 }
1090 }
1091 }
1092 aSeqOfWLine.Clear();
1093 }
1094 }
1095 }
1096
1097 for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) {
1098 slin.Append(aSeqOfRLine.Value(i));
1099 }
1100}
1101// modified by NIZHNY-MKK Mon Apr 2 12:18:34 2001.END
1102
1103//====================================================================================
1104// function: MergeWLinesIfAllSegmentsAlongRestriction
1105//
1106// purpose: If the result of LineConstructor is a set of WLines segments which are
1107// placed along RESTRICTION, we can suppose that this result is not correct:
1108// here we should have a RLine. If it is not possible to construct RLine
1109// we should merge segments of WLines into single WLine equals to the same
1110// RLine.
1111//====================================================================================
1112static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
1113 const Handle(Adaptor3d_HSurface)& theSurface1,
1114 const Handle(Adaptor3d_TopolTool)& theDomain1,
1115 const Handle(Adaptor3d_HSurface)& theSurface2,
1116 const Handle(Adaptor3d_TopolTool)& theDomain2,
1117 const Standard_Real theTolArc)
1118{
1119 Standard_Integer i = 0, rank = 0;
1120 Standard_Real tol = 1.e-9;
1121
1122 // here we check that all segments of WLines placed along restriction
1123 Standard_Integer WLOnRS1 = 0;
1124 Standard_Integer WLOnRS2 = 0;
1125 Standard_Integer NbWLines = 0;
1126 TColgp_SequenceOfPnt sqVertexPoints;
1127
1128 for(rank = 1; rank <= 2; rank++)
1129 {
1130 NbWLines = 0;
1131 for(i = 1; i <= theSlin.Length(); i++)
1132 {
1133 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1134 continue;
1135 NbWLines++;
1136 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1137 Standard_Integer nbvtx = aWLine->NbVertex();
1138 const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
1139 const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
1140 if( rank==1 )
1141 {
1142 sqVertexPoints.Append(Vtx1.Value());
1143 sqVertexPoints.Append(Vtx2.Value());
1144 if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) )
1145 WLOnRS1++;
1146 }
1147 else
1148 {
1149 if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) )
1150 WLOnRS2++;
1151 }
1152 }
1153 if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break;
1154 }
1155
1156 Standard_Integer WLineRank = 0; // not possible to merge WLines
1157
1158 if( WLOnRS1 == NbWLines )
1159 WLineRank = 1; // create merged WLine based on arc of S1
1160 else if( WLOnRS2 == NbWLines )
1161 WLineRank = 2; // create merged WLine based on arc of S2
1162 else
1163 return;
1164
1165 // avoid closed (degenerated) edges
1166 if( sqVertexPoints.Length() <= 2 )
1167 return;
1168 if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) )
1169 return;
1170
1171 Standard_Real TolVrtx = 1.e-5;
1172 Standard_Integer testPointIndex = ( sqVertexPoints.Length() > 3 ) ? ((Standard_Integer) sqVertexPoints.Length() / 2) : 2;
1173 gp_Pnt testPoint = sqVertexPoints.Value( testPointIndex );
1174 Standard_Real Fp = 0., Lp = 0.;
1175
1176
a4d5c9ab 1177 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1178 //
1179 Standard_Integer arcnumber = (WLineRank == 1) ?
1180 GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp) :
1181 GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1182 //
1183 if (arcnumber == 0) {
1184 return;
1185 }
1186 //
1187 Handle(IntPatch_WLine) anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1188 if (!anWLine.IsNull()) {
1189 theSlin.Clear();
1190 theSlin.Append(anWLine);
57c28b61 1191#ifdef OCCT_DEBUG
04232180 1192 std::cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction "
1193 << ((WLineRank == 1) ? "S1" : "S2") << " to WLine***" << std::endl;
7fd59977 1194#endif
a4d5c9ab 1195 }
7fd59977 1196}
1197
1198//=========================================================================================
1199// function: GetArc
1200//
1201// purpose: Define arc on (OBJ) surface which all WLine segments are placed along.
1202// Check states of points in the gaps between segments on (TOOL). If those states
1203// are IN or ON return the LineOn2S based on points3D were given from detected arc.
1204// Returns 0 if it is not possible to create merged WLine.
1205//========================================================================================
1206static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
1207 const Standard_Integer& theRankS,
1208 const Handle(Adaptor3d_HSurface)& theSurfaceObj,
1209 const Handle(Adaptor3d_TopolTool)& theDomainObj,
1210 const Handle(Adaptor3d_HSurface)& theSurfaceTool,
1211 const gp_Pnt& theTestPoint,
1212 Standard_Real& theVrtxTol,
1213 Handle(IntSurf_LineOn2S)& theLineOn2S,
1214 Standard_Real& theFirst,
1215 Standard_Real& theLast)
1216{
1217 // 1. find number of arc (edge) on which the WLine segments are placed.
1218
1219 Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.;
1220 Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0;
1221 theFirst = 0.;
1222 theLast = 0.;
1223
1224 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1225 {
1226 CurArc++;
1227 Standard_Address anEAddress = theDomainObj->Edge();
1228
1229 if( anEAddress == NULL )
1230 continue;
1231
1232 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1233 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1234 if ( aCEdge.IsNull() ) // e.g. degenerated edge, see OCC21770
1235 continue;
1236 GeomAdaptor_Curve CE;
1237 CE.Load(aCEdge);
1238 Extrema_ExtPC epc(theTestPoint, CE, 1.e-7);
1239
1240 if( epc.IsDone() )
1241 {
1242 for( i = 1; i <= epc.NbExt(); i++ )
1243 {
1244 if( epc.SquareDistance( i ) < MinDistance2 )
1245 {
1246 MinDistance2 = epc.SquareDistance( i );
1247 ArcNumber = CurArc;
1248 }
1249 }
1250 }
1251 }
1252
1253 if( ArcNumber == 0 )
1254 return 0;
1255
1256 // 2. load parameters of founded edge and its arc.
1257 CurArc = 0;
1258 TColgp_SequenceOfPnt PointsFromArc;
1259 Handle(Adaptor2d_HCurve2d) arc = NULL;
1260 Standard_Real tol = 1.e-7;
1261 TColStd_SequenceOfReal WLVertexParameters;
1262 Standard_Boolean classifyOK = Standard_True;
1263 Standard_Real CheckTol = 1.e-5;
1264
1265 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1266 {
1267 CurArc++;
1268 if( CurArc != ArcNumber )
1269 continue;
1270
1271 arc = theDomainObj->Value();
1272
1273 for(i = 1; i <= theSlin.Length(); i++)
1274 {
1275 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1276 continue;
1277
1278 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1279
1280 Standard_Integer nbpnts = aWLine->NbPnts();
1281 const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1);
1282 const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts);
1283
1284 Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.;
1285
1286 if(theRankS == 1)
1287 {
1288 POn2S_F.ParametersOnS1(Upf, Vpf);
1289 POn2S_L.ParametersOnS1(Upl, Vpl);
1290 }
1291 else
1292 {
1293 POn2S_F.ParametersOnS2(Upf, Vpf);
1294 POn2S_L.ParametersOnS2(Upl, Vpl);
1295 }
1296
1297 gp_Pnt2d aPOnLine_F(Upf, Vpf);
1298 gp_Pnt2d aPOnLine_L(Upl, Vpl);
1299
1300 Standard_Real par_F = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_F, tol);
1301 Standard_Real par_L = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_L, tol);
1302
1303 WLVertexParameters.Append(par_F);
1304 WLVertexParameters.Append(par_L);
1305 }
1306
1307 for(i = 1; i <= WLVertexParameters.Length(); i++)
1308 {
1309 for(j = i; j <= WLVertexParameters.Length(); j++)
1310 {
1311 if(j == i)
1312 continue;
1313
1314 if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j))
1315 {
1316 Standard_Real pol = WLVertexParameters.Value(i);
1317 WLVertexParameters.SetValue(i, WLVertexParameters.Value(j));
1318 WLVertexParameters.SetValue(j, pol);
1319 }
1320 }
1321 }
1322
1323 Standard_Address anEAddress = theDomainObj->Edge();
1324 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1325 TopoDS_Vertex V1, V2;
1326 TopExp::Vertices(*anE,V1,V2);
1327 Standard_Real MaxVertexTol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
1328 theVrtxTol = MaxVertexTol;
1329 Standard_Real EdgeTol = BRep_Tool::Tolerance(*anE);
1330 CheckTol = Max(MaxVertexTol, EdgeTol);
1331 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1332 // classification gaps
1333 // a. min - first
1334 if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol))
1335 {
1336 Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.;
1337 gp_Pnt point;
1338 aCEdge->D0(param, point);
1339 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1340 {
1341 classifyOK = Standard_False;
1342 break;
1343 }
1344 }
1345 // b. max - last
1346 if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol))
1347 {
1348 Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.;
1349 gp_Pnt point;
1350 aCEdge->D0(param, point);
1351 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1352 {
1353 classifyOK = Standard_False;
1354 break;
1355 }
1356 }
1357 // c. all middle gaps
53e7fede 1358 Standard_Integer NbChkPnts = WLVertexParameters.Length() / 2 - 1;
7fd59977 1359 for(i = 1; i <= NbChkPnts; i++)
1360 {
1361 if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol))
1362 {
1363 Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.;
1364 gp_Pnt point;
1365 aCEdge->D0(param, point);
1366 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1367 {
1368 classifyOK = Standard_False;
1369 break;
1370 }
1371 }
1372 }
1373
1374 if( !classifyOK )
1375 break;
1376
1377 // if classification gaps OK, fill sequence by the points from arc (edge)
1378 Standard_Real ParamFirst = WLVertexParameters.Value(1);
1379 Standard_Real ParamLast = WLVertexParameters.Value(WLVertexParameters.Length());
1380 Standard_Real dParam = Abs(ParamLast - ParamFirst) / 100.;
1381 Standard_Real cParam = ParamFirst;
1382 for( i = 0; i < 100; i++ )
1383 {
1384 if( i == 99 )
1385 cParam = ParamLast;
1386
1387 gp_Pnt cPnt;
1388 aCEdge->D0(cParam, cPnt);
1389 PointsFromArc.Append(cPnt);
1390 cParam += dParam;
1391 }
1392 theFirst = ParamFirst;
1393 theLast = ParamLast;
1394
1395 }
1396
1397 if( !classifyOK )
1398 return 0;
1399
1400 // create IntSurf_LineOn2S from points < PointsFromArc >
1401 for( i = 1; i <= PointsFromArc.Length(); i++ )
1402 {
1403 Extrema_POnSurf pOnS1;
1404 Extrema_POnSurf pOnS2;
1405 gp_Pnt arcpoint = PointsFromArc.Value( i );
1406 Standard_Boolean isOnS1 = GetPointOn2S( arcpoint, theSurfaceObj->Surface(), CheckTol, pOnS1 );
1407 Standard_Boolean isOnS2 = GetPointOn2S( arcpoint, theSurfaceTool->Surface(), CheckTol, pOnS2 );
1408 if( isOnS1 && isOnS2 )
1409 {
1410 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1411 pOnS1.Parameter(u1, v1);
1412 pOnS2.Parameter(u2, v2);
1413 IntSurf_PntOn2S pOn2S;
1414 pOn2S.SetValue(arcpoint, u1, v1, u2, v2 );
1415 theLineOn2S->Add( pOn2S );
1416 }
1417 }
1418
1419 return ArcNumber;
1420}
1421
1422//=========================================================================================
1423// function: IsPointOK
1424//
1425// purpose: returns the state of testPoint on OTHER face.
1426//========================================================================================
1427static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
1428 const Adaptor3d_Surface& theTestSurface,
1429 const Standard_Real& theTol)
1430{
1431 Standard_Boolean result = Standard_False;
1432 Standard_Real ExtTol = theTol;//1.e-7;
1433 Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1434 if( extPS.IsDone() && extPS.NbExt() > 0 )
1435 {
96a95605 1436 Standard_Integer i = 0;
7fd59977 1437 Standard_Real MinDist2 = 1.e+200;
1438 for(i = 1; i <= extPS.NbExt(); i++)
1439 {
1440 if( extPS.SquareDistance(i) < MinDist2 )
1441 {
7fd59977 1442 MinDist2 = extPS.SquareDistance(i);
1443 }
1444 }
1445 if( MinDist2 <= theTol * theTol )
1446 result = Standard_True;
1447 }
1448 return result;
1449}
1450
1451//=========================================================================================
1452// function: GetPointOn2S
1453//
1454// purpose: check state of testPoint and returns result point if state is OK.
1455//========================================================================================
1456static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
1457 const Adaptor3d_Surface& theTestSurface,
1458 const Standard_Real& theTol,
1459 Extrema_POnSurf& theResultPoint)
1460{
1461 Standard_Boolean result = Standard_False;
1462 Standard_Real ExtTol = theTol;//1.e-7;
1463 Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1464 if( extPS.IsDone() && extPS.NbExt() > 0 )
1465 {
1466 Standard_Integer i = 0, minext = 1;
1467 Standard_Real MinDist2 = 1.e+200;
1468 for(i = 1; i <= extPS.NbExt(); i++)
1469 {
1470 if( extPS.SquareDistance(i) < MinDist2 )
1471 {
1472 minext = i;
1473 MinDist2 = extPS.SquareDistance(i);
1474 }
1475 }
1476 if( MinDist2 <= theTol * theTol )
1477 {
1478 result = Standard_True;
1479 theResultPoint = extPS.Point(minext);
1480 }
1481 }
1482 return result;
1483}
1484
1485//=========================================================================================
1486// function: GetMergedWLineOnRestriction
1487//
1488// purpose: merge sequence of WLines all placed along restriction if the conditions of
1489// merging are OK.
1490//========================================================================================
1491static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
1492 const Standard_Real& theVrtxTol,
1493 const Handle(IntSurf_LineOn2S)& theLineOn2S)
1494{
a4d5c9ab 1495 Handle(IntPatch_WLine) mWLine;
1496 if (theLineOn2S->NbPoints() == 0) {
1497 return mWLine;
1498 }
1499 //
7fd59977 1500 IntSurf_TypeTrans trans1 = IntSurf_Undecided;
1501 IntSurf_TypeTrans trans2 = IntSurf_Undecided;
1502 Standard_Integer i = 0;
1503
1504 for(i = 1; i <= theSlin.Length(); i++)
1505 {
1506 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1507 continue;
1508
1509 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1510
1511 if( aWLine->TransitionOnS1() != IntSurf_Undecided && aWLine->TransitionOnS1() != IntSurf_Touch )
1512 trans1 = aWLine->TransitionOnS1();
1513 if( aWLine->TransitionOnS2() != IntSurf_Undecided && aWLine->TransitionOnS2() != IntSurf_Touch )
1514 trans2 = aWLine->TransitionOnS2();
1515 }
1516
a4d5c9ab 1517 mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2);
7fd59977 1518
1519 Standard_Integer NbPnts = mWLine->NbPnts();
1520 IntPatch_Point aFirstVertex, aLastVertex;
1521
1522 aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False);
1523 aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False);
1524
1525 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1526
1527 mWLine->Point(1).Parameters(u1, v1, u2, v2);
1528 aFirstVertex.SetParameters(u1, v1, u2, v2);
1529
1530 mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2);
1531 aLastVertex.SetParameters(u1, v1, u2, v2);
1532
1533 aFirstVertex.SetParameter(1);
1534 aLastVertex.SetParameter(theLineOn2S->NbPoints());
1535
1536 mWLine->AddVertex(aFirstVertex);
1537 mWLine->AddVertex(aLastVertex);
1538
1539 mWLine->ComputeVertexParameters(theVrtxTol);
1540
1541 return mWLine;
1542}