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