1 // Created on: 1992-10-13
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-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.
17 // Modified by skv - Tue Mar 1 14:22:09 2005 OCC8169
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
26 #include <Standard_ConstructionError.hxx>
28 #include <IntRes2d_Domain.hxx>
29 #include <IntRes2d_Position.hxx>
30 #include <IntRes2d_Transition.hxx>
31 #include <IntRes2d_IntersectionPoint.hxx>
32 #include <IntRes2d_IntersectionSegment.hxx>
35 #include <IntImpParGen.hxx>
37 #include <Intf_SectionPoint.hxx>
38 #include <Intf_SectionLine.hxx>
39 #include <Intf_TangentZone.hxx>
40 #include <Intf_InterferencePolygon2d.hxx>
42 #include <gp_Vec2d.hxx>
44 #include <math_Vector.hxx>
45 #include <math_FunctionSetRoot.hxx>
46 #include <math_NewtonFunctionSetRoot.hxx>
47 #include <NCollection_Handle.hxx>
48 #include <Bnd_Box2d.hxx>
49 #include <Precision.hxx>
51 //======================================================================
53 #define NBITER_MAX_POLYGON 10
54 #define TOL_CONF_MINI 0.0000000001
55 #define TOL_MINI 0.0000000001
57 //----------------------------------------------------------------------
60 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
61 const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l,
62 const Standard_Real theTolConf,
63 const Standard_Integer theMaxCount,
64 IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
65 Standard_Integer& theCount);
68 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
70 ,const Standard_Real u
71 ,const IntRes2d_Domain& D2
73 ,const Standard_Real v
74 ,const Standard_Real TolConf
75 ,IntRes2d_IntersectionPoint& IntPt
76 ,Standard_Boolean& HeadOn1
77 ,Standard_Boolean& HeadOn2
78 ,Standard_Boolean& EndOn1
79 ,Standard_Boolean& EndOn2
80 ,Standard_Integer PosSegment);
83 //======================================================================
84 IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen()
86 const Standard_Integer aMinPntNb = 20; // Minimum number of samples.
87 myMinPntNb = aMinPntNb;
88 done = Standard_False;
90 //======================================================================
91 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
92 ,const IntRes2d_Domain& D1
94 ,const IntRes2d_Domain& D2
95 ,const Standard_Real TheTolConf
96 ,const Standard_Real TheTol)
101 Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
102 Standard_Real DV = D2.LastParameter()-D2.FirstParameter();
103 Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
104 Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
105 Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV);
106 //----------------------------------------------------------------------
107 //-- Processing of end points
108 //----------------------------------------------------------------------
109 Standard_Boolean HeadOn1 = Standard_False;
110 Standard_Boolean HeadOn2 = Standard_False;
111 Standard_Boolean EndOn1 = Standard_False;
112 Standard_Boolean EndOn2 = Standard_False;
114 Standard_Integer n=this->NbPoints();
117 //--------------------------------------------------------------------
118 //-- The points Head Head ... End End are not rejected if
119 //-- they are already present at the end of segment
120 //-- ( It is not possible to test the equities on the parameters)
121 //-- ( these points are not found at EpsX precision )
122 //-- PosSegment = 1 if Head Head
126 //--------------------------------------------------------------------
127 Standard_Integer PosSegment = 0;
130 IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
131 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
132 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
134 IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
135 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
136 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
138 if(Pos1 == IntRes2d_Head) {
139 if(Pos2 == IntRes2d_Head) PosSegment|=1;
140 else if(Pos2 == IntRes2d_End) PosSegment|=2;
142 else if(Pos1 == IntRes2d_End) {
143 if(Pos2 == IntRes2d_Head) PosSegment|=4;
144 else if(Pos2 == IntRes2d_End) PosSegment|=8;
148 n=this->NbSegments();
150 IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
151 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
152 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
154 IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
155 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
156 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
158 if(Pos1 == IntRes2d_Head) {
159 if(Pos2 == IntRes2d_Head) PosSegment|=1;
160 else if(Pos2 == IntRes2d_End) PosSegment|=2;
162 else if(Pos1 == IntRes2d_End) {
163 if(Pos2 == IntRes2d_Head) PosSegment|=4;
164 else if(Pos2 == IntRes2d_End) PosSegment|=8;
167 Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
168 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
169 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
171 Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
172 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
173 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
175 if(Pos1 == IntRes2d_Head) {
176 if(Pos2 == IntRes2d_Head) PosSegment|=1;
177 else if(Pos2 == IntRes2d_End) PosSegment|=2;
179 else if(Pos1 == IntRes2d_End) {
180 if(Pos2 == IntRes2d_Head) PosSegment|=4;
181 else if(Pos2 == IntRes2d_End) PosSegment|=8;
185 Standard_Real U0 = D1.FirstParameter();
186 Standard_Real U1 = D1.LastParameter();
187 Standard_Real V0 = D2.FirstParameter();
188 Standard_Real V1 = D2.LastParameter();
189 IntRes2d_IntersectionPoint IntPt;
191 if(D1.FirstTolerance() || D2.FirstTolerance()) {
192 if(HeadOrEndPoint(D1,C1,U0,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
195 if(D1.FirstTolerance() || D2.LastTolerance()) {
196 if(HeadOrEndPoint(D1,C1,U0,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
199 if(D1.LastTolerance() || D2.FirstTolerance()) {
200 if(HeadOrEndPoint(D1,C1,U1,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
203 if(D1.LastTolerance() || D2.LastTolerance()) {
204 if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
210 //======================================================================
211 //== A u t o I n t e r s e c t i o n
212 //======================================================================
213 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
214 ,const IntRes2d_Domain& D1
215 ,const Standard_Real TheTolConf
216 ,const Standard_Real TheTol)
222 Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
223 Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
224 Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
225 Perform(C1,D1,TlConf,Tl,0,DU,DU);
227 Standard_Integer n=this->NbPoints();
229 //--------------------------------------------------------------------
230 //-- The points Head Head ... End End are not rejected if
231 //-- they are already present at the end of segment
232 //-- ( It is not possible to test the equities on the parameters)
233 //-- ( these points are not found at EpsX precision )
234 //-- PosSegment = 1 if Head Head
238 //--------------------------------------------------------------------
239 Standard_Integer PosSegment = 0;
242 IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
243 IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
245 if(Pos1 == IntRes2d_Head) {
246 if(Pos2 == IntRes2d_Head) PosSegment|=1;
247 else if(Pos2 == IntRes2d_End) PosSegment|=2;
249 else if(Pos1 == IntRes2d_End) {
250 if(Pos2 == IntRes2d_Head) PosSegment|=4;
251 else if(Pos2 == IntRes2d_End) PosSegment|=8;
255 n=this->NbSegments();
257 IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
258 IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
260 if(Pos1 == IntRes2d_Head) {
261 if(Pos2 == IntRes2d_Head) PosSegment|=1;
262 else if(Pos2 == IntRes2d_End) PosSegment|=2;
264 else if(Pos1 == IntRes2d_End) {
265 if(Pos2 == IntRes2d_Head) PosSegment|=4;
266 else if(Pos2 == IntRes2d_End) PosSegment|=8;
269 Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
270 Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
272 if(Pos1 == IntRes2d_Head) {
273 if(Pos2 == IntRes2d_Head) PosSegment|=1;
274 else if(Pos2 == IntRes2d_End) PosSegment|=2;
276 else if(Pos1 == IntRes2d_End) {
277 if(Pos2 == IntRes2d_Head) PosSegment|=4;
278 else if(Pos2 == IntRes2d_End) PosSegment|=8;
282 //======================================================================
284 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
285 ,const IntRes2d_Domain& D1
286 ,const Standard_Real TolConf
287 ,const Standard_Real Tol
288 ,const Standard_Integer NbIter
289 ,const Standard_Real /*DeltaU*/
290 ,const Standard_Real) {
292 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
294 Standard_Integer nbsamples;
295 done = Standard_False;
297 nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
299 if(NbIter>3 || (NbIter>2 && nbsamples>100)) return;
301 nbsamples*=2; //--- We take systematically two times more points
302 //-- than on a normal curve.
303 //-- Auto-intersecting curves often produce
304 //-- polygons rather far from the curve with parameter ct.
307 nbsamples=(3*(nbsamples*NbIter))/2;
309 IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol);
310 if(!Poly1.AutoIntersectionIsPossible()) {
311 done = Standard_True;
315 //----------------------------------------------------------------------
316 //-- If the deflection is less than the Tolerance of Confusion
317 //-- then the deflection of the polygon is set in TolConf
318 //-- (Detection of Tangency Zones)
319 //----------------------------------------------------------------------
320 if(Poly1.DeflectionOverEstimation() < TolConf) {
321 Poly1.SetDeflectionOverEstimation(TolConf);
324 Intf_InterferencePolygon2d InterPP(Poly1);
325 IntCurve_ExactIntersectionPoint EIP(C1,C1,TolConf);
328 //----------------------------------------------------------------------
329 //-- Processing of SectionPoint
330 //----------------------------------------------------------------------
331 Standard_Integer Nbsp = InterPP.NbSectionPoints();
334 //-- ---------------------------------------------------------------------
335 //-- filtering, filtering, filtering ...
337 Standard_Integer* TriIndex = new Standard_Integer [Nbsp+1];
338 Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1];
339 Standard_Integer* PtrSegIndex2 = new Standard_Integer [Nbsp+1];
340 Standard_Boolean Triok;
341 Standard_Integer SegIndex1,SegIndex2,SegIndex_1,SegIndex_2;
342 // Standard_Real ParamOn1,ParamOn2,ParamOn_1,ParamOn_2;
343 Standard_Real ParamOn1,ParamOn2;
346 for( i=1;i<=Nbsp;i++) {
348 const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i);
349 SPnt1.InfoFirst(Type,PtrSegIndex1[i],ParamOn1);
350 SPnt1.InfoSecond(Type,PtrSegIndex2[i],ParamOn2);
357 for(Standard_Integer tr=1;tr<Nbsp;tr++) {
358 SegIndex1=PtrSegIndex1[TriIndex[tr]];
359 SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
361 SegIndex2=PtrSegIndex2[TriIndex[tr]];
362 SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
364 if(SegIndex1 > SegIndex_1) {
365 Standard_Integer q=TriIndex[tr];
366 TriIndex[tr]=TriIndex[tr+1];
368 Triok=Standard_False;
370 else if(SegIndex1 == SegIndex_1) {
371 if(SegIndex2 > SegIndex_2) {
372 Standard_Integer q=TriIndex[tr];
373 TriIndex[tr]=TriIndex[tr+1];
375 Triok=Standard_False;
380 while(Triok==Standard_False);
382 //-- supression des doublons Si Si !
383 for(i=1; i<Nbsp;i++) {
384 if( (PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i+1]])
385 && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) {
390 Standard_Integer Nelarg=(Poly1.NbSegments()/20);
391 if(Nelarg<2) Nelarg=2;
393 for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
395 const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
397 SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
398 SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
400 if(Abs(SegIndex1-SegIndex2)>1) {
402 EIP.Perform(Poly1,Poly1,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
403 if(EIP.NbRoots()==0) {
404 //-- All neighbor segments are removed
405 for(Standard_Integer k=sp+1;k<=Nbsp;k++) {
406 Standard_Integer kk=TriIndex[k];
407 // --- avoid negative indicies as well as in outer done
409 if( Abs(SegIndex1-PtrSegIndex1[kk])< Nelarg
410 && Abs(SegIndex2-PtrSegIndex2[kk])< Nelarg) {
416 else if(EIP.NbRoots()>=1) {
417 //--------------------------------------------------------------------
418 //-- It is checked if the found point is a root
419 //--------------------------------------------------------------------
422 TheCurveTool::D1(C1,U,P1,Tan1);
423 TheCurveTool::D1(C1,V,P2,Tan2);
424 Standard_Real Dist = P1.Distance(P2);
425 Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
427 if(Abs(U-V)<=EpsX1) {
428 //-----------------------------------------
429 //-- Solution not valid
430 //-- The maths should have converged in a
431 //-- trivial solution ( point U = V )
432 //-----------------------------------------
436 //-----------------------------------------------------------------
437 //-- It is checked if the point (u,v) already exists
439 done = Standard_True;
440 Standard_Integer nbp=NbPoints();
442 for(Standard_Integer p=1; p<=nbp; p++) {
443 const IntRes2d_IntersectionPoint& P=Point(p);
444 if(Abs(U-P.ParamOnFirst()) <= EpsX1) {
445 if(Abs(V-P.ParamOnSecond()) <= EpsX1) {
446 Dist = TolConf+1.0; p+=nbp;
451 if(Dist <= TolConf) { //-- Or the point is already present
452 IntRes2d_Position Pos1 = IntRes2d_Middle;
453 IntRes2d_Position Pos2 = IntRes2d_Middle;
454 IntRes2d_Transition Trans1,Trans2;
455 //-----------------------------------------------------------------
456 //-- Calculate Positions of Points on the curve
458 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())
459 Pos1 = IntRes2d_Head;
460 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance())
463 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())
464 Pos2 = IntRes2d_Head;
465 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance())
467 //-----------------------------------------------------------------
468 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1
470 ,TolConf) == Standard_False)
472 TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
473 TheCurveTool::D2(C1,V,P2,Tan2,Norm2);
474 IntImpParGen::DetermineTransition( Pos1,Tan1,Norm1,Trans1
475 ,Pos2,Tan2,Norm2,Trans2
478 IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
486 delete [] PtrSegIndex1;
487 delete [] PtrSegIndex2;
490 //----------------------------------------------------------------------
491 //-- Processing of TangentZone
492 //----------------------------------------------------------------------
493 Standard_Integer Nbtz = InterPP.NbTangentZones();
494 for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
495 Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
496 //====================================================================
497 //== Find the first and the last point in the tangency zone.
498 //====================================================================
499 Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
500 Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
501 // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
502 Standard_Integer SegIndex1onP1,SegIndex1onP2;
504 Standard_Real ParamOnLine;
505 Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
506 ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
507 ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
508 for(Standard_Integer qq=1;qq<=NbPnts;qq++) {
509 const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
510 //====================================================================
511 //== The zones of tangency are discretized
512 //== Test of stop : Check if
513 //== (Deflection < Tolerance)
514 //== Or (Sample < EpsX) (normally the first condition is
516 //====================================================================
517 // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
518 Standard_Real _PolyUInf,_PolyVInf;
520 SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
521 if(SegIndex1onP1 > Poly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
522 if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
523 _PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
525 SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
526 if(SegIndex1onP2 > Poly1.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
527 if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
528 _PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
530 //----------------------------------------------------------------------
532 if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
533 if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
535 if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
536 if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
539 PolyUInf= ParamInfOnCurve1;
540 PolyUSup= ParamSupOnCurve1;
541 PolyVInf= ParamInfOnCurve2;
542 PolyVSup= ParamSupOnCurve2;
544 TheCurveTool::D0(C1,PolyUInf,P1);
545 TheCurveTool::D0(C1,PolyVInf,P2);
546 Standard_Real distmemesens = P1.SquareDistance(P2);
547 TheCurveTool::D0(C1,PolyVSup,P2);
548 Standard_Real distdiffsens = P1.SquareDistance(P2);
549 if(distmemesens > distdiffsens) {
550 Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
553 //-----------------------------------------------------------------
554 //-- Calculate Positions of Points on the curve and
555 //-- Transitions on each limit of the segment
557 IntRes2d_Position Pos1 = IntRes2d_Middle;
558 IntRes2d_Position Pos2 = IntRes2d_Middle;
559 IntRes2d_Transition Trans1,Trans2;
561 TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
562 TheCurveTool::D1(C1,PolyVInf,P2,Tan2);
564 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
565 Pos1 = IntRes2d_Head;
567 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
570 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
571 Pos2 = IntRes2d_Head;
573 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
577 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
578 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
580 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
581 PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
583 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
584 PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
587 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
592 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
595 TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
596 TheCurveTool::D2(C1,PolyVInf,P2,Tan2,Norm2);
597 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
598 Pos2,Tan2,Norm2,Trans2,TolConf);
600 IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
601 ,Trans1,Trans2,Standard_False);
602 //----------------------------------------------------------------------
604 if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) ||
605 (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C1)))
611 TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
612 TheCurveTool::D1(C1,PolyVSup,P2,Tan2);
613 Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
615 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
616 Pos1 = IntRes2d_Head;
618 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
621 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
622 Pos2 = IntRes2d_Head;
624 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
629 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
630 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
632 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
633 PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
635 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
636 PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
639 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
642 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
644 TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
645 TheCurveTool::D2(C1,PolyVSup,P2,Tan2,Norm2);
646 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
647 Pos2,Tan2,Norm2,Trans2,TolConf);
649 IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
650 ,Trans1,Trans2,Standard_False);
652 Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
653 if(ParamInfOnCurve1 > ParamSupOnCurve1) {
654 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
658 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
662 } //end of processing of TangentZone
664 done = Standard_True;
668 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
670 ,const Standard_Real tu
671 ,const IntRes2d_Domain& D2
673 ,const Standard_Real tv
674 ,const Standard_Real TolConf
675 ,IntRes2d_IntersectionPoint& IntPt
676 ,Standard_Boolean& HeadOn1
677 ,Standard_Boolean& HeadOn2
678 ,Standard_Boolean& EndOn1
679 ,Standard_Boolean& EndOn2
680 ,Standard_Integer PosSegment) {
682 gp_Pnt2d P1,P2,SP1,SP2;
683 gp_Vec2d T1,T2,N1,N2;
686 Standard_Real svu = u;
687 Standard_Real svv = v;
689 TheCurveTool::D1(C1,u,P1,T1);
690 TheCurveTool::D1(C2,v,P2,T2);
692 IntRes2d_Position Pos1 = IntRes2d_Middle;
693 IntRes2d_Position Pos2 = IntRes2d_Middle;
694 IntRes2d_Transition Trans1,Trans2;
696 //----------------------------------------------------------------------
697 //-- Head On 1 : Head1 <-> P2
698 if(P2.Distance(D1.FirstPoint())<=D1.FirstTolerance()) {
699 Pos1 = IntRes2d_Head;
700 HeadOn1 = Standard_True;
701 SP1 = D1.FirstPoint();
702 u = D1.FirstParameter();
704 //----------------------------------------------------------------------
705 //-- End On 1 : End1 <-> P2
706 else if(P2.Distance(D1.LastPoint())<=D1.LastTolerance()) {
708 EndOn1 = Standard_True;
709 SP1 = D1.LastPoint();
710 u = D1.LastParameter();
713 //----------------------------------------------------------------------
714 //-- Head On 2 : Head2 <-> P1
715 else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance()) {
716 Pos2 = IntRes2d_Head;
717 HeadOn2 = Standard_True;
718 SP2 = D2.FirstPoint();
719 v = D2.FirstParameter();
721 //----------------------------------------------------------------------
722 //-- End On 2 : End2 <-> P1
723 else if(P1.Distance(D2.LastPoint())<=D2.LastTolerance()) {
725 EndOn2 = Standard_True;
726 SP2 = D2.LastPoint();
727 v = D2.LastParameter();
730 Standard_Real EpsX1 = TheCurveTool::EpsX(C1);
731 Standard_Real EpsX2 = TheCurveTool::EpsX(C2);
733 if((Pos1 != IntRes2d_Middle)||(Pos2 != IntRes2d_Middle)) {
734 if(Pos1 == IntRes2d_Middle) {
735 if(Abs(u-D1.FirstParameter()) <= EpsX1) {
736 Pos1 = IntRes2d_Head;
737 P1 = D1.FirstPoint();
738 HeadOn1 = Standard_True;
740 else if(Abs(u-D1.LastParameter()) <= EpsX1) {
743 EndOn1 = Standard_True;
751 if(Pos2 == IntRes2d_Middle) {
752 if(Abs(v-D2.FirstParameter()) <= EpsX2) {
753 Pos2 = IntRes2d_Head;
754 HeadOn2 = Standard_True;
755 P2 = D2.FirstPoint();
756 if(Pos1 != IntRes2d_Middle) {
757 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
763 else if(Abs(v-D2.LastParameter()) <= EpsX2) {
765 EndOn2 = Standard_True;
767 if(Pos1 != IntRes2d_Middle) {
768 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
776 //--------------------------------------------------------------------
777 //-- It is tested if a point at the end of segment already has its transitions
778 //-- If Yes, the new point is not created
780 //-- PosSegment = 1 if Head Head
784 //--------------------------------------------------------------------
785 if(Pos1 == IntRes2d_Head) {
786 if((Pos2 == IntRes2d_Head)&&(PosSegment & 1)) return(Standard_False);
787 if((Pos2 == IntRes2d_End )&&(PosSegment & 2)) return(Standard_False);
789 else if(Pos1 == IntRes2d_End) {
790 if((Pos2 == IntRes2d_Head)&&(PosSegment & 4)) return(Standard_False);
791 if((Pos2 == IntRes2d_End )&&(PosSegment & 8)) return(Standard_False);
795 if(IntImpParGen::DetermineTransition( Pos1,T1,Trans1,Pos2,T2,Trans2,TolConf)
797 TheCurveTool::D2(C1,svu,P1,T1,N1);
798 TheCurveTool::D2(C2,svv,P2,T2,N2);
799 IntImpParGen::DetermineTransition(Pos1,T1,N1,Trans1,
800 Pos2,T2,N2,Trans2,TolConf);
802 IntPt.SetValues(P1,u,v,Trans1,Trans2,Standard_False);
803 return(Standard_True);
806 return(Standard_False);
809 //=======================================================================
811 //purpose : Base method to perform polyline / polyline intersection for
813 //=======================================================================
814 void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
815 const IntRes2d_Domain& D1,
817 const IntRes2d_Domain& D2,
818 const Standard_Real TolConf,
819 const Standard_Real Tol,
820 const Standard_Integer NbIter,
821 const Standard_Real DeltaU,
822 const Standard_Real DeltaV)
824 Standard_Integer nbsamplesOnC1,nbsamplesOnC2;
825 done = Standard_False;
827 if(NbIter>NBITER_MAX_POLYGON) return;
829 // Number of samples tunning.
830 nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
831 nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
835 // Minimal number of points.
836 nbsamplesOnC1 = Max(nbsamplesOnC1, myMinPntNb);
837 nbsamplesOnC2 = Max(nbsamplesOnC2, myMinPntNb);
841 // Increase number of samples in second and next iterations.
842 nbsamplesOnC1=(5 * (nbsamplesOnC1 * NbIter)) / 4;
843 nbsamplesOnC2=(5 * (nbsamplesOnC2 * NbIter)) / 4;
846 NCollection_Handle<IntCurve_ThePolygon2d>
847 aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
848 aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
850 if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
851 (aPoly2->DeflectionOverEstimation() > TolConf))
853 const Standard_Real aDeflectionSum =
854 Max(aPoly1->DeflectionOverEstimation(), TolConf) +
855 Max(aPoly2->DeflectionOverEstimation(), TolConf);
857 if (nbsamplesOnC2 > nbsamplesOnC1)
859 aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
860 aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
861 aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
865 aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
866 aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
867 aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
871 //----------------------------------------------------------------------
872 //-- if the deflection less then the Tolerance of Confusion
873 //-- Then the deflection of the polygon is set in TolConf
874 //-- (Detection of Tangency Zones)
875 //----------------------------------------------------------------------
877 if(aPoly1->DeflectionOverEstimation() < TolConf) {
878 aPoly1->SetDeflectionOverEstimation(TolConf);
880 if(aPoly2->DeflectionOverEstimation() < TolConf) {
881 aPoly2->SetDeflectionOverEstimation(TolConf);
883 // for case when a few polygon points were replaced by line
884 // if exact solution was not found
885 // then search of precise solution will be repeated
886 // for polygon contains all initial points
887 // secondary search will be performed only for case when initial points
889 Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 &&
890 aPoly2->NbSegments() == nbsamplesOnC2 );
892 if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
893 DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation )
895 if(aPoly1->NbSegments() < nbsamplesOnC1)
897 aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
899 if(aPoly2->NbSegments() < nbsamplesOnC2)
901 aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
904 findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
905 DeltaU, DeltaV, *aPoly1, *aPoly2,
910 done = Standard_True;
913 //======================================================================
914 // Purpose : findIntersect
915 //======================================================================
917 Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect(
919 const IntRes2d_Domain& D1,
921 const IntRes2d_Domain& D2,
922 const Standard_Real TolConf,
923 const Standard_Real Tol,
924 const Standard_Integer NbIter,
925 const Standard_Real DeltaU,
926 const Standard_Real DeltaV,
927 const IntCurve_ThePolygon2d& thePoly1,
928 const IntCurve_ThePolygon2d& thePoly2,
929 Standard_Boolean isFullPolygon )
932 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
934 Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2);
935 IntCurve_ExactIntersectionPoint EIP(C1,C2,TolConf);
936 Standard_Real U = 0., V = 0.;
937 Standard_Boolean AnErrorOccurred = Standard_False;
938 done = Standard_True; // To prevent exception in nbp=NbPoints();
939 //----------------------------------------------------------------------
940 //-- Processing of SectionPoint
941 //----------------------------------------------------------------------
942 Standard_Integer Nbsp = InterPP.NbSectionPoints();
943 for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
944 const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
945 Standard_Integer SegIndex1,SegIndex2;
946 Standard_Real ParamOn1,ParamOn2;
949 SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
950 SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
951 EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
952 AnErrorOccurred = EIP.AnErrorOccurred();
954 if( !EIP.NbRoots() && !isFullPolygon)
955 return Standard_False;
962 //--------------------------------------------------------------------
963 //-- It is checked if the found point is really a root
964 //--------------------------------------------------------------------
967 TheCurveTool::D1(C1,U,P1,Tan1);
968 TheCurveTool::D1(C2,V,P2,Tan2);
969 Standard_Real Dist = P1.Distance(P2);
970 if(EIP.NbRoots() == 0 && Dist > TolConf)
972 IntRes2d_Transition aTrans;
973 IntRes2d_IntersectionPoint aPInt(P1, U, V, aTrans, aTrans, Standard_False);
974 Standard_Real aT1f, aT1l, aT2f, aT2l;
975 aT1f= thePoly1.ApproxParamOnCurve(SegIndex1, 0.0);
976 aT1l= thePoly1.ApproxParamOnCurve(SegIndex1, 1.0);
977 aT2f= thePoly2.ApproxParamOnCurve(SegIndex2, 0.0);
978 aT2l= thePoly2.ApproxParamOnCurve(SegIndex2, 1.0);
980 Standard_Integer aMaxCount = 16, aCount = 0;
981 GetIntersection(C1, aT1f, aT1l, C2, aT2f, aT2l, TolConf, aMaxCount,
982 aPInt, Dist, aCount);
983 U = aPInt.ParamOnFirst();
984 V = aPInt.ParamOnSecond();
985 TheCurveTool::D1(C1,U,P1,Tan1);
986 TheCurveTool::D1(C2,V,P2,Tan2);
987 Dist = P1.Distance(P2);
989 //-----------------------------------------------------------------
990 //-- It is checked if the point (u,v) does not exist already
992 Standard_Integer nbp=NbPoints();
993 Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
994 Standard_Real EpsX2 = 10.0*TheCurveTool::EpsX(C2);
995 for(Standard_Integer p=1; p<=nbp; p++) {
996 const IntRes2d_IntersectionPoint& P=Point(p);
997 if(Abs(U-P.ParamOnFirst()) <= EpsX1) {
998 if(Abs(V-P.ParamOnSecond()) <= EpsX2) {
999 Dist = TolConf+1.0; p+=nbp;
1004 if(Dist <= TolConf) { //-- Or the point is already present
1005 IntRes2d_Position Pos1 = IntRes2d_Middle;
1006 IntRes2d_Position Pos2 = IntRes2d_Middle;
1007 IntRes2d_Transition Trans1,Trans2;
1008 //-----------------------------------------------------------------
1009 //-- Calculate the Positions of Points on the curve
1011 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())
1012 Pos1 = IntRes2d_Head;
1013 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance())
1014 Pos1 = IntRes2d_End;
1016 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())
1017 Pos2 = IntRes2d_Head;
1018 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance())
1019 Pos2 = IntRes2d_End;
1020 //-----------------------------------------------------------------
1021 //-- Calculate the Transitions (see IntImpParGen.cxx)
1023 if(IntImpParGen::DetermineTransition (Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == Standard_False) {
1024 TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
1025 TheCurveTool::D2(C2,V,P2,Tan2,Norm2);
1026 IntImpParGen::DetermineTransition (Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, TolConf);
1028 IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
1033 //----------------------------------------------------------------------
1034 //-- Processing of TangentZone
1035 //----------------------------------------------------------------------
1036 Standard_Integer Nbtz = InterPP.NbTangentZones();
1037 for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
1038 Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
1039 //====================================================================
1040 //== Find the first and the last point in the tangency zone.
1041 //====================================================================
1042 Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
1043 Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
1044 // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
1045 Standard_Integer SegIndex1onP1,SegIndex1onP2;
1047 Standard_Real ParamOnLine;
1048 Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
1049 ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
1050 ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
1051 for(Standard_Integer qq=1;qq<=NbPnts;qq++) {
1052 const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
1053 //====================================================================
1054 //== The zones of tangency are discretized
1055 //== Test of stop : Check if
1056 //== (Deflection < Tolerance)
1057 //== Or (Sample < EpsX) (normally the first condition is
1059 //====================================================================
1060 // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
1061 Standard_Real _PolyUInf,_PolyVInf;
1063 SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
1064 if(SegIndex1onP1 > thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
1065 if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
1066 _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
1068 SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
1069 if(SegIndex1onP2 > thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
1070 if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
1071 _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
1073 //----------------------------------------------------------------------
1075 if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
1076 if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
1078 if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
1079 if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
1082 PolyUInf= ParamInfOnCurve1;
1083 PolyUSup= ParamSupOnCurve1;
1084 PolyVInf= ParamInfOnCurve2;
1085 PolyVSup= ParamSupOnCurve2;
1087 TheCurveTool::D0(C1,PolyUInf,P1);
1088 TheCurveTool::D0(C2,PolyVInf,P2);
1089 Standard_Real distmemesens = P1.SquareDistance(P2);
1090 TheCurveTool::D0(C2,PolyVSup,P2);
1091 Standard_Real distdiffsens = P1.SquareDistance(P2);
1092 if(distmemesens > distdiffsens) {
1093 Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
1096 if( ( (thePoly1.DeflectionOverEstimation() > TolConf)
1097 ||(thePoly2.DeflectionOverEstimation() > TolConf))
1098 &&(NbIter<NBITER_MAX_POLYGON)) {
1100 IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
1101 ,ParamInfOnCurve1,TolConf
1102 ,TheCurveTool::Value(C1,ParamSupOnCurve1)
1103 ,ParamSupOnCurve1,TolConf);
1104 IntRes2d_Domain RecursD2( TheCurveTool::Value(C2,ParamInfOnCurve2)
1105 ,ParamInfOnCurve2,TolConf
1106 ,TheCurveTool::Value(C2,ParamSupOnCurve2)
1107 ,ParamSupOnCurve2,TolConf);
1108 //-- thePoly1(2) are not deleted,
1109 //-- finally they are destroyed.
1110 //-- !! No untimely return !!
1111 Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
1114 //-----------------------------------------------------------------
1115 //-- Calculate Positions of Points on the curve and
1116 //-- Transitions on each limit of the segment
1118 IntRes2d_Position Pos1 = IntRes2d_Middle;
1119 IntRes2d_Position Pos2 = IntRes2d_Middle;
1120 IntRes2d_Transition Trans1,Trans2;
1122 TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
1123 TheCurveTool::D1(C2,PolyVInf,P2,Tan2);
1125 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
1126 Pos1 = IntRes2d_Head;
1128 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
1129 Pos1 = IntRes2d_End;
1131 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
1132 Pos2 = IntRes2d_Head;
1134 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
1135 Pos2 = IntRes2d_End;
1138 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
1139 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1141 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
1142 PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1144 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
1145 PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1148 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1153 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1156 TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
1157 TheCurveTool::D2(C2,PolyVInf,P2,Tan2,Norm2);
1158 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1159 Pos2,Tan2,Norm2,Trans2,TolConf);
1161 IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
1162 ,Trans1,Trans2,Standard_False);
1163 //----------------------------------------------------------------------
1165 if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1))
1166 || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C2)))
1172 TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
1173 TheCurveTool::D1(C2,PolyVSup,P2,Tan2);
1174 Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
1176 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
1177 Pos1 = IntRes2d_Head;
1179 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
1180 Pos1 = IntRes2d_End;
1182 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
1183 Pos2 = IntRes2d_Head;
1185 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
1186 Pos2 = IntRes2d_End;
1190 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
1191 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1193 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
1194 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1196 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
1197 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1200 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1203 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1205 TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
1206 TheCurveTool::D2(C2,PolyVSup,P2,Tan2,Norm2);
1207 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1208 Pos2,Tan2,Norm2,Trans2,TolConf);
1210 IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
1211 ,Trans1,Trans2,Standard_False);
1213 Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
1214 if(ParamInfOnCurve1 > ParamSupOnCurve1) {
1215 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
1219 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
1225 return Standard_True;
1228 //======================================================================
1230 //======================================================================
1232 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
1233 const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l,
1234 const Standard_Real theTolConf,
1235 const Standard_Integer theMaxCount,
1236 IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
1237 Standard_Integer& theCount)
1241 Standard_Real aTol2 = theTolConf*theTolConf;
1242 Standard_Real aPTol1 = Max(100.*Epsilon(Max(Abs(theT1f), Abs(theT1l))), Precision::PConfusion());
1243 Standard_Real aPTol2 = Max(100.*Epsilon(Max(Abs(theT2f), Abs(theT2l))), Precision::PConfusion());
1244 gp_Pnt2d aP1f, aP1l, aP2f, aP2l;
1247 TheCurveTool::D0(theC1, theT1f, aP1f);
1248 TheCurveTool::D0(theC1, theT1l, aP1l);
1251 aB1.Enlarge(theTolConf);
1253 TheCurveTool::D0(theC2, theT2f, aP2f);
1254 TheCurveTool::D0(theC2, theT2l, aP2l);
1257 aB2.Enlarge(theTolConf);
1265 Standard_Boolean isSmall1 = (theT1l - theT1f) <= aPTol1 || aP1f.SquareDistance(aP1l) / 4. <= aTol2;
1266 Standard_Boolean isSmall2 = (theT2l - theT2f) <= aPTol2 || aP2f.SquareDistance(aP2l) / 4. <= aTol2;
1268 if((isSmall1 && isSmall2) || (theCount > theMaxCount))
1270 //Seems to be intersection
1271 //Simple treatment of segment intersection
1272 gp_XY aPnts1[3] = {aP1f.XY(), (aP1f.XY() + aP1l.XY()) / 2., aP1l.XY()};
1273 gp_XY aPnts2[3] = {aP2f.XY(), (aP2f.XY() + aP2l.XY()) / 2., aP2l.XY()};
1274 Standard_Integer i, j, imin = -1, jmin = -1;
1275 Standard_Real dmin = RealLast(), d;
1276 for(i = 0; i < 3; i++)
1278 for(j = 0; j < 3; j++)
1280 d = (aPnts1[i] - aPnts2[j]).SquareModulus();
1302 t1 = (theT1f + theT1l) / 2.;
1316 t2 = (theT2f + theT2l) / 2.;
1323 gp_Pnt2d aPint((aPnts1[imin] + aPnts2[jmin])/2.);
1325 IntRes2d_Transition aTrans1, aTrans2;
1326 thePInt.SetValues(aPint, t1, t2, aTrans1, aTrans2, Standard_False);
1334 Standard_Real aT2m = (theT2l + theT2f) / 2.;
1335 GetIntersection(theC1, theT1f, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1336 GetIntersection(theC1, theT1f, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1340 Standard_Real aT1m = (theT1l + theT1f) / 2.;
1341 GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1342 GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1346 Standard_Real aT1m = (theT1l + theT1f) / 2.;
1347 Standard_Real aT2m = (theT2l + theT2f) / 2.;
1348 GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1349 GetIntersection(theC1, theT1f, aT1m, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1350 GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1351 GetIntersection(theC1, aT1m, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1356 //=======================================================================
1357 //function : GetMinNbPoints
1359 //=======================================================================
1360 Standard_Integer IntCurve_IntPolyPolyGen::GetMinNbSamples() const
1365 //=======================================================================
1366 //function : SetMinNbPoints
1368 //=======================================================================
1369 void IntCurve_IntPolyPolyGen::SetMinNbSamples(const Standard_Integer theMinNbSamples)
1371 myMinPntNb = theMinNbSamples;