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