1 // Created on: 1993-11-18
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box.hxx>
19 #include <BRepAdaptor_HSurface.hxx>
20 #include <BRepTopAdaptor_TopolTool.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopOpeBRep_FacesIntersector.hxx>
23 #include <TopOpeBRep_LineInter.hxx>
26 #include <TopOpeBRep_DRAW.hxx>
29 #include <IntPatch_LineConstructor.hxx>
30 #include <TopOpeBRep_TypeLineCurve.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <BRep_Tool.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <TopOpeBRepTool_ShapeTool.hxx>
37 #include <Precision.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Standard_ProgramError.hxx>
40 #include <TCollection_AsciiString.hxx>
41 #include <Standard_CString.hxx>
42 #include <BRepTools.hxx>
43 #include <TopOpeBRepTool_tol.hxx>
45 Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7;
49 extern Standard_Boolean TopOpeBRep_GettraceFI();
50 extern Standard_Boolean TopOpeBRep_GettraceFITOL();
51 extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
53 Standard_Integer SAVFFi1 = 0;
54 Standard_Integer SAVFFi2 = 0;
55 static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2)
57 TCollection_AsciiString an1("SAVA");if (SAVFFi1) an1=an1+SAVFFi1;
58 TCollection_AsciiString an2("SAVB");if (SAVFFi2) an2=an2+SAVFFi2;
59 Standard_CString n1=an1.ToCString();Standard_CString n2=an2.ToCString();
61 cout<<"FaceIntersector : set "<<n1<<","<<n2<<endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2);
63 cout<<"FaceIntersector : write "<<n1<<","<<n2<<endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2);
66 extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
67 #include <TopOpeBRepTool_KRO.hxx>
68 Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face");
73 // NYI : IntPatch_Intersection : TolArc,TolTang exact definition
77 // modified by NIZHNY-MKK Mon Apr 2 12:14:32 2001.BEGIN
78 #include <IntPatch_WLine.hxx>
79 #include <IntPatch_RLine.hxx>
80 #include <IntPatch_Point.hxx>
81 #include <Adaptor3d_HSurface.hxx>
82 #include <Adaptor3d_TopolTool.hxx>
83 #include <Adaptor3d_HVertex.hxx>
84 #include <Adaptor2d_HCurve2d.hxx>
85 #include <Geom2dInt_TheProjPCurOfGInter.hxx>
87 static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
88 const Standard_Integer theRank,
89 const Handle(Adaptor3d_HSurface)& theSurface,
90 const Handle(Adaptor3d_TopolTool)& theDomain,
91 const Standard_Real theTolArc);
94 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
95 const Handle(Adaptor2d_HCurve2d)& theArc,
96 const Standard_Integer theRank);
99 Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
100 const Standard_Integer theRank,
101 const Handle(Adaptor3d_HSurface)& theSurface,
102 const Handle(Adaptor3d_TopolTool)& theDomain,
103 const Standard_Real theTolArc);
105 static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
106 const Handle(Adaptor3d_HSurface)& theSurface1,
107 const Handle(Adaptor3d_TopolTool)& theDomain1,
108 const Handle(Adaptor3d_HSurface)& theSurface2,
109 const Handle(Adaptor3d_TopolTool)& theDomain2,
110 const Standard_Real theTolArc);
111 // modified by NIZHNY-MKK Mon Apr 2 12:14:38 2001.END
113 // modified by NIZHNY-OFV Fri Mar 29 12:37:21 2002.BEGIN
114 #include <TColgp_SequenceOfPnt.hxx>
115 #include <TopExp.hxx>
116 #include <TColStd_SequenceOfReal.hxx>
117 #include <Extrema_ExtPS.hxx>
118 #include <Extrema_ExtPC.hxx>
119 #include <Extrema_POnSurf.hxx>
120 #include <GeomAdaptor_Curve.hxx>
121 static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
122 const Handle(Adaptor3d_HSurface)& theSurface1,
123 const Handle(Adaptor3d_TopolTool)& theDomain1,
124 const Handle(Adaptor3d_HSurface)& theSurface2,
125 const Handle(Adaptor3d_TopolTool)& theDomain2,
126 const Standard_Real theTolArc);
127 //------------------------------------------------------------------------------------------------
128 static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
129 const Standard_Integer& theRankS,
130 const Handle(Adaptor3d_HSurface)& theSurfaceObj,
131 const Handle(Adaptor3d_TopolTool)& theDomainObj,
132 const Handle(Adaptor3d_HSurface)& theSurfaceTool,
133 const gp_Pnt& theTestPoint,
134 Standard_Real& theVrtxTol,
135 Handle(IntSurf_LineOn2S)& theLineOn2S,
136 Standard_Real& theFirst,
137 Standard_Real& theLast);
138 //------------------------------------------------------------------------------------------------
139 static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
140 const Adaptor3d_Surface& theTestSurface,
141 const Standard_Real& theTol);
142 //-------------------------------------------------------------------------------------------------
143 static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
144 const Adaptor3d_Surface& theTestSurface,
145 const Standard_Real& theTol,
146 Extrema_POnSurf& theResultPoint);
147 //-------------------------------------------------------------------------------------------------------------------------
148 static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
149 const Standard_Real& theVrtxTol,
150 const Handle(IntSurf_LineOn2S)& theLineOn2S);
151 //---------------------------------------------------------------------------------------------------------------------------
152 // modified by NIZHNY-OFV Fri Mar 29 12:41:02 2002.END
154 //=======================================================================
155 //function : TopOpeBRep_FacesIntersector
157 //=======================================================================
158 TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector ()
161 myTol1 = myTol2 = Precision::Confusion();
162 myForceTolerances = Standard_False;
163 mySurface1 = new BRepAdaptor_HSurface();
164 mySurface2 = new BRepAdaptor_HSurface();
165 myDomain1 = new BRepTopAdaptor_TopolTool();
166 myDomain2 = new BRepTopAdaptor_TopolTool();
169 //=======================================================================
172 //=======================================================================
173 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2,
174 const Bnd_Box& B1,const Bnd_Box& B2)
177 if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2));
181 if (!myForceTolerances) ShapeTolerances(F1,F2);
183 myFace1 = TopoDS::Face(F1); myFace1.Orientation(TopAbs_FORWARD);
184 myFace2 = TopoDS::Face(F2); myFace2.Orientation(TopAbs_FORWARD);
185 BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1);
186 BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2);
187 mySurfaceType1 = S1.GetType();
188 mySurfaceType2 = S2.GetType();
189 const Handle(Adaptor3d_HSurface)& aSurf1 = mySurface1; // to avoid ambiguity
190 myDomain1->Initialize(aSurf1);
191 const Handle(Adaptor3d_HSurface)& aSurf2 = mySurface2; // to avoid ambiguity
192 myDomain2->Initialize(aSurf2);
195 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start();
198 Standard_Real Deflection=0.01,MaxUV=0.01;
199 if (!myForceTolerances) {
200 FTOL_FaceTolerances3d(B1,B2,myFace1,myFace2,S1,S2,
201 myTol1,myTol2,Deflection,MaxUV);
202 myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1;
203 myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2;
206 Standard_Real tol1 = myTol1;
207 Standard_Real tol2 = myTol2;
208 GLOBAL_tolFF = Max(tol1,tol2);
211 if (TopOpeBRep_GettraceFITOL()) {
212 cout<<"FacesIntersector : Perform tol1 = "<<tol1<<endl;
213 cout<<" tol2 = "<<tol2<<endl;
214 cout<<" defl = "<<Deflection<<" MaxUV = "<<MaxUV<<endl;
218 myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection);
219 myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,
220 myTol1,myTol2,Standard_True,Standard_True);
223 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop();
226 //xpu180998 : cto900Q1
227 Standard_Boolean done = myIntersector.IsDone();
231 myIntersectionDone = Standard_True;
233 // mySurfacesSameOriented : a mettre dans IntPatch NYI
234 if ( SameDomain() ) {
235 mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
238 // build the map of edges found as RESTRICTION
239 for (InitLine(); MoreLine(); NextLine()) {
240 TopOpeBRep_LineInter& L = CurrentLine();
241 if (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) {
242 const TopoDS_Shape& E = L.Arc();
243 myEdgeRestrictionMap.Add(E);
248 if (TopOpeBRep_GettraceFI()) cout<<"Perform : isempty "<<IsEmpty()<<endl;
252 //=======================================================================
255 //=======================================================================
257 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
260 Perform(F1,F2,B1,B2);
264 //=======================================================================
267 //=======================================================================
269 Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty ()
271 if ( ! myIntersectionDone ) return Standard_False;
272 Standard_Boolean done = myIntersector.IsDone();
273 Standard_Boolean empty = myIntersector.IsEmpty();
274 if ( !done || empty ) return Standard_True;
276 // ElemIntersector is done and is not empty
277 // returns True if at least one VPoint is found
278 empty = Standard_True;
279 for ( InitLine(); MoreLine(); NextLine() ) {
280 empty = (CurrentLine().NbVPoint() == 0);
281 if ( ! empty ) break;
287 //=======================================================================
290 //=======================================================================
292 Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const
294 return myIntersectionDone;
297 //=======================================================================
298 //function : SameDomain
300 //=======================================================================
302 Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const
304 if (!myIntersectionDone)
305 Standard_ProgramError::Raise("FacesIntersector : bad SameDomain");
307 Standard_Boolean sd = myIntersector.TangentFaces();
309 //Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane);
311 // if (!plpl) return Standard_False;
316 //=======================================================================
319 //=======================================================================
321 const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face
322 (const Standard_Integer Index) const
324 if ( Index == 1 ) return myFace1;
325 else if ( Index == 2 ) return myFace2;
326 else Standard_ProgramError::Raise("TopOpeBRep_FacesIntersector::Face");
332 //=======================================================================
333 //function : SurfacesSameOriented
335 //=======================================================================
337 Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const
339 if ( SameDomain() ) {
340 return mySurfacesSameOriented;
342 Standard_ProgramError::Raise("FacesIntersector : bad SurfacesSameOriented");
343 return Standard_False;
346 //=======================================================================
347 //function : IsRestriction
349 //=======================================================================
351 Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction
352 (const TopoDS_Shape& E) const
354 Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E);
358 //=======================================================================
359 //function : Restrictions
361 //=======================================================================
363 const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions
366 return myEdgeRestrictionMap;
369 //=======================================================================
370 //function : PrepareLines
372 //=======================================================================
374 void TopOpeBRep_FacesIntersector::PrepareLines()
377 Standard_Integer n = myIntersector.NbLines();
378 myHAL = new TopOpeBRep_HArray1OfLineInter(0,n);
379 BRepAdaptor_Surface& S1 = *((BRepAdaptor_Surface*)&(mySurface1->Surface()));
380 BRepAdaptor_Surface& S2 = *((BRepAdaptor_Surface*)&(mySurface2->Surface()));
382 // modified by NIZHNY-MKK Mon Apr 2 12:14:58 2001.BEGIN
385 // modified by NIZHNY-MKK Mon Apr 2 12:15:09 2001.END
387 Standard_Boolean newV = Standard_True;
390 /*for ( Standard_Integer i=1; i<=n; i++) {
391 TopOpeBRep_LineInter& LI = myHAL->ChangeValue(i);
392 const Handle(IntPatch_Line)& L = myIntersector.Line(i);
401 // modified by NIZHNY-MKK Mon Apr 2 12:16:04 2001
402 IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines;
405 // Standard_Integer nbl=0;
406 IntPatch_LineConstructor **Ptr =
407 (IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *));
409 Ptr[i-1]=new IntPatch_LineConstructor(2);
410 Ptr[i-1]->Perform(myIntersector.SequenceOfLine(),
411 myIntersector.Line(i),
412 mySurface1,myDomain1,
413 mySurface2,myDomain2,
415 // modified by NIZHNY-MKK Mon Apr 2 12:16:26 2001.BEGIN
417 for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) {
418 aSeqOfLines.Append(Ptr[i-1]->Line(k));
421 TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
423 for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) {
424 aSeqOfResultLines.Append(aSeqOfLines.Value(j));
427 // nbl+=Ptr[i-1]->NbLines();
428 // modified by NIZHNY-MKK Mon Apr 2 12:16:31 2001.END
431 // modified by NIZHNY-MKK Mon Apr 2 12:17:22 2001.BEGIN
432 // myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl);
433 myLineNb = aSeqOfResultLines.Length();
435 //Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
436 MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
437 myLineNb = aSeqOfResultLines.Length();
441 myHAL = new TopOpeBRep_HArray1OfLineInter(1, myLineNb);
442 for(Standard_Integer index = 1; index <= myLineNb; index++) {
443 TopOpeBRep_LineInter& LI = myHAL->ChangeValue(index);
444 const Handle(IntPatch_Line)& L = aSeqOfResultLines.Value(index);
451 // for(i=1;i<=n;i++) {
452 // for(Standard_Integer k=1;k<=Ptr[i-1]->NbLines();k++) {
453 // TopOpeBRep_LineInter& LI = myHAL->ChangeValue(nbl);
454 // const Handle(IntPatch_Line)& L = Ptr[i-1]->Line(k);
455 // LI.SetLine(L,S1,S2);
462 // modified by NIZHNY-MKK Mon Apr 2 12:17:57 2001.END
467 //=======================================================================
470 //=======================================================================
472 Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines()
477 //=======================================================================
480 //=======================================================================
482 Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const
487 //=======================================================================
488 //function : InitLine
490 //=======================================================================
492 void TopOpeBRep_FacesIntersector::InitLine()
498 //=======================================================================
499 //function : FindLine
501 //=======================================================================
503 void TopOpeBRep_FacesIntersector::FindLine()
505 myLineFound = Standard_False;
506 if ( ! myIntersectionDone ) return;
508 while (myLineIndex <= myLineNb) {
509 const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex);
510 myLineFound = L.OK();
511 if (myLineFound) break;
516 //=======================================================================
517 //function : MoreLine
519 //=======================================================================
521 Standard_Boolean TopOpeBRep_FacesIntersector::MoreLine()const
527 //=======================================================================
528 //function : NextLine
530 //=======================================================================
532 void TopOpeBRep_FacesIntersector::NextLine()
538 //=======================================================================
539 //function : CurrentLine
541 //=======================================================================
543 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine()
545 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex);
550 //=======================================================================
551 //function : CurrentLineIndex
553 //=======================================================================
555 Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const
560 //=======================================================================
563 //=======================================================================
565 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL)
567 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL);
571 //=======================================================================
572 //function : ResetIntersection
574 //=======================================================================
576 void TopOpeBRep_FacesIntersector::ResetIntersection()
578 myIntersectionDone = Standard_False;
581 myEdgeRestrictionMap.Clear();
582 myLineFound = Standard_False;
586 //=======================================================================
587 //function : ForceTolerances
589 //=======================================================================
591 void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1,
592 const Standard_Real Tol2)
596 myForceTolerances = Standard_True;
598 if (TopOpeBRep_GettraceFITOL())
599 cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
603 //=======================================================================
604 //function : GetTolerances
606 //=======================================================================
608 void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1,
609 Standard_Real& Tol2) const
615 //=======================================================================
616 //function : ShapeTolerances
617 //purpose : (private)
618 //=======================================================================
621 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1,
622 const TopoDS_Shape& S2)
624 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& ,
625 const TopoDS_Shape& )
628 // myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
629 myTol1 = Precision::Confusion();
631 myForceTolerances = Standard_False;
633 if (TopOpeBRep_GettraceFITOL()) {
634 cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout);
635 cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout);
636 cout<<" : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
641 //=======================================================================
642 //function : ToleranceMax
643 //purpose : (private)
644 //=======================================================================
646 Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax
647 (const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
649 TopExp_Explorer e(S,T);
650 if ( ! e.More() ) return Precision::Intersection();
652 Standard_Real tol = RealFirst();
653 for (; e.More(); e.Next())
654 tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
660 // modified by NIZHNY-MKK Mon Apr 2 12:18:30 2001.BEGIN
661 // ================================================================================================
662 // static function: TestWLineAlongRestriction
664 // ================================================================================================
665 static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine,
666 const Standard_Integer theRank,
667 const Handle(Adaptor3d_HSurface)& theSurface,
668 const Handle(Adaptor3d_TopolTool)& theDomain,
669 const Standard_Real theTolArc) {
671 Standard_Boolean result = Standard_False;
672 Standard_Integer NbPnts = theWLine->NbPnts();
673 Standard_Integer along = 0;
675 for(Standard_Integer i=1; i<=NbPnts; i++) {
676 const IntSurf_PntOn2S& Pmid = theWLine->Point(i);
677 Standard_Real u=0., v=0.;
678 if(theRank==1) Pmid.ParametersOnS1(u, v);
679 else Pmid.ParametersOnS2(u, v);
680 //------------------------------------------
683 //Standard_Real nad1u, nad1v, tolu, tolv;
685 theSurface->D1(u, v, ap, ad1u, ad1v);
686 //nad1u=ad1u.Magnitude();
687 //nad1v=ad1v.Magnitude();
688 //if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
689 //if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
690 //if(tolu>tolv) tolu=tolv;
691 //------------------------------------------
693 //if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) {
697 if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++;
698 //if(along!=i) break;
700 if(along==NbPnts) result = Standard_True;
705 // ================================================================================================
706 // static function: BuildRLineBasedOnWLine
708 // ================================================================================================
710 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
711 const Handle(Adaptor2d_HCurve2d)& theArc,
712 const Standard_Integer theRank) {
713 Handle(IntPatch_RLine) anRLine;
715 if((theRank != 1) && (theRank != 2))
719 Standard_Real u=0., v=0.;
720 Standard_Integer nbvtx = theWLine->NbVertex();
721 const IntPatch_Point& Vtx1 = theWLine->Vertex(1);
722 const IntPatch_Point& Vtx2 = theWLine->Vertex(nbvtx);
725 Vtx1.ParametersOnS1(u, v);
728 Vtx1.ParametersOnS2(u, v);
731 aPOnLine = gp_Pnt2d(u, v);
732 Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
735 Vtx2.ParametersOnS1(u, v);
738 Vtx2.ParametersOnS2(u, v);
740 aPOnLine = gp_Pnt2d(u, v);
741 Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
743 Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance();
745 if(Abs(par1 - par2) < theArc->Resolution(tol))
748 Standard_Boolean IsOnFirst = (theRank == 1);
750 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
751 const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve();
752 IntSurf_Transition TransitionUndecided;
754 anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2());
757 anRLine->SetArcOnS1(theArc);
760 anRLine->SetArcOnS2(theArc);
763 Standard_Integer k = 0;
766 for(k = 1; k <= Lori->NbPoints(); k++) {
767 aLineOn2S->Add(Lori->Value(k));
769 anRLine->Add(aLineOn2S);
770 IntPatch_Point VtxFirst = Vtx1;
772 VtxFirst.SetArc(IsOnFirst, //-- On First
776 TransitionUndecided);
777 VtxFirst.SetParameter(par1);
778 anRLine->AddVertex(VtxFirst);
780 for(k = 2; k < nbvtx; k++) {
781 IntPatch_Point Vtx = theWLine->Vertex(k);
783 Vtx.ParametersOnS1(u, v);
786 Vtx.ParametersOnS2(u, v);
788 gp_Pnt2d atmpPoint(u, v);
789 Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
790 Vtx.SetParameter(apar);
791 anRLine->AddVertex(Vtx);
794 IntPatch_Point VtxLast = Vtx2;
795 VtxLast.SetArc(IsOnFirst, //-- On First
799 TransitionUndecided);
800 VtxLast.SetParameter(par2);
801 anRLine->AddVertex(VtxLast);
802 anRLine->SetFirstPoint(1);
803 anRLine->SetLastPoint(nbvtx);
804 anRLine->ComputeVertexParameters(Precision::Confusion());
808 for(k = Lori->NbPoints(); k >= 1; k--) {
809 aLineOn2S->Add(Lori->Value(k));
811 anRLine->Add(aLineOn2S);
813 IntPatch_Point VtxFirst = Vtx2;
814 VtxFirst.SetArc(IsOnFirst, //-- On First
818 TransitionUndecided);
819 VtxFirst.SetParameter(par2);
820 anRLine->AddVertex(VtxFirst);
822 for(k = nbvtx - 1; k >= 2; k--) {
823 IntPatch_Point Vtx = theWLine->Vertex(k);
824 Vtx.ReverseTransition();
826 Vtx.ParametersOnS1(u, v);
829 Vtx.ParametersOnS2(u, v);
831 gp_Pnt2d atmpPoint(u, v);
832 Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7);
833 Vtx.SetParameter(apar);
834 anRLine->AddVertex(Vtx);
836 IntPatch_Point VtxLast = Vtx1;
837 VtxLast.SetArc(IsOnFirst, //-- On First
841 TransitionUndecided);
842 VtxLast.SetParameter(par1);
843 anRLine->AddVertex(VtxLast);
844 anRLine->SetFirstPoint(1);
845 anRLine->SetLastPoint(nbvtx);
846 anRLine->ComputeVertexParameters(Precision::Confusion());
852 // ================================================================================================
853 // static function: BuildRLine
854 // purpose: build rline based on group of wlines
855 // return null handle if it is not possible to build rline
856 // ================================================================================================
858 Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine,
859 const Standard_Integer theRank,
860 const Handle(Adaptor3d_HSurface)& theSurface,
861 const Handle(Adaptor3d_TopolTool)& theDomain,
862 const Standard_Real theTolArc) {
863 Handle(IntPatch_RLine) anRLine;
864 const Handle(IntPatch_WLine)& aWLine1 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(1)));
865 const Handle(IntPatch_WLine)& aWLine2 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(theSeqOfWLine.Length())));
866 const IntPatch_Point& P1 = aWLine1->Vertex(1);
867 const IntPatch_Point& P2 = aWLine2->Vertex(aWLine2->NbVertex());
868 const Handle(Adaptor3d_HVertex)& aV1 = (theRank==1) ? P1.VertexOnS1() : P1.VertexOnS2();
869 const Handle(Adaptor3d_HVertex)& aV2 = (theRank==1) ? P2.VertexOnS1() : P2.VertexOnS2();
871 // avoid closed and degenerated edges
875 for(theDomain->Init(); theDomain->More(); theDomain->Next()) {
876 theDomain->Initialize(theDomain->Value());
877 Standard_Boolean foundVertex1 = Standard_False;
878 Standard_Boolean foundVertex2 = Standard_False;
880 for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) {
882 if(!foundVertex1 && aV1->IsSame(theDomain->Vertex()))
883 foundVertex1 = Standard_True;
884 if(!foundVertex2 && aV2->IsSame(theDomain->Vertex()))
885 foundVertex2 = Standard_True;
888 if(foundVertex1 && foundVertex2) {
889 Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0);
891 for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) {
892 const Handle(IntPatch_WLine)& aWLine =
893 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i)));
895 Standard_Integer indexpnt = aWLine->NbPnts()/2;
897 buildrline = Standard_False;
899 Standard_Real u = RealLast(), v = RealLast();
900 const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt);
902 POn2S.ParametersOnS1(u, v);
905 POn2S.ParametersOnS2(u, v);
907 gp_Pnt2d aPOnArc, aPOnLine(u, v);
908 Standard_Real par = Geom2dInt_TheProjPCurOfGInter::FindParameter(theDomain->Value()->Curve2d(), aPOnLine, 1e-7);
909 aPOnArc = theDomain->Value()->Value(par);
912 Standard_Real nad1u, nad1v, tolu, tolv;
914 theSurface->D1(u, v, ap, ad1u, ad1v);
915 nad1u=ad1u.Magnitude();
916 nad1v=ad1v.Magnitude();
917 if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1;
918 if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1;
919 Standard_Real aTolerance = (tolu > tolv) ? tolv : tolu;
921 if(aPOnArc.Distance(aPOnLine) > aTolerance) {
922 buildrline = Standard_False;
928 IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided;
930 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
932 for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) {
933 const Handle(IntPatch_WLine)& atmpWLine =
934 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j)));
936 const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve();
938 if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) {
939 trans1 = atmpWLine->TransitionOnS1();
941 if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) {
942 trans2 = atmpWLine->TransitionOnS2();
945 Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine();
946 Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine();
948 for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) {
949 aLineOn2S->Add(Lori->Value(k));
953 Handle(IntPatch_WLine) emulatedWLine =
954 new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2);
956 IntPatch_Point aFirstVertex = P1;
957 IntPatch_Point aLastVertex = P2;
958 aFirstVertex.SetParameter(1);
959 aLastVertex.SetParameter(aLineOn2S->NbPoints());
961 emulatedWLine->AddVertex(aFirstVertex);
962 Standard_Integer apointindex = 0;
964 for(apointindex = 2; apointindex <= aWLine1->NbVertex(); apointindex++) {
965 IntPatch_Point aPoint = aWLine1->Vertex(apointindex);
966 Standard_Real aTolerance = (aPoint.Tolerance() > P1.Tolerance()) ? aPoint.Tolerance() : P1.Tolerance();
967 if(aPoint.Value().IsEqual(P1.Value(), aTolerance)) {
968 aPoint.SetParameter(1);
969 emulatedWLine->AddVertex(aPoint);
973 for(apointindex = 1; apointindex < aWLine2->NbVertex(); apointindex++) {
974 IntPatch_Point aPoint = aWLine2->Vertex(apointindex);
975 Standard_Real aTolerance = (aPoint.Tolerance() > P2.Tolerance()) ? aPoint.Tolerance() : P2.Tolerance();
976 if(aPoint.Value().IsEqual(P2.Value(), aTolerance)) {
977 aPoint.SetParameter(aLineOn2S->NbPoints());
978 emulatedWLine->AddVertex(aPoint);
982 emulatedWLine->AddVertex(aLastVertex);
984 anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank);
994 // ================================================================================================
995 // static function: TestWLinesToAnArc
996 // purpose: test if possible to replace group of wlines by rline and replace in the sequence slin
997 // ================================================================================================
998 static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin,
999 const Handle(Adaptor3d_HSurface)& theSurface1,
1000 const Handle(Adaptor3d_TopolTool)& theDomain1,
1001 const Handle(Adaptor3d_HSurface)& theSurface2,
1002 const Handle(Adaptor3d_TopolTool)& theDomain2,
1003 const Standard_Real theTolArc) {
1005 IntPatch_SequenceOfLine aSeqOfWLine;
1006 IntPatch_SequenceOfLine aSeqOfRLine;
1007 for(Standard_Integer rank = 1; rank <= 2; rank++) {
1008 for(Standard_Integer i=1; i<=slin.Length(); i++) {
1009 if(slin.Value(i)->ArcType()!=IntPatch_Walking)
1011 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (slin.Value(i)));
1012 Standard_Integer nbvtx = aWLine->NbVertex();
1013 const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
1014 const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
1015 Standard_Boolean isvertex = Standard_False, wlineWasAppended = Standard_False;
1019 isvertex = Vtx1.IsVertexOnS1();
1021 isvertex = Vtx1.IsVertexOnS2();
1024 Standard_Boolean appendwline = Standard_True;
1026 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1027 appendwline = Standard_False;
1031 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1032 appendwline = Standard_False;
1035 wlineWasAppended = appendwline;
1037 aSeqOfWLine.Append(aWLine);
1040 if(aSeqOfWLine.Length()==0)
1042 const Handle(IntPatch_WLine)& aLastWLine =
1043 *((Handle(IntPatch_WLine) *)& (aSeqOfWLine.Value(aSeqOfWLine.Length())));
1044 const IntPatch_Point& aLastPoint = aLastWLine->Vertex(aLastWLine->NbVertex());
1045 Standard_Real aTolerance = (aLastPoint.Tolerance() > Vtx1.Tolerance()) ? aLastPoint.Tolerance() : Vtx1.Tolerance();
1046 if(aLastPoint.Value().IsEqual(Vtx1.Value(), aTolerance)) {
1047 Standard_Boolean appendwline = Standard_True;
1049 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1050 appendwline = Standard_False;
1054 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1055 appendwline = Standard_False;
1058 wlineWasAppended = appendwline;
1060 aSeqOfWLine.Append(aWLine);
1063 aSeqOfWLine.Clear();
1067 isvertex = Standard_False;
1069 isvertex = Vtx2.IsVertexOnS1();
1071 isvertex = Vtx2.IsVertexOnS2();
1073 if(wlineWasAppended && isvertex) {
1074 // build rline based on sequence of wlines.
1075 Handle(IntPatch_RLine) anRLine;
1077 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc);
1080 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc);
1083 if(!anRLine.IsNull()) {
1084 aSeqOfRLine.Append(anRLine);
1085 for(Standard_Integer k=1; k<=aSeqOfWLine.Length(); k++) {
1086 for(Standard_Integer j=1; j<=slin.Length(); j++) {
1087 if(aSeqOfWLine(k)==slin(j)) {
1094 aSeqOfWLine.Clear();
1099 for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) {
1100 slin.Append(aSeqOfRLine.Value(i));
1103 // modified by NIZHNY-MKK Mon Apr 2 12:18:34 2001.END
1105 //====================================================================================
1106 // function: MergeWLinesIfAllSegmentsAlongRestriction
1108 // purpose: If the result of LineConstructor is a set of WLines segments which are
1109 // placed along RESTRICTION, we can suppose that this result is not correct:
1110 // here we should have a RLine. If it is not possible to construct RLine
1111 // we should merge segments of WLines into single WLine equals to the same
1113 //====================================================================================
1114 static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin,
1115 const Handle(Adaptor3d_HSurface)& theSurface1,
1116 const Handle(Adaptor3d_TopolTool)& theDomain1,
1117 const Handle(Adaptor3d_HSurface)& theSurface2,
1118 const Handle(Adaptor3d_TopolTool)& theDomain2,
1119 const Standard_Real theTolArc)
1121 Standard_Integer i = 0, rank = 0;
1122 Standard_Real tol = 1.e-9;
1124 // here we check that all segments of WLines placed along restriction
1125 Standard_Integer WLOnRS1 = 0;
1126 Standard_Integer WLOnRS2 = 0;
1127 Standard_Integer NbWLines = 0;
1128 TColgp_SequenceOfPnt sqVertexPoints;
1130 for(rank = 1; rank <= 2; rank++)
1133 for(i = 1; i <= theSlin.Length(); i++)
1135 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1138 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1139 Standard_Integer nbvtx = aWLine->NbVertex();
1140 const IntPatch_Point& Vtx1 = aWLine->Vertex(1);
1141 const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx);
1144 sqVertexPoints.Append(Vtx1.Value());
1145 sqVertexPoints.Append(Vtx2.Value());
1146 if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) )
1151 if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) )
1155 if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break;
1158 Standard_Integer WLineRank = 0; // not possible to merge WLines
1160 if( WLOnRS1 == NbWLines )
1161 WLineRank = 1; // create merged WLine based on arc of S1
1162 else if( WLOnRS2 == NbWLines )
1163 WLineRank = 2; // create merged WLine based on arc of S2
1167 // avoid closed (degenerated) edges
1168 if( sqVertexPoints.Length() <= 2 )
1170 if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) )
1173 Standard_Real TolVrtx = 1.e-5;
1174 Standard_Integer testPointIndex = ( sqVertexPoints.Length() > 3 ) ? ((Standard_Integer) sqVertexPoints.Length() / 2) : 2;
1175 gp_Pnt testPoint = sqVertexPoints.Value( testPointIndex );
1176 Standard_Real Fp = 0., Lp = 0.;
1179 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1181 Standard_Integer arcnumber = (WLineRank == 1) ?
1182 GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp) :
1183 GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1185 if (arcnumber == 0) {
1189 Handle(IntPatch_WLine) anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1190 if (!anWLine.IsNull()) {
1192 theSlin.Append(anWLine);
1194 cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction "
1195 << ((WLineRank == 1) ? "S1" : "S2") << " to WLine***" << endl;
1200 //=========================================================================================
1203 // purpose: Define arc on (OBJ) surface which all WLine segments are placed along.
1204 // Check states of points in the gaps between segments on (TOOL). If those states
1205 // are IN or ON return the LineOn2S based on points3D were given from detected arc.
1206 // Returns 0 if it is not possible to create merged WLine.
1207 //========================================================================================
1208 static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin,
1209 const Standard_Integer& theRankS,
1210 const Handle(Adaptor3d_HSurface)& theSurfaceObj,
1211 const Handle(Adaptor3d_TopolTool)& theDomainObj,
1212 const Handle(Adaptor3d_HSurface)& theSurfaceTool,
1213 const gp_Pnt& theTestPoint,
1214 Standard_Real& theVrtxTol,
1215 Handle(IntSurf_LineOn2S)& theLineOn2S,
1216 Standard_Real& theFirst,
1217 Standard_Real& theLast)
1219 // 1. find number of arc (edge) on which the WLine segments are placed.
1221 Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.;
1222 Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0;
1226 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1229 Standard_Address anEAddress = theDomainObj->Edge();
1231 if( anEAddress == NULL )
1234 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1235 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1236 if ( aCEdge.IsNull() ) // e.g. degenerated edge, see OCC21770
1238 GeomAdaptor_Curve CE;
1240 Extrema_ExtPC epc(theTestPoint, CE, 1.e-7);
1244 for( i = 1; i <= epc.NbExt(); i++ )
1246 if( epc.SquareDistance( i ) < MinDistance2 )
1248 MinDistance2 = epc.SquareDistance( i );
1255 if( ArcNumber == 0 )
1258 // 2. load parameters of founded edge and its arc.
1260 TColgp_SequenceOfPnt PointsFromArc;
1261 Handle(Adaptor2d_HCurve2d) arc = NULL;
1262 Standard_Real tol = 1.e-7;
1263 TColStd_SequenceOfReal WLVertexParameters;
1264 Standard_Boolean classifyOK = Standard_True;
1265 Standard_Real CheckTol = 1.e-5;
1267 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1270 if( CurArc != ArcNumber )
1273 arc = theDomainObj->Value();
1275 for(i = 1; i <= theSlin.Length(); i++)
1277 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1280 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1282 Standard_Integer nbpnts = aWLine->NbPnts();
1283 const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1);
1284 const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts);
1286 Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.;
1290 POn2S_F.ParametersOnS1(Upf, Vpf);
1291 POn2S_L.ParametersOnS1(Upl, Vpl);
1295 POn2S_F.ParametersOnS2(Upf, Vpf);
1296 POn2S_L.ParametersOnS2(Upl, Vpl);
1299 gp_Pnt2d aPOnLine_F(Upf, Vpf);
1300 gp_Pnt2d aPOnLine_L(Upl, Vpl);
1302 Standard_Real par_F = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_F, tol);
1303 Standard_Real par_L = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_L, tol);
1305 WLVertexParameters.Append(par_F);
1306 WLVertexParameters.Append(par_L);
1309 for(i = 1; i <= WLVertexParameters.Length(); i++)
1311 for(j = i; j <= WLVertexParameters.Length(); j++)
1316 if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j))
1318 Standard_Real pol = WLVertexParameters.Value(i);
1319 WLVertexParameters.SetValue(i, WLVertexParameters.Value(j));
1320 WLVertexParameters.SetValue(j, pol);
1325 Standard_Address anEAddress = theDomainObj->Edge();
1326 TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
1327 TopoDS_Vertex V1, V2;
1328 TopExp::Vertices(*anE,V1,V2);
1329 Standard_Real MaxVertexTol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2));
1330 theVrtxTol = MaxVertexTol;
1331 Standard_Real EdgeTol = BRep_Tool::Tolerance(*anE);
1332 CheckTol = Max(MaxVertexTol, EdgeTol);
1333 Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1);
1334 // classification gaps
1336 if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol))
1338 Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.;
1340 aCEdge->D0(param, point);
1341 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1343 classifyOK = Standard_False;
1348 if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol))
1350 Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.;
1352 aCEdge->D0(param, point);
1353 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1355 classifyOK = Standard_False;
1359 // c. all middle gaps
1360 Standard_Integer NbChkPnts = WLVertexParameters.Length() / 2 - 1;
1361 for(i = 1; i <= NbChkPnts; i++)
1363 if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol))
1365 Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.;
1367 aCEdge->D0(param, point);
1368 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1370 classifyOK = Standard_False;
1379 // if classification gaps OK, fill sequence by the points from arc (edge)
1380 Standard_Real ParamFirst = WLVertexParameters.Value(1);
1381 Standard_Real ParamLast = WLVertexParameters.Value(WLVertexParameters.Length());
1382 Standard_Real dParam = Abs(ParamLast - ParamFirst) / 100.;
1383 Standard_Real cParam = ParamFirst;
1384 for( i = 0; i < 100; i++ )
1390 aCEdge->D0(cParam, cPnt);
1391 PointsFromArc.Append(cPnt);
1394 theFirst = ParamFirst;
1395 theLast = ParamLast;
1402 // create IntSurf_LineOn2S from points < PointsFromArc >
1403 for( i = 1; i <= PointsFromArc.Length(); i++ )
1405 Extrema_POnSurf pOnS1;
1406 Extrema_POnSurf pOnS2;
1407 gp_Pnt arcpoint = PointsFromArc.Value( i );
1408 Standard_Boolean isOnS1 = GetPointOn2S( arcpoint, theSurfaceObj->Surface(), CheckTol, pOnS1 );
1409 Standard_Boolean isOnS2 = GetPointOn2S( arcpoint, theSurfaceTool->Surface(), CheckTol, pOnS2 );
1410 if( isOnS1 && isOnS2 )
1412 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1413 pOnS1.Parameter(u1, v1);
1414 pOnS2.Parameter(u2, v2);
1415 IntSurf_PntOn2S pOn2S;
1416 pOn2S.SetValue(arcpoint, u1, v1, u2, v2 );
1417 theLineOn2S->Add( pOn2S );
1424 //=========================================================================================
1425 // function: IsPointOK
1427 // purpose: returns the state of testPoint on OTHER face.
1428 //========================================================================================
1429 static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
1430 const Adaptor3d_Surface& theTestSurface,
1431 const Standard_Real& theTol)
1433 Standard_Boolean result = Standard_False;
1434 Standard_Real ExtTol = theTol;//1.e-7;
1435 Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1436 if( extPS.IsDone() && extPS.NbExt() > 0 )
1438 Standard_Integer i = 0;
1439 Standard_Real MinDist2 = 1.e+200;
1440 for(i = 1; i <= extPS.NbExt(); i++)
1442 if( extPS.SquareDistance(i) < MinDist2 )
1444 MinDist2 = extPS.SquareDistance(i);
1447 if( MinDist2 <= theTol * theTol )
1448 result = Standard_True;
1453 //=========================================================================================
1454 // function: GetPointOn2S
1456 // purpose: check state of testPoint and returns result point if state is OK.
1457 //========================================================================================
1458 static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
1459 const Adaptor3d_Surface& theTestSurface,
1460 const Standard_Real& theTol,
1461 Extrema_POnSurf& theResultPoint)
1463 Standard_Boolean result = Standard_False;
1464 Standard_Real ExtTol = theTol;//1.e-7;
1465 Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol);
1466 if( extPS.IsDone() && extPS.NbExt() > 0 )
1468 Standard_Integer i = 0, minext = 1;
1469 Standard_Real MinDist2 = 1.e+200;
1470 for(i = 1; i <= extPS.NbExt(); i++)
1472 if( extPS.SquareDistance(i) < MinDist2 )
1475 MinDist2 = extPS.SquareDistance(i);
1478 if( MinDist2 <= theTol * theTol )
1480 result = Standard_True;
1481 theResultPoint = extPS.Point(minext);
1487 //=========================================================================================
1488 // function: GetMergedWLineOnRestriction
1490 // purpose: merge sequence of WLines all placed along restriction if the conditions of
1492 //========================================================================================
1493 static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
1494 const Standard_Real& theVrtxTol,
1495 const Handle(IntSurf_LineOn2S)& theLineOn2S)
1497 Handle(IntPatch_WLine) mWLine;
1498 if (theLineOn2S->NbPoints() == 0) {
1502 IntSurf_TypeTrans trans1 = IntSurf_Undecided;
1503 IntSurf_TypeTrans trans2 = IntSurf_Undecided;
1504 Standard_Integer i = 0;
1506 for(i = 1; i <= theSlin.Length(); i++)
1508 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1511 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1513 if( aWLine->TransitionOnS1() != IntSurf_Undecided && aWLine->TransitionOnS1() != IntSurf_Touch )
1514 trans1 = aWLine->TransitionOnS1();
1515 if( aWLine->TransitionOnS2() != IntSurf_Undecided && aWLine->TransitionOnS2() != IntSurf_Touch )
1516 trans2 = aWLine->TransitionOnS2();
1519 mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2);
1521 Standard_Integer NbPnts = mWLine->NbPnts();
1522 IntPatch_Point aFirstVertex, aLastVertex;
1524 aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False);
1525 aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False);
1527 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1529 mWLine->Point(1).Parameters(u1, v1, u2, v2);
1530 aFirstVertex.SetParameters(u1, v1, u2, v2);
1532 mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2);
1533 aLastVertex.SetParameters(u1, v1, u2, v2);
1535 aFirstVertex.SetParameter(1);
1536 aLastVertex.SetParameter(theLineOn2S->NbPoints());
1538 mWLine->AddVertex(aFirstVertex);
1539 mWLine->AddVertex(aLastVertex);
1541 mWLine->ComputeVertexParameters(theVrtxTol);