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