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