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
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.
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.
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.
22 #include <TopOpeBRep_FacesIntersector.ixx>
25 #include <TopOpeBRep_DRAW.hxx>
28 #include <IntPatch_LineConstructor.hxx>
29 #include <TopOpeBRep_TypeLineCurve.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>
44 Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7;
48 extern Standard_Boolean TopOpeBRep_GettraceFI();
49 extern Standard_Boolean TopOpeBRep_GettraceFITOL();
50 extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
52 Standard_Integer SAVFFi1 = 0;
53 Standard_Integer SAVFFi2 = 0;
54 static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2)
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();
60 cout<<"FaceIntersector : set "<<n1<<","<<n2<<endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2);
62 cout<<"FaceIntersector : write "<<n1<<","<<n2<<endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2);
65 extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
66 #include <TopOpeBRepTool_KRO.hxx>
67 Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face");
72 // NYI : IntPatch_Intersection : TolArc,TolTang exact definition
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>
86 static 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);
93 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
94 const Handle(Adaptor2d_HCurve2d)& theArc,
95 const Standard_Integer theRank);
98 Handle(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);
104 static 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
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>
120 static 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 //------------------------------------------------------------------------------------------------
127 static 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 //------------------------------------------------------------------------------------------------
138 static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
139 const Adaptor3d_Surface& theTestSurface,
140 const Standard_Real& theTol);
141 //-------------------------------------------------------------------------------------------------
142 static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
143 const Adaptor3d_Surface& theTestSurface,
144 const Standard_Real& theTol,
145 Extrema_POnSurf& theResultPoint);
146 //-------------------------------------------------------------------------------------------------------------------------
147 static 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
153 //=======================================================================
154 //function : TopOpeBRep_FacesIntersector
156 //=======================================================================
157 TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector ()
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();
168 //=======================================================================
171 //=======================================================================
172 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2,
173 const Bnd_Box& B1,const Bnd_Box& B2)
176 if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2));
180 if (!myForceTolerances) ShapeTolerances(F1,F2);
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);
192 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start();
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;
203 Standard_Real tol1 = myTol1;
204 Standard_Real tol2 = myTol2;
205 GLOBAL_tolFF = Max(tol1,tol2);
208 if (TopOpeBRep_GettraceFITOL()) {
209 cout<<"FacesIntersector : Perform tol1 = "<<tol1<<endl;
210 cout<<" tol2 = "<<tol2<<endl;
211 cout<<" defl = "<<Deflection<<" MaxUV = "<<MaxUV<<endl;
215 myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection);
216 myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,myTol1,myTol2);
219 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop();
222 //xpu180998 : cto900Q1
223 Standard_Boolean done = myIntersector.IsDone();
227 myIntersectionDone = Standard_True;
229 // mySurfacesSameOriented : a mettre dans IntPatch NYI
230 if ( SameDomain() ) {
231 mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2);
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) {
238 const TopoDS_Shape& E = L.Arc();
239 myEdgeRestrictionMap.Add(E);
244 if (TopOpeBRep_GettraceFI()) cout<<"Perform : isempty "<<IsEmpty()<<endl;
248 //=======================================================================
251 //=======================================================================
253 void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2)
256 Perform(F1,F2,B1,B2);
260 //=======================================================================
263 //=======================================================================
265 Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty ()
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;
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;
283 //=======================================================================
286 //=======================================================================
288 Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const
290 return myIntersectionDone;
293 //=======================================================================
294 //function : SameDomain
296 //=======================================================================
298 Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const
300 if (!myIntersectionDone)
301 Standard_ProgramError::Raise("FacesIntersector : bad SameDomain");
303 Standard_Boolean sd = myIntersector.TangentFaces();
305 //Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane);
307 // if (!plpl) return Standard_False;
312 //=======================================================================
315 //=======================================================================
317 const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face
318 (const Standard_Integer Index) const
320 if ( Index == 1 ) return myFace1;
321 else if ( Index == 2 ) return myFace2;
322 else Standard_ProgramError::Raise("TopOpeBRep_FacesIntersector::Face");
328 //=======================================================================
329 //function : SurfacesSameOriented
331 //=======================================================================
333 Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const
335 if ( SameDomain() ) {
336 return mySurfacesSameOriented;
338 Standard_ProgramError::Raise("FacesIntersector : bad SurfacesSameOriented");
339 return Standard_False;
342 //=======================================================================
343 //function : IsRestriction
345 //=======================================================================
347 Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction
348 (const TopoDS_Shape& E) const
350 Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E);
354 //=======================================================================
355 //function : Restrictions
357 //=======================================================================
359 const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions
362 return myEdgeRestrictionMap;
365 //=======================================================================
366 //function : PrepareLines
368 //=======================================================================
370 void TopOpeBRep_FacesIntersector::PrepareLines()
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()));
378 // modified by NIZHNY-MKK Mon Apr 2 12:14:58 2001.BEGIN
381 // modified by NIZHNY-MKK Mon Apr 2 12:15:09 2001.END
383 Standard_Boolean newV = Standard_True;
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);
397 // modified by NIZHNY-MKK Mon Apr 2 12:16:04 2001
398 IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines;
401 // Standard_Integer nbl=0;
402 IntPatch_LineConstructor **Ptr =
403 (IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *));
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,
411 // modified by NIZHNY-MKK Mon Apr 2 12:16:26 2001.BEGIN
413 for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) {
414 aSeqOfLines.Append(Ptr[i-1]->Line(k));
417 TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
419 for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) {
420 aSeqOfResultLines.Append(aSeqOfLines.Value(j));
423 // nbl+=Ptr[i-1]->NbLines();
424 // modified by NIZHNY-MKK Mon Apr 2 12:16:31 2001.END
427 // modified by NIZHNY-MKK Mon Apr 2 12:17:22 2001.BEGIN
428 // myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl);
429 myLineNb = aSeqOfResultLines.Length();
431 //Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
432 MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1);
433 myLineNb = aSeqOfResultLines.Length();
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);
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);
458 // modified by NIZHNY-MKK Mon Apr 2 12:17:57 2001.END
463 //=======================================================================
466 //=======================================================================
468 Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines()
473 //=======================================================================
476 //=======================================================================
478 Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const
483 //=======================================================================
484 //function : InitLine
486 //=======================================================================
488 void TopOpeBRep_FacesIntersector::InitLine()
494 //=======================================================================
495 //function : FindLine
497 //=======================================================================
499 void TopOpeBRep_FacesIntersector::FindLine()
501 myLineFound = Standard_False;
502 if ( ! myIntersectionDone ) return;
504 while (myLineIndex <= myLineNb) {
505 const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex);
506 myLineFound = L.OK();
507 if (myLineFound) break;
512 //=======================================================================
513 //function : MoreLine
515 //=======================================================================
517 Standard_Boolean TopOpeBRep_FacesIntersector::MoreLine()const
523 //=======================================================================
524 //function : NextLine
526 //=======================================================================
528 void TopOpeBRep_FacesIntersector::NextLine()
534 //=======================================================================
535 //function : CurrentLine
537 //=======================================================================
539 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine()
541 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex);
546 //=======================================================================
547 //function : CurrentLineIndex
549 //=======================================================================
551 Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const
556 //=======================================================================
559 //=======================================================================
561 TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL)
563 TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL);
567 //=======================================================================
568 //function : ResetIntersection
570 //=======================================================================
572 void TopOpeBRep_FacesIntersector::ResetIntersection()
574 myIntersectionDone = Standard_False;
577 myEdgeRestrictionMap.Clear();
578 myLineFound = Standard_False;
582 //=======================================================================
583 //function : ForceTolerances
585 //=======================================================================
587 void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1,
588 const Standard_Real Tol2)
592 myForceTolerances = Standard_True;
594 if (TopOpeBRep_GettraceFITOL())
595 cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl;
599 //=======================================================================
600 //function : GetTolerances
602 //=======================================================================
604 void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1,
605 Standard_Real& Tol2) const
611 //=======================================================================
612 //function : ShapeTolerances
613 //purpose : (private)
614 //=======================================================================
617 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1,
618 const TopoDS_Shape& S2)
620 void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& ,
621 const TopoDS_Shape& )
624 // myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
625 myTol1 = Precision::Confusion();
627 myForceTolerances = Standard_False;
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;
637 //=======================================================================
638 //function : ToleranceMax
639 //purpose : (private)
640 //=======================================================================
642 Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax
643 (const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const
645 TopExp_Explorer e(S,T);
646 if ( ! e.More() ) return Precision::Intersection();
648 Standard_Real tol = RealFirst();
649 for (; e.More(); e.Next())
650 tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
656 // modified by NIZHNY-MKK Mon Apr 2 12:18:30 2001.BEGIN
657 // ================================================================================================
658 // static function: TestWLineAlongRestriction
660 // ================================================================================================
661 static 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) {
667 Standard_Boolean result = Standard_False;
668 Standard_Integer NbPnts = theWLine->NbPnts();
669 Standard_Integer along = 0;
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 //------------------------------------------
679 //Standard_Real nad1u, nad1v, tolu, tolv;
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 //------------------------------------------
689 //if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) {
693 if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++;
694 //if(along!=i) break;
696 if(along==NbPnts) result = Standard_True;
701 // ================================================================================================
702 // static function: BuildRLineBasedOnWLine
704 // ================================================================================================
706 Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine,
707 const Handle(Adaptor2d_HCurve2d)& theArc,
708 const Standard_Integer theRank) {
709 Handle(IntPatch_RLine) anRLine;
711 if((theRank != 1) && (theRank != 2))
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);
721 Vtx1.ParametersOnS1(u, v);
724 Vtx1.ParametersOnS2(u, v);
727 aPOnLine = gp_Pnt2d(u, v);
728 Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
731 Vtx2.ParametersOnS1(u, v);
734 Vtx2.ParametersOnS2(u, v);
736 aPOnLine = gp_Pnt2d(u, v);
737 Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7);
739 Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance();
741 if(Abs(par1 - par2) < theArc->Resolution(tol))
744 Standard_Boolean IsOnFirst = (theRank == 1);
746 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
747 const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve();
748 IntSurf_Transition TransitionUndecided;
750 anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2());
753 anRLine->SetArcOnS1(theArc);
756 anRLine->SetArcOnS2(theArc);
759 Standard_Integer k = 0;
762 for(k = 1; k <= Lori->NbPoints(); k++) {
763 aLineOn2S->Add(Lori->Value(k));
765 anRLine->Add(aLineOn2S);
766 IntPatch_Point VtxFirst = Vtx1;
768 VtxFirst.SetArc(IsOnFirst, //-- On First
772 TransitionUndecided);
773 VtxFirst.SetParameter(par1);
774 anRLine->AddVertex(VtxFirst);
776 for(k = 2; k < nbvtx; k++) {
777 IntPatch_Point Vtx = theWLine->Vertex(k);
779 Vtx.ParametersOnS1(u, v);
782 Vtx.ParametersOnS2(u, v);
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);
790 IntPatch_Point VtxLast = Vtx2;
791 VtxLast.SetArc(IsOnFirst, //-- On First
795 TransitionUndecided);
796 VtxLast.SetParameter(par2);
797 anRLine->AddVertex(VtxLast);
798 anRLine->SetFirstPoint(1);
799 anRLine->SetLastPoint(nbvtx);
800 anRLine->ComputeVertexParameters(Precision::Confusion());
804 for(k = Lori->NbPoints(); k >= 1; k--) {
805 aLineOn2S->Add(Lori->Value(k));
807 anRLine->Add(aLineOn2S);
809 IntPatch_Point VtxFirst = Vtx2;
810 VtxFirst.SetArc(IsOnFirst, //-- On First
814 TransitionUndecided);
815 VtxFirst.SetParameter(par2);
816 anRLine->AddVertex(VtxFirst);
818 for(k = nbvtx - 1; k >= 2; k--) {
819 IntPatch_Point Vtx = theWLine->Vertex(k);
820 Vtx.ReverseTransition();
822 Vtx.ParametersOnS1(u, v);
825 Vtx.ParametersOnS2(u, v);
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);
832 IntPatch_Point VtxLast = Vtx1;
833 VtxLast.SetArc(IsOnFirst, //-- On First
837 TransitionUndecided);
838 VtxLast.SetParameter(par1);
839 anRLine->AddVertex(VtxLast);
840 anRLine->SetFirstPoint(1);
841 anRLine->SetLastPoint(nbvtx);
842 anRLine->ComputeVertexParameters(Precision::Confusion());
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 // ================================================================================================
854 Handle(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();
867 // avoid closed and degenerated edges
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;
876 for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) {
878 if(!foundVertex1 && aV1->IsSame(theDomain->Vertex()))
879 foundVertex1 = Standard_True;
880 if(!foundVertex2 && aV2->IsSame(theDomain->Vertex()))
881 foundVertex2 = Standard_True;
884 if(foundVertex1 && foundVertex2) {
885 Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0);
887 for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) {
888 const Handle(IntPatch_WLine)& aWLine =
889 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i)));
891 Standard_Integer indexpnt = aWLine->NbPnts()/2;
893 buildrline = Standard_False;
895 Standard_Real u = RealLast(), v = RealLast();
896 const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt);
898 POn2S.ParametersOnS1(u, v);
901 POn2S.ParametersOnS2(u, v);
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);
908 Standard_Real nad1u, nad1v, tolu, tolv;
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;
917 if(aPOnArc.Distance(aPOnLine) > aTolerance) {
918 buildrline = Standard_False;
924 IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided;
926 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
928 for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) {
929 const Handle(IntPatch_WLine)& atmpWLine =
930 *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j)));
932 const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve();
934 if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) {
935 trans1 = atmpWLine->TransitionOnS1();
937 if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) {
938 trans2 = atmpWLine->TransitionOnS2();
941 Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine();
942 Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine();
944 for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) {
945 aLineOn2S->Add(Lori->Value(k));
949 Handle(IntPatch_WLine) emulatedWLine =
950 new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2);
952 IntPatch_Point aFirstVertex = P1;
953 IntPatch_Point aLastVertex = P2;
954 aFirstVertex.SetParameter(1);
955 aLastVertex.SetParameter(aLineOn2S->NbPoints());
957 emulatedWLine->AddVertex(aFirstVertex);
958 Standard_Integer apointindex = 0;
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);
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);
978 emulatedWLine->AddVertex(aLastVertex);
980 anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank);
990 // ================================================================================================
991 // static function: TestWLinesToAnArc
992 // purpose: test if possible to replace group of wlines by rline and replace in the sequence slin
993 // ================================================================================================
994 static 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) {
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)
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;
1015 isvertex = Vtx1.IsVertexOnS1();
1017 isvertex = Vtx1.IsVertexOnS2();
1020 Standard_Boolean appendwline = Standard_True;
1022 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1023 appendwline = Standard_False;
1027 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1028 appendwline = Standard_False;
1031 wlineWasAppended = appendwline;
1033 aSeqOfWLine.Append(aWLine);
1036 if(aSeqOfWLine.Length()==0)
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;
1045 if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) {
1046 appendwline = Standard_False;
1050 if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) {
1051 appendwline = Standard_False;
1054 wlineWasAppended = appendwline;
1056 aSeqOfWLine.Append(aWLine);
1059 aSeqOfWLine.Clear();
1063 isvertex = Standard_False;
1065 isvertex = Vtx2.IsVertexOnS1();
1067 isvertex = Vtx2.IsVertexOnS2();
1069 if(wlineWasAppended && isvertex) {
1070 // build rline based on sequence of wlines.
1071 Handle(IntPatch_RLine) anRLine;
1073 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc);
1076 anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc);
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)) {
1090 aSeqOfWLine.Clear();
1095 for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) {
1096 slin.Append(aSeqOfRLine.Value(i));
1099 // modified by NIZHNY-MKK Mon Apr 2 12:18:34 2001.END
1101 //====================================================================================
1102 // function: MergeWLinesIfAllSegmentsAlongRestriction
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
1109 //====================================================================================
1110 static 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)
1117 Standard_Integer i = 0, rank = 0;
1118 Standard_Real tol = 1.e-9;
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;
1126 for(rank = 1; rank <= 2; rank++)
1129 for(i = 1; i <= theSlin.Length(); i++)
1131 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
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);
1140 sqVertexPoints.Append(Vtx1.Value());
1141 sqVertexPoints.Append(Vtx2.Value());
1142 if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) )
1147 if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) )
1151 if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break;
1154 Standard_Integer WLineRank = 0; // not possible to merge WLines
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
1163 // avoid closed (degenerated) edges
1164 if( sqVertexPoints.Length() <= 2 )
1166 if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) )
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.;
1175 if( WLineRank == 1 )
1177 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1178 Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1180 if( arcnumber == 0 )
1183 Handle(IntPatch_WLine) anWLine = NULL;
1184 anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1186 cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S1 to WLine ***" << endl;
1189 theSlin.Append(anWLine);
1193 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1194 Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp);
1196 if( arcnumber == 0 )
1199 Handle(IntPatch_WLine) anWLine = NULL;
1200 anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S);
1202 cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S2 to WLine***" << endl;
1205 theSlin.Append(anWLine);
1209 //=========================================================================================
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 //========================================================================================
1217 static 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)
1228 // 1. find number of arc (edge) on which the WLine segments are placed.
1230 Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.;
1231 Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0;
1235 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1238 Standard_Address anEAddress = theDomainObj->Edge();
1240 if( anEAddress == NULL )
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
1247 GeomAdaptor_Curve CE;
1249 Extrema_ExtPC epc(theTestPoint, CE, 1.e-7);
1253 for( i = 1; i <= epc.NbExt(); i++ )
1255 if( epc.SquareDistance( i ) < MinDistance2 )
1257 MinDistance2 = epc.SquareDistance( i );
1264 if( ArcNumber == 0 )
1267 // 2. load parameters of founded edge and its arc.
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;
1276 for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next())
1279 if( CurArc != ArcNumber )
1282 arc = theDomainObj->Value();
1284 for(i = 1; i <= theSlin.Length(); i++)
1286 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1289 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
1291 Standard_Integer nbpnts = aWLine->NbPnts();
1292 const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1);
1293 const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts);
1295 Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.;
1299 POn2S_F.ParametersOnS1(Upf, Vpf);
1300 POn2S_L.ParametersOnS1(Upl, Vpl);
1304 POn2S_F.ParametersOnS2(Upf, Vpf);
1305 POn2S_L.ParametersOnS2(Upl, Vpl);
1308 gp_Pnt2d aPOnLine_F(Upf, Vpf);
1309 gp_Pnt2d aPOnLine_L(Upl, Vpl);
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);
1314 WLVertexParameters.Append(par_F);
1315 WLVertexParameters.Append(par_L);
1318 for(i = 1; i <= WLVertexParameters.Length(); i++)
1320 for(j = i; j <= WLVertexParameters.Length(); j++)
1325 if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j))
1327 Standard_Real pol = WLVertexParameters.Value(i);
1328 WLVertexParameters.SetValue(i, WLVertexParameters.Value(j));
1329 WLVertexParameters.SetValue(j, pol);
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
1345 if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol))
1347 Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.;
1349 aCEdge->D0(param, point);
1350 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1352 classifyOK = Standard_False;
1357 if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol))
1359 Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.;
1361 aCEdge->D0(param, point);
1362 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1364 classifyOK = Standard_False;
1368 // c. all middle gaps
1369 Standard_Integer NbChkPnts = WLVertexParameters.Length() / 2 - 1;
1370 for(i = 1; i <= NbChkPnts; i++)
1372 if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol))
1374 Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.;
1376 aCEdge->D0(param, point);
1377 if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) )
1379 classifyOK = Standard_False;
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++ )
1399 aCEdge->D0(cParam, cPnt);
1400 PointsFromArc.Append(cPnt);
1403 theFirst = ParamFirst;
1404 theLast = ParamLast;
1411 // create IntSurf_LineOn2S from points < PointsFromArc >
1412 for( i = 1; i <= PointsFromArc.Length(); i++ )
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 )
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 );
1433 //=========================================================================================
1434 // function: IsPointOK
1436 // purpose: returns the state of testPoint on OTHER face.
1437 //========================================================================================
1438 static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt,
1439 const Adaptor3d_Surface& theTestSurface,
1440 const Standard_Real& theTol)
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 )
1447 Standard_Integer i = 0, minext = 1;
1448 Standard_Real MinDist2 = 1.e+200;
1449 for(i = 1; i <= extPS.NbExt(); i++)
1451 if( extPS.SquareDistance(i) < MinDist2 )
1454 MinDist2 = extPS.SquareDistance(i);
1457 if( MinDist2 <= theTol * theTol )
1458 result = Standard_True;
1463 //=========================================================================================
1464 // function: GetPointOn2S
1466 // purpose: check state of testPoint and returns result point if state is OK.
1467 //========================================================================================
1468 static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt,
1469 const Adaptor3d_Surface& theTestSurface,
1470 const Standard_Real& theTol,
1471 Extrema_POnSurf& theResultPoint)
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 )
1478 Standard_Integer i = 0, minext = 1;
1479 Standard_Real MinDist2 = 1.e+200;
1480 for(i = 1; i <= extPS.NbExt(); i++)
1482 if( extPS.SquareDistance(i) < MinDist2 )
1485 MinDist2 = extPS.SquareDistance(i);
1488 if( MinDist2 <= theTol * theTol )
1490 result = Standard_True;
1491 theResultPoint = extPS.Point(minext);
1497 //=========================================================================================
1498 // function: GetMergedWLineOnRestriction
1500 // purpose: merge sequence of WLines all placed along restriction if the conditions of
1502 //========================================================================================
1503 static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin,
1504 const Standard_Real& theVrtxTol,
1505 const Handle(IntSurf_LineOn2S)& theLineOn2S)
1507 IntSurf_TypeTrans trans1 = IntSurf_Undecided;
1508 IntSurf_TypeTrans trans2 = IntSurf_Undecided;
1509 Standard_Integer i = 0;
1511 for(i = 1; i <= theSlin.Length(); i++)
1513 if( theSlin.Value(i)->ArcType() != IntPatch_Walking )
1516 const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i)));
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();
1524 Handle(IntPatch_WLine) mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2);
1526 Standard_Integer NbPnts = mWLine->NbPnts();
1527 IntPatch_Point aFirstVertex, aLastVertex;
1529 aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False);
1530 aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False);
1532 Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.;
1534 mWLine->Point(1).Parameters(u1, v1, u2, v2);
1535 aFirstVertex.SetParameters(u1, v1, u2, v2);
1537 mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2);
1538 aLastVertex.SetParameters(u1, v1, u2, v2);
1540 aFirstVertex.SetParameter(1);
1541 aLastVertex.SetParameter(theLineOn2S->NbPoints());
1543 mWLine->AddVertex(aFirstVertex);
1544 mWLine->AddVertex(aLastVertex);
1546 mWLine->ComputeVertexParameters(theVrtxTol);