0027441: The method IntTools_Context::IsVertexOnLine incorrectly computes parameter...
[occt.git] / src / IntPatch / IntPatch_WLineTool.cxx
CommitLineData
4e14c88f 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
2//
3// This file is part of Open CASCADE Technology software library.
4//
5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
14#include <IntPatch_WLineTool.hxx>
15
16#include <Adaptor3d_HSurface.hxx>
17#include <Adaptor3d_TopolTool.hxx>
b8f67cc2 18#include <ElCLib.hxx>
19
d30895f5 20// It is pure empirical value.
21const Standard_Real IntPatch_WLineTool::myMaxConcatAngle = M_PI/6;
22
b8f67cc2 23//Bit-mask is used for information about
24//the operation made in
25//IntPatch_WLineTool::ExtendTwoWlinesToEachOther() method.
26enum
27{
28 IntPatchWT_EnAll = 0x00,
29 IntPatchWT_DisLastLast = 0x01,
30 IntPatchWT_DisLastFirst = 0x02,
31 IntPatchWT_DisFirstLast = 0x04,
32 IntPatchWT_DisFirstFirst = 0x08
33};
4e14c88f 34
35//=======================================================================
36//function : MinMax
37//purpose : Replaces theParMIN = MIN(theParMIN, theParMAX),
38// theParMAX = MAX(theParMIN, theParMAX).
39//
40// Static subfunction in IsSeamOrBound.
41//=======================================================================
42static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
43{
44 if(theParMIN > theParMAX)
45 {
46 const Standard_Real aTmp = theParMAX;
47 theParMAX = theParMIN;
48 theParMIN = aTmp;
49 }
50}
51
52//=========================================================================
53// function : FillPointsHash
54// purpose : Fill points hash by input data.
55// Static subfunction in ComputePurgedWLine.
56//=========================================================================
57static void FillPointsHash(const Handle(IntPatch_WLine) &theWLine,
58 NCollection_Array1<Standard_Integer> &thePointsHash)
59{
60 // 1 - Delete point.
61 // 0 - Store point.
62 // -1 - Vertex point (not delete).
63 Standard_Integer i, v;
64
65 for(i = 1; i <= theWLine->NbPnts(); i++)
66 thePointsHash.SetValue(i, 0);
67
68 for(v = 1; v <= theWLine->NbVertex(); v++)
69 {
70 IntPatch_Point aVertex = theWLine->Vertex(v);
71 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
72 thePointsHash.SetValue(avertexindex, -1);
73 }
74}
75
76//=========================================================================
77// function : MakeNewWLine
78// purpose : Makes new walking line according to the points hash
79// Static subfunction in ComputePurgedWLine and DeleteOuter.
80//=========================================================================
81static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine) &theWLine,
82 const NCollection_Array1<Standard_Integer> &thePointsHash)
83{
84 Standard_Integer i;
85
86 Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S();
87 Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False);
88 Standard_Integer anOldLineIdx = 1, aVertexIdx = 1;
89 for(i = 1; i <= thePointsHash.Upper(); i++)
90 {
91 if (thePointsHash(i) == 0)
92 {
93 // Store this point.
94 aPurgedLineOn2S->Add(theWLine->Point(i));
95 anOldLineIdx++;
96 }
97 else if (thePointsHash(i) == -1)
98 {
99 // Add vertex.
100 IntPatch_Point aVertex = theWLine->Vertex(aVertexIdx++);
101 aVertex.SetParameter(anOldLineIdx++);
102 aLocalWLine->AddVertex(aVertex);
103 aPurgedLineOn2S->Add(theWLine->Point(i));
104 }
105 }
106
107 return aLocalWLine;
108}
109
110//=========================================================================
111// function : MovePoint
112// purpose : Move point into surface param space. No interpolation used
113// because walking algorithm should care for closeness to the param space.
114// Static subfunction in ComputePurgedWLine.
115//=========================================================================
116static void MovePoint(const Handle(Adaptor3d_HSurface) &theS1,
117 Standard_Real &U1, Standard_Real &V1)
118{
119 if (U1 < theS1->FirstUParameter())
120 U1 = theS1->FirstUParameter();
121
122 if (U1 > theS1->LastUParameter())
123 U1 = theS1->LastUParameter();
124
125 if (V1 < theS1->FirstVParameter())
126 V1 = theS1->FirstVParameter();
127
128 if (V1 > theS1->LastVParameter())
129 V1 = theS1->LastVParameter();
130}
131
132//=========================================================================
133// function : DeleteOuterPoints
134// purpose : Check and delete out of bounds points on walking line.
135// Static subfunction in ComputePurgedWLine.
136//=========================================================================
137static Handle(IntPatch_WLine)
138 DeleteOuterPoints(const Handle(IntPatch_WLine) &theWLine,
139 const Handle(Adaptor3d_HSurface) &theS1,
140 const Handle(Adaptor3d_HSurface) &theS2,
141 const Handle(Adaptor3d_TopolTool) &theDom1,
142 const Handle(Adaptor3d_TopolTool) &theDom2)
143{
144 Standard_Integer i;
145
146 NCollection_Array1<Standard_Integer> aDelOuterPointsHash(1, theWLine->NbPnts());
147 FillPointsHash(theWLine, aDelOuterPointsHash);
148
149 if (theS1->IsUPeriodic() || theS1->IsVPeriodic() ||
150 theS2->IsUPeriodic() || theS2->IsVPeriodic() )
151 return theWLine;
152
153 gp_Pnt2d aPntOnF1, aPntOnF2;
154 Standard_Real aX1, aY1, aX2, aY2;
155
156 // Iterate over points in walking line and delete which are out of bounds.
157 // Forward.
158 Standard_Boolean isAllDeleted = Standard_True;
159 Standard_Boolean aChangedFirst = Standard_False;
160 Standard_Integer aFirstGeomIdx = 1;
161 for(i = 1; i <= theWLine->NbPnts(); i++)
162 {
163 theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2);
164 aPntOnF1.SetCoord(aX1, aY1);
165 aPntOnF2.SetCoord(aX2, aY2);
166
167 TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion());
168 TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion());
169
170 if (aState1 == TopAbs_OUT ||
171 aState2 == TopAbs_OUT )
172 {
173 aDelOuterPointsHash(i) = 1;
174 aChangedFirst = Standard_True;
175 }
176 else
177 {
178 isAllDeleted = Standard_False;
179
180 aFirstGeomIdx = Max (i - 1, 1);
181 if (aDelOuterPointsHash(i) == -1)
182 aFirstGeomIdx = i; // Use data what lies in (i) point / vertex.
183
184 aDelOuterPointsHash(i) = -1;
185 break;
186 }
187 }
188
189 if (isAllDeleted)
190 {
191 // ALL points are out of bounds:
192 // case boolean bcut_complex F5 and similar.
193 return theWLine;
194 }
195
196 // Backward.
197 Standard_Boolean aChangedLast = Standard_False;
198 Standard_Integer aLastGeomIdx = theWLine->NbPnts();
199 for(i = theWLine->NbPnts(); i >= 1; i--)
200 {
201 theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2);
202 aPntOnF1.SetCoord(aX1, aY1);
203 aPntOnF2.SetCoord(aX2, aY2);
204
205 TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion());
206 TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion());
207
208 if (aState1 == TopAbs_OUT ||
209 aState2 == TopAbs_OUT )
210 {
211 aDelOuterPointsHash(i) = 1;
212 aChangedLast = Standard_True; // Move vertex to first good point
213 }
214 else
215 {
216 aLastGeomIdx = Min (i + 1, theWLine->NbPnts());
217 if (aDelOuterPointsHash(i) == -1)
218 aLastGeomIdx = i; // Use data what lies in (i) point / vertex.
219
220 aDelOuterPointsHash(i) = -1;
221 break;
222 }
223 }
224
225 if (!aChangedFirst && !aChangedLast)
226 {
227 // Nothing is done, return input.
228 return theWLine;
229 }
230
231 // Build new line and modify geometry of necessary vertexes.
232 Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash);
233
234 if (aChangedFirst)
235 {
236 // Vertex geometry.
237 IntPatch_Point aVertex = aLocalWLine->Vertex(1);
238 aVertex.SetValue(theWLine->Point(aFirstGeomIdx).Value());
239 Standard_Real aU1, aU2, aV1, aV2;
240 theWLine->Point(aFirstGeomIdx).Parameters(aU1, aV1, aU2, aV2);
241 MovePoint(theS1, aU1, aV1);
242 MovePoint(theS2, aU2, aV2);
243 aVertex.SetParameters(aU1, aV1, aU2, aV2);
244 aLocalWLine->Replace(1, aVertex);
245 // Change point in walking line.
246 aLocalWLine->SetPoint(1, aVertex);
247 }
248
249 if (aChangedLast)
250 {
251 // Vertex geometry.
252 IntPatch_Point aVertex = aLocalWLine->Vertex(aLocalWLine->NbVertex());
253 aVertex.SetValue(theWLine->Point(aLastGeomIdx).Value());
254 Standard_Real aU1, aU2, aV1, aV2;
255 theWLine->Point(aLastGeomIdx).Parameters(aU1, aV1, aU2, aV2);
256 MovePoint(theS1, aU1, aV1);
257 MovePoint(theS2, aU2, aV2);
258 aVertex.SetParameters(aU1, aV1, aU2, aV2);
259 aLocalWLine->Replace(aLocalWLine->NbVertex(), aVertex);
260 // Change point in walking line.
261 aLocalWLine->SetPoint(aLocalWLine->NbPnts(), aVertex);
262 }
263
264
265 return aLocalWLine;
266}
267
268//=========================================================================
269// function : IsInsideIn2d
270// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec.
271// In 2d space. Static subfunction in DeleteByTube.
272//=========================================================================
273static Standard_Boolean IsInsideIn2d(const gp_Pnt2d& aBasePnt,
274 const gp_Vec2d& aBaseVec,
275 const gp_Pnt2d& aNextPnt,
276 const Standard_Real aSquareMaxDist)
277{
278 gp_Vec2d aVec2d(aBasePnt, aNextPnt);
279
280 //d*d = (basevec^(nextpnt-basepnt))**2 / basevec**2
281 Standard_Real aCross = aVec2d.Crossed(aBaseVec);
282 Standard_Real aSquareDist = aCross * aCross
283 / aBaseVec.SquareMagnitude();
284
285 return (aSquareDist <= aSquareMaxDist);
286}
287
288//=========================================================================
289// function : IsInsideIn3d
290// purpose : Check if aNextPnt lies inside of tube build on aBasePnt and aBaseVec.
291// In 3d space. Static subfunction in DeleteByTube.
292//=========================================================================
293static Standard_Boolean IsInsideIn3d(const gp_Pnt& aBasePnt,
294 const gp_Vec& aBaseVec,
295 const gp_Pnt& aNextPnt,
296 const Standard_Real aSquareMaxDist)
297{
298 gp_Vec aVec(aBasePnt, aNextPnt);
299
300 //d*d = (basevec^(nextpnt-basepnt))**2 / basevec**2
301 Standard_Real aSquareDist = aVec.CrossSquareMagnitude(aBaseVec)
302 / aBaseVec.SquareMagnitude();
303
304 return (aSquareDist <= aSquareMaxDist);
305}
306
307static const Standard_Integer aMinNbBadDistr = 15;
308static const Standard_Integer aNbSingleBezier = 30;
309
310//=========================================================================
311// function : DeleteByTube
312// purpose : Check and delete points using tube criteria.
313// Static subfunction in ComputePurgedWLine.
314//=========================================================================
315static Handle(IntPatch_WLine)
316 DeleteByTube(const Handle(IntPatch_WLine) &theWLine,
317 const Handle(Adaptor3d_HSurface) &theS1,
318 const Handle(Adaptor3d_HSurface) &theS2)
319{
320 // III: Check points for tube criteria:
321 // Workaround to handle case of small amount points after purge.
322 // Test "boolean boptuc_complex B5" and similar.
323 Standard_Integer aNbPnt = 0 , i;
324
325 if (theWLine->NbPnts() <= 2)
326 return theWLine;
327
328 NCollection_Array1<Standard_Integer> aNewPointsHash(1, theWLine->NbPnts());
329 FillPointsHash(theWLine, aNewPointsHash);
330
331 // Inital computations.
332 Standard_Real UonS1[3], VonS1[3], UonS2[3], VonS2[3];
333 theWLine->Point(1).ParametersOnS1(UonS1[0], VonS1[0]);
334 theWLine->Point(2).ParametersOnS1(UonS1[1], VonS1[1]);
335 theWLine->Point(1).ParametersOnS2(UonS2[0], VonS2[0]);
336 theWLine->Point(2).ParametersOnS2(UonS2[1], VonS2[1]);
337
338 gp_Pnt2d aBase2dPnt1(UonS1[0], VonS1[0]);
339 gp_Pnt2d aBase2dPnt2(UonS2[0], VonS2[0]);
340 gp_Vec2d aBase2dVec1(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0]);
341 gp_Vec2d aBase2dVec2(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0]);
342 gp_Pnt aBase3dPnt = theWLine->Point(1).Value();
343 gp_Vec aBase3dVec(theWLine->Point(1).Value(), theWLine->Point(2).Value());
344
345 // Choose base tolerance and scale it to pipe algorithm.
346 const Standard_Real aBaseTolerance = Precision::Approximation();
347 Standard_Real aResS1Tol = Min(theS1->UResolution(aBaseTolerance),
348 theS1->VResolution(aBaseTolerance));
349 Standard_Real aResS2Tol = Min(theS2->UResolution(aBaseTolerance),
350 theS2->VResolution(aBaseTolerance));
351 Standard_Real aTol1 = aResS1Tol * aResS1Tol;
352 Standard_Real aTol2 = aResS2Tol * aResS2Tol;
353 Standard_Real aTol3d = aBaseTolerance * aBaseTolerance;
354
355 const Standard_Real aLimitCoeff = 0.99 * 0.99;
356 for(i = 3; i <= theWLine->NbPnts(); i++)
357 {
358 Standard_Boolean isDeleteState = Standard_False;
359
360 theWLine->Point(i).ParametersOnS1(UonS1[2], VonS1[2]);
361 theWLine->Point(i).ParametersOnS2(UonS2[2], VonS2[2]);
362 gp_Pnt2d aPnt2dOnS1(UonS1[2], VonS1[2]);
363 gp_Pnt2d aPnt2dOnS2(UonS2[2], VonS2[2]);
364 const gp_Pnt& aPnt3d = theWLine->Point(i).Value();
365
366 if (aNewPointsHash(i - 1) != - 1 &&
367 IsInsideIn2d(aBase2dPnt1, aBase2dVec1, aPnt2dOnS1, aTol1) &&
368 IsInsideIn2d(aBase2dPnt2, aBase2dVec2, aPnt2dOnS2, aTol2) &&
369 IsInsideIn3d(aBase3dPnt, aBase3dVec, aPnt3d, aTol3d) )
370 {
371 // Handle possible uneven parametrization on one of 2d subspaces.
372 // Delete point only when expected lengths are close to each other (aLimitCoeff).
373 // Example:
374 // c2d1 - line
375 // c3d - line
376 // c2d2 - geometrically line, but have uneven parametrization -> c2d2 is bspline.
377 gp_XY aPntOnS1[2]= { gp_XY(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0])
378 , gp_XY(UonS1[2] - UonS1[1], VonS1[2] - VonS1[1])};
379 gp_XY aPntOnS2[2]= { gp_XY(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0])
380 , gp_XY(UonS2[2] - UonS2[1], VonS2[2] - VonS2[1])};
381
382 Standard_Real aStepOnS1 = aPntOnS1[0].SquareModulus() / aPntOnS1[1].SquareModulus();
383 Standard_Real aStepOnS2 = aPntOnS2[0].SquareModulus() / aPntOnS2[1].SquareModulus();
384
871776ea 385 // Check very rare case when wline fluctuates nearly one point and some of them may be equal.
386 // Middle point will be deleted when such situation occurs.
387 // bugs moddata_2 bug469.
388 if (Min(aStepOnS1, aStepOnS2) >= aLimitCoeff * Max(aStepOnS1, aStepOnS2))
4e14c88f 389 {
390 // Set hash flag to "Delete" state.
391 isDeleteState = Standard_True;
392 aNewPointsHash.SetValue(i - 1, 1);
393
394 // Change middle point.
395 UonS1[1] = UonS1[2];
396 UonS2[1] = UonS2[2];
397 VonS1[1] = VonS1[2];
398 VonS2[1] = VonS2[2];
399 }
400 }
401
402 if (!isDeleteState)
403 {
404 // Compute new pipe parameters.
405 UonS1[0] = UonS1[1];
406 VonS1[0] = VonS1[1];
407 UonS2[0] = UonS2[1];
408 VonS2[0] = VonS2[1];
409
410 UonS1[1] = UonS1[2];
411 VonS1[1] = VonS1[2];
412 UonS2[1] = UonS2[2];
413 VonS2[1] = VonS2[2];
414
415 aBase2dPnt1.SetCoord(UonS1[0], VonS1[0]);
416 aBase2dPnt2.SetCoord(UonS2[0], VonS2[0]);
417 aBase2dVec1.SetCoord(UonS1[1] - UonS1[0], VonS1[1] - VonS1[0]);
418 aBase2dVec2.SetCoord(UonS2[1] - UonS2[0], VonS2[1] - VonS2[0]);
419 aBase3dPnt = theWLine->Point(i - 1).Value();
420 aBase3dVec = gp_Vec(theWLine->Point(i - 1).Value(), theWLine->Point(i).Value());
421
422 aNbPnt++;
423 }
424 }
425
426 // Workaround to handle case of small amount of points after purge.
427 // Test "boolean boptuc_complex B5" and similar.
428 // This is possible since there are at least two points.
429 if (aNewPointsHash(1) == -1 &&
430 aNewPointsHash(2) == -1 &&
431 aNbPnt <= 3)
432 {
433 // Delete first.
434 aNewPointsHash(1) = 1;
435 }
436 if (aNewPointsHash(theWLine->NbPnts() - 1) == -1 &&
437 aNewPointsHash(theWLine->NbPnts() ) == -1 &&
438 aNbPnt <= 3)
439 {
440 // Delete last.
441 aNewPointsHash(theWLine->NbPnts()) = 1;
442 }
443
444 // Purgre when too small amount of points left.
445 if (aNbPnt <= 2)
446 {
447 for(i = aNewPointsHash.Lower(); i <= aNewPointsHash.Upper(); i++)
448 {
449 if (aNewPointsHash(i) != -1)
450 {
451 aNewPointsHash(i) = 1;
452 }
453 }
454 }
455
456 // Handle possible bad distribution of points,
457 // which are will converted into one single bezier curve (less than 30 points).
458 // Make distribution more even:
459 // max step will be nearly to 0.1 of param distance.
460 if (aNbPnt + 2 > aMinNbBadDistr &&
461 aNbPnt + 2 < aNbSingleBezier )
462 {
463 for(Standard_Integer anIdx = 1; anIdx <= 8; anIdx++)
464 {
465 Standard_Integer aHashIdx =
466 Standard_Integer(anIdx * theWLine->NbPnts() / 9);
467
47e3009d 468 //Vertex must be stored as VERTEX (HASH = -1)
469 if (aNewPointsHash(aHashIdx) != -1)
470 aNewPointsHash(aHashIdx) = 0;
4e14c88f 471 }
472 }
473
474 return MakeNewWLine(theWLine, aNewPointsHash);
475}
476
477//=======================================================================
b8f67cc2 478//function : IsOnPeriod
479//purpose : Checks, if [theU1, theU2] intersects the period-value
480// (k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...).
481//
482// Returns:
483// 0 - if interval [theU1, theU2] does not intersect the "period-value"
484// or if thePeriod == 0.0;
485// 1 - if interval (theU1, theU2) intersect the "period-value".
486// 2 - if theU1 or/and theU2 lie ON the "period-value"
4e14c88f 487//
488//ATTENTION!!!
489// If (theU1 == theU2) then this function will return only both 0 or 2.
4e14c88f 490//=======================================================================
b8f67cc2 491static Standard_Integer IsOnPeriod(const Standard_Real theU1,
492 const Standard_Real theU2,
493 const Standard_Real thePeriod)
4e14c88f 494{
b8f67cc2 495 if(thePeriod < RealSmall())
4e14c88f 496 return 0;
497
498 //If interval [theU1, theU2] intersect seam-edge then there exists an integer
499 //number N such as
500 // (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T),
501 //where T is the period.
502 //I.e. the inerval [theU1/T, theU2/T] must contain at least one
503 //integer number. In this case, Floor(theU1/T) and Floor(theU2/T)
504 //return different values or theU1/T is strictly integer number.
505 //Examples:
506 // 1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3.
507 // 2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2.
508
509 const Standard_Real aVal1 = theU1/thePeriod,
510 aVal2 = theU2/thePeriod;
511 const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
512 const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
513 if(aPar1 != aPar2)
514 {//Interval (theU1, theU2] intersects seam-edge
515 if(IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
516 {//aVal2 is an integer number => theU2 lies ON the "seam-edge"
517 return 2;
518 }
519
520 return 1;
521 }
522
523 //Here, aPar1 == aPar2.
524
525 if(IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
526 {//aVal1 is an integer number => theU1 lies ON the "seam-edge"
527 return 2;
528 }
529
530 //If aVal2 is a true integer number then always (aPar1 != aPar2).
531
532 return 0;
533}
534
535//=======================================================================
536//function : IsSeamOrBound
537//purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge"
538// (if it exist) or surface boundaries and both thePtf and thePtl do
539// not match "seam-edge" or boundaries.
eee615ad 540// Point thePtmid lies in this segment (in both 3D and 2D-space).
541// If thePtmid match "seam-edge" or boundaries strictly
542// (without any tolerance) then the function will return TRUE.
4e14c88f 543// See comments in function body for detail information.
4e14c88f 544//=======================================================================
545static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
546 const IntSurf_PntOn2S& thePtl,
547 const IntSurf_PntOn2S& thePtmid,
548 const Standard_Real theU1Period,
549 const Standard_Real theU2Period,
550 const Standard_Real theV1Period,
551 const Standard_Real theV2Period,
552 const Standard_Real theUfSurf1,
553 const Standard_Real theUlSurf1,
554 const Standard_Real theVfSurf1,
555 const Standard_Real theVlSurf1,
556 const Standard_Real theUfSurf2,
557 const Standard_Real theUlSurf2,
558 const Standard_Real theVfSurf2,
559 const Standard_Real theVlSurf2)
560{
561 Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
562 Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
563 thePtf.Parameters(aU11, aV11, aU12, aV12);
564 thePtl.Parameters(aU21, aV21, aU22, aV22);
565
566 MinMax(aU11, aU21);
567 MinMax(aV11, aV21);
568 MinMax(aU12, aU22);
569 MinMax(aV12, aV22);
570
571 if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0)
572 {//Interval [aU11, aU21] intersects theUfSurf1
573 return Standard_True;
574 }
575
576 if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0)
577 {//Interval [aU11, aU21] intersects theUlSurf1
578 return Standard_True;
579 }
580
581 if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0)
582 {//Interval [aV11, aV21] intersects theVfSurf1
583 return Standard_True;
584 }
585
586 if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0)
587 {//Interval [aV11, aV21] intersects theVlSurf1
588 return Standard_True;
589 }
590
591 if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0)
592 {//Interval [aU12, aU22] intersects theUfSurf2
593 return Standard_True;
594 }
595
596 if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0)
597 {//Interval [aU12, aU22] intersects theUlSurf2
598 return Standard_True;
599 }
600
601 if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0)
602 {//Interval [aV12, aV22] intersects theVfSurf2
603 return Standard_True;
604 }
605
606 if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0)
607 {//Interval [aV12, aV22] intersects theVlSurf2
608 return Standard_True;
609 }
610
b8f67cc2 611 if(IsOnPeriod(aU11, aU21, theU1Period))
4e14c88f 612 return Standard_True;
613
b8f67cc2 614 if(IsOnPeriod(aV11, aV21, theV1Period))
4e14c88f 615 return Standard_True;
616
b8f67cc2 617 if(IsOnPeriod(aU12, aU22, theU2Period))
4e14c88f 618 return Standard_True;
619
b8f67cc2 620 if(IsOnPeriod(aV12, aV22, theV2Period))
4e14c88f 621 return Standard_True;
622
623 /*
624 The segment [thePtf, thePtl] does not intersect the boundaries and
625 the seam-edge of the surfaces.
626 Nevertheless, following situation is possible:
627
628 seam or
629 bound
630 |
631 thePtf * |
632 |
633 * thePtmid
634 thePtl * |
635 |
636
637 This case must be processed, too.
638 */
639
640 Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
641 thePtmid.Parameters(aU1, aV1, aU2, aV2);
642
643 if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1))
644 return Standard_True;
645
646 if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2))
647 return Standard_True;
648
649 if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1))
650 return Standard_True;
651
652 if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2))
653 return Standard_True;
654
b8f67cc2 655 if(IsOnPeriod(aU1, aU1, theU1Period))
4e14c88f 656 return Standard_True;
657
b8f67cc2 658 if(IsOnPeriod(aU2, aU2, theU2Period))
4e14c88f 659 return Standard_True;
660
b8f67cc2 661 if(IsOnPeriod(aV1, aV1, theV1Period))
4e14c88f 662 return Standard_True;
663
b8f67cc2 664 if(IsOnPeriod(aV2, aV2, theV2Period))
4e14c88f 665 return Standard_True;
666
667 return Standard_False;
668}
669
eee615ad 670//=======================================================================
671//function : AbjustPeriodicToPrevPoint
672//purpose : Returns theCurrentParam in order to the distance betwen
673// theRefParam and theCurrentParam is less than 0.5*thePeriod.
674//=======================================================================
675static void AbjustPeriodicToPrevPoint(const Standard_Real theRefParam,
676 const Standard_Real thePeriod,
677 Standard_Real& theCurrentParam)
678{
679 if(thePeriod == 0.0)
680 return;
681
682 Standard_Real aDeltaPar = 2.0*(theRefParam - theCurrentParam);
683 const Standard_Real anIncr = Sign(thePeriod, aDeltaPar);
684 while(Abs(aDeltaPar) > thePeriod)
685 {
686 theCurrentParam += anIncr;
687 aDeltaPar = 2.0*(theRefParam-theCurrentParam);
688 }
689}
690
691//=======================================================================
692//function : IsIntersectionPoint
693//purpose : Returns True if thePmid is intersection point
694// between theS1 and theS2 with given tolerance.
695// In this case, parameters of thePmid on every quadric
696// will be recomputed and returned.
697//=======================================================================
698static Standard_Boolean IsIntersectionPoint(const gp_Pnt& thePmid,
699 const IntSurf_Quadric& theS1,
700 const IntSurf_Quadric& theS2,
701 const IntSurf_PntOn2S& theRefPt,
702 const Standard_Real theTol,
703 const Standard_Real theU1Period,
704 const Standard_Real theU2Period,
705 const Standard_Real theV1Period,
706 const Standard_Real theV2Period,
707 Standard_Real &theU1,
708 Standard_Real &theV1,
709 Standard_Real &theU2,
710 Standard_Real &theV2)
711{
712 Standard_Real aU1Ref = 0.0, aV1Ref = 0.0, aU2Ref = 0.0, aV2Ref = 0.0;
713 theRefPt.Parameters(aU1Ref, aV1Ref, aU2Ref, aV2Ref);
714 theS1.Parameters(thePmid, theU1, theV1);
715 theS2.Parameters(thePmid, theU2, theV2);
716
717 AbjustPeriodicToPrevPoint(aU1Ref, theU1Period, theU1);
718 AbjustPeriodicToPrevPoint(aV1Ref, theV1Period, theV1);
719 AbjustPeriodicToPrevPoint(aU2Ref, theU2Period, theU2);
720 AbjustPeriodicToPrevPoint(aV2Ref, theV2Period, theV2);
721
722 const gp_Pnt aP1(theS1.Value(theU1, theV1));
723 const gp_Pnt aP2(theS2.Value(theU2, theV2));
724
725 return (aP1.SquareDistance(aP2) <= theTol*theTol);
726}
727
728//=======================================================================
729//function : ExtendFirst
730//purpose : Adds thePOn2S to the begin of theWline
731//=======================================================================
732static void ExtendFirst(const Handle(IntPatch_WLine)& theWline,
b8f67cc2 733 const IntSurf_PntOn2S& theAddedPt)
eee615ad 734{
b8f67cc2 735 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
736 theAddedPt.Parameters(aU1, aV1, aU2, aV2);
eee615ad 737
b8f67cc2 738 if(theAddedPt.IsSame(theWline->Point(1), Precision::Confusion()))
739 {
740 theWline->Curve()->Value(1, theAddedPt);
741 for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++)
742 {
743 IntPatch_Point &aVert = theWline->ChangeVertex(i);
744 if(aVert.ParameterOnLine() != 1)
745 break;
eee615ad 746
b8f67cc2 747 aVert.SetParameters(aU1, aV1, aU2, aV2);
748 aVert.SetValue(theAddedPt.Value());
749 }
750
751 return;
752 }
eee615ad 753
b8f67cc2 754 theWline->Curve()->InsertBefore(1, theAddedPt);
eee615ad 755
b8f67cc2 756 for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++)
eee615ad 757 {
b8f67cc2 758 IntPatch_Point &aVert = theWline->ChangeVertex(i);
759
760 if(aVert.ParameterOnLine() == 1)
761 {
762 aVert.SetParameters(aU1, aV1, aU2, aV2);
763 aVert.SetValue(theAddedPt.Value());
764 }
765 else
766 {
767 aVert.SetParameter(aVert.ParameterOnLine()+1);
768 }
eee615ad 769 }
770}
771
772//=======================================================================
773//function : ExtendLast
774//purpose : Adds thePOn2S to the end of theWline
775//=======================================================================
776static void ExtendLast(const Handle(IntPatch_WLine)& theWline,
b8f67cc2 777 const IntSurf_PntOn2S& theAddedPt)
eee615ad 778{
b8f67cc2 779 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
780 theAddedPt.Parameters(aU1, aV1, aU2, aV2);
781
782 const Standard_Integer aNbPnts = theWline->NbPnts();
783 if(theAddedPt.IsSame(theWline->Point(aNbPnts), Precision::Confusion()))
784 {
785 theWline->Curve()->Value(aNbPnts, theAddedPt);
786 }
787 else
788 {
789 theWline->Curve()->Add(theAddedPt);
790 }
eee615ad 791
b8f67cc2 792 for(Standard_Integer i = theWline->NbVertex(); i >= 1; i--)
793 {
794 IntPatch_Point &aVert = theWline->ChangeVertex(i);
795 if(aVert.ParameterOnLine() != aNbPnts)
796 break;
eee615ad 797
b8f67cc2 798 aVert.SetParameters(aU1, aV1, aU2, aV2);
799 aVert.SetValue(theAddedPt.Value());
800 aVert.SetParameter(theWline->NbPnts());
801 }
802}
803
804//=========================================================================
805// function: IsOutOfDomain
806// purpose : Checks, if 2D-representation of thePOn2S is in surfaces domain,
807// defined by bounding-boxes theBoxS1 and theBoxS2
808//=========================================================================
809static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1,
810 const Bnd_Box2d& theBoxS2,
811 const IntSurf_PntOn2S &thePOn2S,
812 const Standard_Real theU1Period,
813 const Standard_Real theU2Period,
814 const Standard_Real theV1Period,
815 const Standard_Real theV2Period)
816{
eee615ad 817 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
b8f67cc2 818 Standard_Real aU1min = 0.0, aU1max = 0.0, aV1min = 0.0, aV1max = 0.0;
819 Standard_Real aU2min = 0.0, aU2max = 0.0, aV2min = 0.0, aV2max = 0.0;
820
eee615ad 821 thePOn2S.Parameters(aU1, aV1, aU2, aV2);
822
b8f67cc2 823 theBoxS1.Get(aU1min, aV1min, aU1max, aV1max);
824 theBoxS2.Get(aU2min, aV2min, aU2max, aV2max);
825
826 aU1 = ElCLib::InPeriod(aU1, aU1min, aU1min + theU1Period);
827 aV1 = ElCLib::InPeriod(aV1, aV1min, aV1min + theV1Period);
828 aU2 = ElCLib::InPeriod(aU2, aU2min, aU2min + theU2Period);
829 aV2 = ElCLib::InPeriod(aV2, aV2min, aV2min + theV2Period);
830
831 return (theBoxS1.IsOut(gp_Pnt2d(aU1, aV1)) ||
832 theBoxS2.IsOut(gp_Pnt2d(aU2, aV2)));
833}
834
835//=======================================================================
d30895f5 836//function : CheckArgumentsToExtend
b8f67cc2 837//purpose : Check if extending is possible
838// (see IntPatch_WLineTool::ExtendTwoWlinesToEachOther)
839//=======================================================================
d30895f5 840Standard_Boolean CheckArgumentsToExtend(const IntSurf_Quadric& theS1,
841 const IntSurf_Quadric& theS2,
842 const IntSurf_PntOn2S& thePtWL1,
843 const IntSurf_PntOn2S& thePtWL2,
844 IntSurf_PntOn2S& theNewPoint,
845 const gp_Vec& theVec1,
846 const gp_Vec& theVec2,
847 const gp_Vec& theVec3,
848 const Bnd_Box2d& theBoxS1,
849 const Bnd_Box2d& theBoxS2,
850 const Standard_Real theToler3D,
851 const Standard_Real theU1Period,
852 const Standard_Real theU2Period,
853 const Standard_Real theV1Period,
854 const Standard_Real theV2Period)
b8f67cc2 855{
b8f67cc2 856 const Standard_Real aSqToler = theToler3D*theToler3D;
857
858 if(theVec3.SquareMagnitude() <= aSqToler)
859 {
860 return Standard_False;
861 }
862
d30895f5 863 if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
864 (theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
865 (theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
b8f67cc2 866 {
867 return Standard_False;
868 }
869
870 const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
871
872 Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0;
873
874 theBoxS1.Get(aU1, aV1, aU2, aV2);
875 const Standard_Real aU1f = aU1, aV1f = aV1;
876 theBoxS2.Get(aU1, aV1, aU2, aV2);
877 const Standard_Real aU2f = aU1, aV2f = aV1;
878
879 if(!IsIntersectionPoint(aPmid, theS1, theS2, thePtWL1, theToler3D,
880 theU1Period, theU2Period, theV1Period, theV2Period,
881 aU1, aV1, aU2, aV2))
882 {
883 return Standard_False;
884 }
885
886 theNewPoint.SetValue(aPmid, aU1, aV1, aU2, aV2);
887
888 if(IsOutOfDomain(theBoxS1, theBoxS2, theNewPoint,
889 theU1Period, theU2Period,
890 theV1Period, theV2Period))
891 {
892 return Standard_False;
893 }
894
895 Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
896 aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
897
898 thePtWL1.Parameters(aU11, aV11, aU21, aV21);
899 thePtWL2.Parameters(aU12, aV12, aU22, aV22);
900
901 if(IsOnPeriod(aU11 - aU1f, aU12 - aU1f, theU1Period) ||
902 IsOnPeriod(aV11 - aV1f, aV12 - aV1f, theV1Period) ||
903 IsOnPeriod(aU21 - aU2f, aU22 - aU2f, theU2Period) ||
904 IsOnPeriod(aV21 - aV2f, aV22 - aV2f, theV2Period))
905 {
906 return Standard_False;
907 }
908
909 return Standard_True;
910}
911
d30895f5 912//=======================================================================
913//function : CheckArgumentsToJoin
914//purpose : Check if joining is possible
915// (see IntPatch_WLineTool::JoinWLines)
916//=======================================================================
917Standard_Boolean CheckArgumentsToJoin(const gp_Vec& theVec1,
918 const gp_Vec& theVec2)
919{
920 // [0, PI] - range
921 const Standard_Real anAngle = theVec1.Angle(theVec2);
922
923 return (anAngle < IntPatch_WLineTool::myMaxConcatAngle);
924}
925
b8f67cc2 926//=======================================================================
927//function : ExtendTwoWLFirstFirst
928//purpose : Performs extending theWLine1 and theWLine2 through their
929// respecting start point.
930//=======================================================================
931static void ExtendTwoWLFirstFirst(const IntSurf_Quadric& theS1,
932 const IntSurf_Quadric& theS2,
933 const Handle(IntPatch_WLine)& theWLine1,
934 const Handle(IntPatch_WLine)& theWLine2,
935 const IntSurf_PntOn2S& thePtWL1,
936 const IntSurf_PntOn2S& thePtWL2,
937 const gp_Vec& theVec1,
938 const gp_Vec& theVec2,
939 const gp_Vec& theVec3,
940 const Bnd_Box2d& theBoxS1,
941 const Bnd_Box2d& theBoxS2,
942 const Standard_Real theToler3D,
943 const Standard_Real theU1Period,
944 const Standard_Real theU2Period,
945 const Standard_Real theV1Period,
946 const Standard_Real theV2Period,
947 unsigned int &theCheckResult,
948 Standard_Boolean &theHasBeenJoined)
949{
950 IntSurf_PntOn2S aPOn2S;
d30895f5 951 if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
952 theVec1, theVec2, theVec3,
953 theBoxS1, theBoxS2, theToler3D,
954 theU1Period, theU2Period, theV1Period, theV2Period))
b8f67cc2 955 {
956 return;
957 }
958
959 theCheckResult |= (IntPatchWT_DisFirstLast | IntPatchWT_DisLastFirst);
960
961 ExtendFirst(theWLine1, aPOn2S);
962 ExtendFirst(theWLine2, aPOn2S);
963
964 if(theHasBeenJoined)
965 return;
966
967 Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
968 while(theWLine1->Vertex(1).ParameterOnLine() == aPrm)
969 theWLine1->RemoveVertex(1);
970
971 aPrm = theWLine2->Vertex(1).ParameterOnLine();
972 while(theWLine2->Vertex(1).ParameterOnLine() == aPrm)
973 theWLine2->RemoveVertex(1);
974
975 const Standard_Integer aNbPts = theWLine2->NbPnts();
976 for(Standard_Integer aNPt = 2; aNPt <= aNbPts; aNPt++)
977 {
978 const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
979 theWLine1->Curve()->InsertBefore(1, aPt);
980 }
981
982 for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++)
983 {
984 IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx);
985 const Standard_Real aCurParam = aVert.ParameterOnLine();
986 aVert.SetParameter(aNbPts+aCurParam-1);
987 }
988
989 for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++)
990 {
991 IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
992 const Standard_Real aCurParam = aVert.ParameterOnLine();
993 aVert.SetParameter(aNbPts-aCurParam+1);
994 theWLine1->AddVertex(aVert, Standard_True);
995 }
996
997 theHasBeenJoined = Standard_True;
998}
999
1000//=======================================================================
1001//function : ExtendTwoWLFirstLast
1002//purpose : Performs extending theWLine1 through its start point and theWLine2
1003// through its end point.
1004//=======================================================================
1005static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1,
1006 const IntSurf_Quadric& theS2,
1007 const Handle(IntPatch_WLine)& theWLine1,
1008 const Handle(IntPatch_WLine)& theWLine2,
1009 const IntSurf_PntOn2S& thePtWL1,
1010 const IntSurf_PntOn2S& thePtWL2,
1011 const gp_Vec& theVec1,
1012 const gp_Vec& theVec2,
1013 const gp_Vec& theVec3,
1014 const Bnd_Box2d& theBoxS1,
1015 const Bnd_Box2d& theBoxS2,
1016 const Standard_Real theToler3D,
1017 const Standard_Real theU1Period,
1018 const Standard_Real theU2Period,
1019 const Standard_Real theV1Period,
1020 const Standard_Real theV2Period,
1021 unsigned int &theCheckResult,
1022 Standard_Boolean &theHasBeenJoined)
1023{
1024 IntSurf_PntOn2S aPOn2S;
d30895f5 1025 if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
1026 theVec1, theVec2, theVec3,
1027 theBoxS1, theBoxS2, theToler3D,
1028 theU1Period, theU2Period, theV1Period, theV2Period))
b8f67cc2 1029 {
1030 return;
1031 }
1032
1033 theCheckResult |= IntPatchWT_DisLastLast;
1034
1035 ExtendFirst(theWLine1, aPOn2S);
1036 ExtendLast (theWLine2, aPOn2S);
1037
1038 if(theHasBeenJoined)
1039 return;
1040
1041 Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
1042 while(theWLine1->Vertex(1).ParameterOnLine() == aPrm)
1043 theWLine1->RemoveVertex(1);
1044
1045 aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine();
1046 while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm)
1047 theWLine2->RemoveVertex(theWLine2->NbVertex());
1048
1049 const Standard_Integer aNbPts = theWLine2->NbPnts();
1050 for(Standard_Integer aNPt = aNbPts - 1; aNPt >= 1; aNPt--)
1051 {
1052 const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
1053 theWLine1->Curve()->InsertBefore(1, aPt);
1054 }
1055
1056 for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++)
1057 {
1058 IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx);
1059 const Standard_Real aCurParam = aVert.ParameterOnLine();
1060 aVert.SetParameter(aNbPts+aCurParam-1);
1061 }
1062
1063 for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--)
1064 {
1065 const IntPatch_Point &aVert = theWLine2->Vertex(aNVtx);
1066 theWLine1->AddVertex(aVert, Standard_True);
1067 }
1068
1069 theHasBeenJoined = Standard_True;
1070}
1071
1072//=======================================================================
1073//function : ExtendTwoWLLastFirst
1074//purpose : Performs extending theWLine1 through its end point and theWLine2
1075// through its start point.
1076//=======================================================================
1077static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1,
1078 const IntSurf_Quadric& theS2,
1079 const Handle(IntPatch_WLine)& theWLine1,
1080 const Handle(IntPatch_WLine)& theWLine2,
1081 const IntSurf_PntOn2S& thePtWL1,
1082 const IntSurf_PntOn2S& thePtWL2,
1083 const gp_Vec& theVec1,
1084 const gp_Vec& theVec2,
1085 const gp_Vec& theVec3,
1086 const Bnd_Box2d& theBoxS1,
1087 const Bnd_Box2d& theBoxS2,
1088 const Standard_Real theToler3D,
1089 const Standard_Real theU1Period,
1090 const Standard_Real theU2Period,
1091 const Standard_Real theV1Period,
1092 const Standard_Real theV2Period,
1093 unsigned int &theCheckResult,
1094 Standard_Boolean &theHasBeenJoined)
1095{
1096 IntSurf_PntOn2S aPOn2S;
d30895f5 1097 if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
1098 theVec1, theVec2, theVec3,
1099 theBoxS1, theBoxS2, theToler3D,
1100 theU1Period, theU2Period, theV1Period, theV2Period))
b8f67cc2 1101 {
1102 return;
1103 }
1104
1105 theCheckResult |= IntPatchWT_DisLastLast;
1106
1107 ExtendLast (theWLine1, aPOn2S);
1108 ExtendFirst(theWLine2, aPOn2S);
1109
1110 if(theHasBeenJoined)
1111 {
1112 return;
1113 }
1114
1115 Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine();
1116 while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm)
1117 theWLine1->RemoveVertex(theWLine1->NbVertex());
1118
1119 aPrm = theWLine2->Vertex(1).ParameterOnLine();
1120 while(theWLine2->Vertex(1).ParameterOnLine() == aPrm)
1121 theWLine2->RemoveVertex(1);
1122
1123 const Standard_Integer aNbPts = theWLine1->NbPnts();
1124 for(Standard_Integer aNPt = 2; aNPt <= theWLine2->NbPnts(); aNPt++)
1125 {
1126 const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
1127 theWLine1->Curve()->Add(aPt);
1128 }
1129
1130 for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++)
1131 {
1132 IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
1133 const Standard_Real aCurParam = aVert.ParameterOnLine();
1134 aVert.SetParameter(aNbPts+aCurParam-1);
1135 theWLine1->AddVertex(aVert, Standard_False);
1136 }
1137
1138 theHasBeenJoined = Standard_True;
1139}
1140
1141//=======================================================================
1142//function : ExtendTwoWLLastLast
1143//purpose :
1144//=======================================================================
1145static void ExtendTwoWLLastLast(const IntSurf_Quadric& theS1,
1146 const IntSurf_Quadric& theS2,
1147 const Handle(IntPatch_WLine)& theWLine1,
1148 const Handle(IntPatch_WLine)& theWLine2,
1149 const IntSurf_PntOn2S& thePtWL1,
1150 const IntSurf_PntOn2S& thePtWL2,
1151 const gp_Vec& theVec1,
1152 const gp_Vec& theVec2,
1153 const gp_Vec& theVec3,
1154 const Bnd_Box2d& theBoxS1,
1155 const Bnd_Box2d& theBoxS2,
1156 const Standard_Real theToler3D,
1157 const Standard_Real theU1Period,
1158 const Standard_Real theU2Period,
1159 const Standard_Real theV1Period,
1160 const Standard_Real theV2Period,
1161 unsigned int &/*theCheckResult*/,
1162 Standard_Boolean &theHasBeenJoined)
1163{
1164 IntSurf_PntOn2S aPOn2S;
d30895f5 1165 if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
1166 theVec1, theVec2, theVec3,
1167 theBoxS1, theBoxS2, theToler3D,
1168 theU1Period, theU2Period, theV1Period, theV2Period))
b8f67cc2 1169 {
1170 return;
1171 }
1172
1173 //theCheckResult |= IntPatchWT_DisLastLast;
1174
1175 ExtendLast(theWLine1, aPOn2S);
1176 ExtendLast(theWLine2, aPOn2S);
1177
1178 if(theHasBeenJoined)
1179 return;
1180
1181 Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine();
1182 while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm)
1183 theWLine1->RemoveVertex(theWLine1->NbVertex());
1184
1185 aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine();
1186 while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm)
1187 theWLine2->RemoveVertex(theWLine2->NbVertex());
1188
1189 const Standard_Integer aNbPts = theWLine1->NbPnts() + theWLine2->NbPnts();
1190 for(Standard_Integer aNPt = theWLine2->NbPnts()-1; aNPt >= 1; aNPt--)
1191 {
1192 const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
1193 theWLine1->Curve()->Add(aPt);
1194 }
1195
1196 for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--)
1197 {
1198 IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
1199 const Standard_Real aCurParam = aVert.ParameterOnLine();
1200 aVert.SetParameter(aNbPts - aCurParam);
1201 theWLine1->AddVertex(aVert, Standard_False);
1202 }
1203
1204 theHasBeenJoined = Standard_True;
eee615ad 1205}
1206
4e14c88f 1207//=========================================================================
1208// function : ComputePurgedWLine
1209// purpose :
1210//=========================================================================
1211Handle(IntPatch_WLine) IntPatch_WLineTool::
1212 ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine,
1213 const Handle(Adaptor3d_HSurface) &theS1,
1214 const Handle(Adaptor3d_HSurface) &theS2,
1215 const Handle(Adaptor3d_TopolTool) &theDom1,
5185b161 1216 const Handle(Adaptor3d_TopolTool) &theDom2,
1217 const Standard_Boolean theRestrictLine)
4e14c88f 1218{
1219 Standard_Integer i, k, v, nb, nbvtx;
1220 Handle(IntPatch_WLine) aResult;
1221 nbvtx = theWLine->NbVertex();
1222 nb = theWLine->NbPnts();
1223 if (nb==2)
1224 {
1225 const IntSurf_PntOn2S& p1 = theWLine->Point(1);
1226 const IntSurf_PntOn2S& p2 = theWLine->Point(2);
1227 if(p1.Value().IsEqual(p2.Value(), gp::Resolution()))
1228 return aResult;
1229 }
1230
1231 Handle(IntPatch_WLine) aLocalWLine;
1232 Handle(IntPatch_WLine) aTmpWLine = theWLine;
1233 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
1234 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1235 for(i = 1; i <= nb; i++)
1236 aLineOn2S->Add(theWLine->Point(i));
1237
1238 for(v = 1; v <= nbvtx; v++)
1239 aLocalWLine->AddVertex(theWLine->Vertex(v));
1240
1241 // I: Delete equal points
1242 for(i = 1; i <= aLineOn2S->NbPoints(); i++)
1243 {
1244 Standard_Integer aStartIndex = i + 1;
1245 Standard_Integer anEndIndex = i + 5;
1246 nb = aLineOn2S->NbPoints();
1247 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
1248
1249 if((aStartIndex > nb) || (anEndIndex <= 1))
1250 continue;
1251
1252 k = aStartIndex;
1253
1254 while(k <= anEndIndex)
1255 {
1256 if(i != k)
1257 {
1258 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
1259 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
1260
1261 Standard_Real UV[8];
1262 p1.Parameters(UV[0], UV[1], UV[2], UV[3]);
1263 p2.Parameters(UV[4], UV[5], UV[6], UV[7]);
1264
1265 Standard_Real aMax = Abs(UV[0]);
1266 for(Standard_Integer anIdx = 1; anIdx < 8; anIdx++)
1267 {
1268 if (aMax < Abs(UV[anIdx]))
1269 aMax = Abs(UV[anIdx]);
1270 }
1271
1272 if(p1.Value().IsEqual(p2.Value(), gp::Resolution()) ||
1273 Abs(UV[0] - UV[4]) + Abs(UV[1] - UV[5]) < 1.0e-16 * aMax ||
1274 Abs(UV[2] - UV[6]) + Abs(UV[3] - UV[7]) < 1.0e-16 * aMax )
1275 {
1276 aTmpWLine = aLocalWLine;
1277 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
1278
1279 for(v = 1; v <= aTmpWLine->NbVertex(); v++)
1280 {
1281 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
1282 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
1283
1284 if(avertexindex >= k)
1285 {
1286 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
1287 }
1288 aLocalWLine->AddVertex(aVertex);
1289 }
1290 aLineOn2S->RemovePoint(k);
1291 anEndIndex--;
1292 continue;
1293 }
1294 }
1295 k++;
1296 }
1297 }
1298
1299 if (aLineOn2S->NbPoints() <= 2)
1300 {
1301 if (aLineOn2S->NbPoints() == 2)
1302 return aLocalWLine;
1303 else
1304 return aResult;
1305 }
1306
1307 // Avoid purge in case of C0 continuity:
1308 // Intersection approximator may produce invalid curve after purge, example:
1309 // bugs modalg_5 bug24731.
1310 // Do not run purger when base number of points is too small.
1311 if (theS1->UContinuity() == GeomAbs_C0 ||
1312 theS1->VContinuity() == GeomAbs_C0 ||
1313 theS2->UContinuity() == GeomAbs_C0 ||
1314 theS2->VContinuity() == GeomAbs_C0 ||
1315 nb < aNbSingleBezier)
1316 {
1317 return aLocalWLine;
1318 }
1319
5185b161 1320 if (theRestrictLine)
1321 {
1322 // II: Delete out of borders points.
1323 aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
1324 }
4e14c88f 1325
1326 // III: Delete points by tube criteria.
1327 Handle(IntPatch_WLine) aLocalWLineTube =
5185b161 1328 DeleteByTube(aLocalWLine, theS1, theS2);
4e14c88f 1329
1330 if(aLocalWLineTube->NbPnts() > 1)
1331 {
1332 aResult = aLocalWLineTube;
1333 }
1334 return aResult;
1335}
1336
1337
1338//=======================================================================
1339//function : JoinWLines
1340//purpose :
1341//=======================================================================
1342void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
1343 IntPatch_SequenceOfPoint& theSPnt,
1344 const Standard_Real theTol3D,
1345 const Standard_Real theU1Period,
1346 const Standard_Real theU2Period,
1347 const Standard_Real theV1Period,
1348 const Standard_Real theV2Period,
1349 const Standard_Real theUfSurf1,
1350 const Standard_Real theUlSurf1,
1351 const Standard_Real theVfSurf1,
1352 const Standard_Real theVlSurf1,
1353 const Standard_Real theUfSurf2,
1354 const Standard_Real theUlSurf2,
1355 const Standard_Real theVfSurf2,
1356 const Standard_Real theVlSurf2)
1357{
1358 if(theSlin.Length() == 0)
1359 return;
1360
1361 for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
1362 {
1363 Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1)));
1364
1365 if(aWLine1.IsNull())
1366 {//We must have failed to join not-point-lines
1367 continue;
1368 }
1369
1370 const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
1371 const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1);
1372 const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1);
1373
1374 for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
1375 {
1376 const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
1377
1378 if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) ||
1379 aPntCur.IsSame(aPntLW1, Precision::Confusion()))
1380 {
1381 theSPnt.Remove(aNPt);
1382 aNPt--;
1383 }
1384 }
1385
1386 Standard_Boolean hasBeenRemoved = Standard_False;
1387 for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
1388 {
1389 Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2)));
1390
1391 if(aWLine2.IsNull())
1392 continue;
1393
1394 const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
1395
1396 const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
1397 const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
1398
1399 const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
1400 const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
1401
1402 if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
1403 {
1404 const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
1405 const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
d30895f5 1406 Standard_Boolean aCond =
1407 CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()),
1408 gp_Vec(aPt2.Value(), aPntFWL2.Value()));
1409
1410 aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1,
1411 theU1Period, theU2Period,
1412 theV1Period, theV2Period,
1413 theUfSurf1, theUlSurf1,
1414 theVfSurf1, theVlSurf1,
1415 theUfSurf2, theUlSurf2,
1416 theVfSurf2, theVlSurf2);
1417
1418 if(aCond)
4e14c88f 1419 {
1420 aWLine1->ClearVertexes();
1421 for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
1422 {
1423 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
1424 aWLine1->Curve()->InsertBefore(1, aPt);
1425 }
1426
1427 aWLine1->ComputeVertexParameters(theTol3D);
1428
1429 theSlin.Remove(aNumOfLine2);
1430 aNumOfLine2--;
1431 hasBeenRemoved = Standard_True;
1432
1433 continue;
1434 }
1435 }
1436
1437 if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
1438 {
1439 const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
1440 const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
d30895f5 1441
1442 Standard_Boolean aCond =
1443 CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()),
1444 gp_Vec(aPt2.Value(), aPntLWL2.Value()));
1445
1446 aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1,
1447 theU1Period, theU2Period,
1448 theV1Period, theV2Period,
1449 theUfSurf1, theUlSurf1,
1450 theVfSurf1, theVlSurf1,
1451 theUfSurf2, theUlSurf2,
1452 theVfSurf2, theVlSurf2);
1453
1454 if(aCond)
4e14c88f 1455 {
1456 aWLine1->ClearVertexes();
1457 for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
1458 {
1459 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
1460 aWLine1->Curve()->InsertBefore(1, aPt);
1461 }
1462
1463 aWLine1->ComputeVertexParameters(theTol3D);
1464
1465 theSlin.Remove(aNumOfLine2);
1466 aNumOfLine2--;
1467 hasBeenRemoved = Standard_True;
1468
1469 continue;
1470 }
1471 }
1472
1473 if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
1474 {
1475 const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
1476 const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
d30895f5 1477
1478 Standard_Boolean aCond =
1479 CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()),
1480 gp_Vec(aPntFWL2.Value(), aPt2.Value()));
1481
1482 aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1,
1483 theU1Period, theU2Period,
1484 theV1Period, theV2Period,
1485 theUfSurf1, theUlSurf1,
1486 theVfSurf1, theVlSurf1,
1487 theUfSurf2, theUlSurf2,
1488 theVfSurf2, theVlSurf2);
1489
1490 if(aCond)
4e14c88f 1491 {
1492 aWLine1->ClearVertexes();
1493 for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
1494 {
1495 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
1496 aWLine1->Curve()->Add(aPt);
1497 }
1498
1499 aWLine1->ComputeVertexParameters(theTol3D);
1500
1501 theSlin.Remove(aNumOfLine2);
1502 aNumOfLine2--;
1503 hasBeenRemoved = Standard_True;
1504
1505 continue;
1506 }
1507 }
1508
1509 if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
1510 {
1511 const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
1512 const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
d30895f5 1513
1514 Standard_Boolean aCond =
1515 CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()),
1516 gp_Vec(aPntLWL2.Value(), aPt2.Value()));
1517
1518 aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1,
1519 theU1Period, theU2Period,
1520 theV1Period, theV2Period,
1521 theUfSurf1, theUlSurf1,
1522 theVfSurf1, theVlSurf1,
1523 theUfSurf2, theUlSurf2,
1524 theVfSurf2, theVlSurf2);
1525
1526 if(aCond)
4e14c88f 1527 {
1528 aWLine1->ClearVertexes();
1529 for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
1530 {
1531 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
1532 aWLine1->Curve()->Add(aPt);
1533 }
1534
1535 aWLine1->ComputeVertexParameters(theTol3D);
1536
1537 theSlin.Remove(aNumOfLine2);
1538 aNumOfLine2--;
1539 hasBeenRemoved = Standard_True;
1540
1541 continue;
1542 }
1543 }
1544 }
1545
1546 if(hasBeenRemoved)
1547 aNumOfLine1--;
1548 }
eee615ad 1549}
1550
1551//=======================================================================
1552//function : ExtendTwoWlinesToEachOther
b8f67cc2 1553//purpose : Performs extending theWLine1 and theWLine2 through their
1554// respecting end point.
eee615ad 1555//=======================================================================
1556void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
1557 const IntSurf_Quadric& theS1,
1558 const IntSurf_Quadric& theS2,
1559 const Standard_Real theToler3D,
1560 const Standard_Real theU1Period,
1561 const Standard_Real theU2Period,
1562 const Standard_Real theV1Period,
b8f67cc2 1563 const Standard_Real theV2Period,
1564 const Bnd_Box2d& theBoxS1,
1565 const Bnd_Box2d& theBoxS2)
eee615ad 1566{
1567 if(theSlin.Length() < 2)
1568 return;
1569
eee615ad 1570 gp_Vec aVec1, aVec2, aVec3;
1571
1572 for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
1573 {
1574 Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::
1575 DownCast(theSlin.Value(aNumOfLine1)));
1576
1577 if(aWLine1.IsNull())
1578 {//We must have failed to join not-point-lines
1579 continue;
1580 }
1581
1582 const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
1583
b8f67cc2 1584 if(aWLine1->Vertex(1).ParameterOnLine() != 1)
1585 continue;
1586
1587 if(aWLine1->Vertex(aWLine1->NbVertex()).ParameterOnLine() != aWLine1->NbPnts())
1588 continue;
1589
eee615ad 1590 for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1;
1591 aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
1592 {
1593 Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::
1594 DownCast(theSlin.Value(aNumOfLine2)));
1595
1596 if(aWLine2.IsNull())
1597 continue;
1598
b8f67cc2 1599 if(aWLine2->Vertex(1).ParameterOnLine() != 1)
1600 continue;
1601
1602 if(aWLine2->Vertex(aWLine2->NbVertex()).ParameterOnLine() != aWLine2->NbPnts())
1603 continue;
1604
eee615ad 1605 //Enable/Disable of some ckeck. Bit-mask is used for it.
1606 //E.g. if 1st point of aWLine1 matches with
1607 //1st point of aWLine2 then we do not need in check
1608 //1st point of aWLine1 and last point of aWLine2 etc.
eee615ad 1609 unsigned int aCheckResult = IntPatchWT_EnAll;
1610
b8f67cc2 1611 Standard_Boolean hasBeenJoined = Standard_False;
1612
eee615ad 1613 const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
1614
1615 const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
1616 const IntSurf_PntOn2S& aPntFp1WL1 = aWLine1->Point(2);
1617
1618 const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
1619 const IntSurf_PntOn2S& aPntLm1WL1 = aWLine1->Point(aNbPntsWL1-1);
1620
1621 const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
1622 const IntSurf_PntOn2S& aPntFp1WL2 = aWLine2->Point(2);
1623
1624 const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
1625 const IntSurf_PntOn2S& aPntLm1WL2 = aWLine2->Point(aNbPntsWL2-1);
1626
1627 //if(!(aCheckResult & IntPatchWT_DisFirstFirst))
1628 {// First/First
1629 aVec1.SetXYZ(aPntFp1WL1.Value().XYZ() - aPntFWL1.Value().XYZ());
1630 aVec2.SetXYZ(aPntFWL2.Value().XYZ() - aPntFp1WL2.Value().XYZ());
1631 aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntFWL2.Value().XYZ());
1632
b8f67cc2 1633 ExtendTwoWLFirstFirst(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntFWL2,
1634 aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
1635 theU1Period, theU2Period, theV1Period, theV2Period,
1636 aCheckResult, hasBeenJoined);
1637 }
eee615ad 1638
1639 if(!(aCheckResult & IntPatchWT_DisFirstLast))
1640 {// First/Last
1641 aVec1.SetXYZ(aPntFp1WL1.Value().XYZ() - aPntFWL1.Value().XYZ());
1642 aVec2.SetXYZ(aPntLWL2.Value().XYZ() - aPntLm1WL2.Value().XYZ());
1643 aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntLWL2.Value().XYZ());
1644
b8f67cc2 1645 ExtendTwoWLFirstLast(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntLWL2,
1646 aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
1647 theU1Period, theU2Period, theV1Period, theV2Period,
1648 aCheckResult, hasBeenJoined);
1649 }
eee615ad 1650
1651 if(!(aCheckResult & IntPatchWT_DisLastFirst))
1652 {// Last/First
1653 aVec1.SetXYZ(aPntLWL1.Value().XYZ() - aPntLm1WL1.Value().XYZ());
1654 aVec2.SetXYZ(aPntFp1WL2.Value().XYZ() - aPntFWL2.Value().XYZ());
1655 aVec3.SetXYZ(aPntFWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
1656
b8f67cc2 1657 ExtendTwoWLLastFirst(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntFWL2,
1658 aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
1659 theU1Period, theU2Period, theV1Period, theV2Period,
1660 aCheckResult, hasBeenJoined);
1661 }
eee615ad 1662
1663 if(!(aCheckResult & IntPatchWT_DisLastLast))
1664 {// Last/Last
1665 aVec1.SetXYZ(aPntLWL1.Value().XYZ() - aPntLm1WL1.Value().XYZ());
1666 aVec2.SetXYZ(aPntLm1WL2.Value().XYZ() - aPntLWL2.Value().XYZ());
1667 aVec3.SetXYZ(aPntLWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
1668
b8f67cc2 1669 ExtendTwoWLLastLast(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntLWL2,
1670 aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
1671 theU1Period, theU2Period, theV1Period, theV2Period,
1672 aCheckResult, hasBeenJoined);
1673 }
1674
1675 if(hasBeenJoined)
1676 {
1677 theSlin.Remove(aNumOfLine2);
1678 aNumOfLine2--;
1679 }
eee615ad 1680 }
1681 }
1682}