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