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