7fd59977 |
1 | // File: TopOpeBRep_FacesIntersector.cxx |
2 | // Created: Thu Nov 18 11:12:07 1993 |
3 | // Author: Jean Yves LEBEY |
4 | // Copyright: OPEN CASCADE 1993 |
5 | |
6 | #include <TopOpeBRep_FacesIntersector.ixx> |
7 | |
8 | #ifdef DRAW |
9 | #include <TopOpeBRep_DRAW.hxx> |
10 | #endif |
11 | |
12 | #include <IntPatch_LineConstructor.hxx> |
13 | #include <TopOpeBRep_TypeLineCurve.hxx> |
14 | #include <TopoDS.hxx> |
15 | #include <TopoDS_Face.hxx> |
16 | #include <TopoDS_Edge.hxx> |
17 | #include <BRep_Tool.hxx> |
18 | #include <TopExp_Explorer.hxx> |
19 | #include <TopOpeBRepTool_ShapeTool.hxx> |
20 | #include <Precision.hxx> |
21 | #include <Geom_Curve.hxx> |
22 | #include <Standard_ProgramError.hxx> |
23 | #include <TCollection_AsciiString.hxx> |
24 | #include <Standard_CString.hxx> |
25 | #include <BRepTools.hxx> |
26 | #include <TopOpeBRepTool_tol.hxx> |
27 | |
28 | Standard_EXPORT Standard_Real GLOBAL_tolFF = 1.e-7; |
29 | |
30 | #ifdef DEB |
31 | #include <TopAbs.hxx> |
32 | Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFI(); |
33 | Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFITOL(); |
34 | Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceSAVFF(); |
35 | |
36 | Standard_EXPORT Standard_Integer SAVFFi1 = 0; |
37 | Standard_EXPORT Standard_Integer SAVFFi2 = 0; |
38 | static void SAVFF(const TopoDS_Face& F1,const TopoDS_Face& F2) |
39 | { |
40 | TCollection_AsciiString an1("SAVA");if (SAVFFi1) an1=an1+SAVFFi1; |
41 | TCollection_AsciiString an2("SAVB");if (SAVFFi2) an2=an2+SAVFFi2; |
42 | Standard_CString n1=an1.ToCString();Standard_CString n2=an2.ToCString(); |
43 | #ifdef DRAW |
44 | cout<<"FaceIntersector : set "<<n1<<","<<n2<<endl;DBRep::Set(n1,F1);DBRep::Set(n2,F2); |
45 | #endif |
46 | cout<<"FaceIntersector : write "<<n1<<","<<n2<<endl;BRepTools::Write(F1,n1);BRepTools::Write(F2,n2); |
47 | } |
48 | |
49 | Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceKRO(); |
50 | #include <TopOpeBRepTool_KRO.hxx> |
51 | Standard_EXPORT TOPKRO KRO_DSFILLER_INTFF("intersection face/face"); |
52 | |
53 | #endif |
54 | |
55 | // NYI |
56 | // NYI : IntPatch_Intersection : TolArc,TolTang exact definition |
57 | // NYI |
58 | |
59 | |
60 | // modified by NIZHNY-MKK Mon Apr 2 12:14:32 2001.BEGIN |
61 | #include <IntPatch_WLine.hxx> |
62 | #include <IntPatch_RLine.hxx> |
63 | #include <IntPatch_Point.hxx> |
64 | #include <Adaptor3d_HSurface.hxx> |
65 | #include <Adaptor3d_TopolTool.hxx> |
66 | #include <Adaptor3d_HVertex.hxx> |
67 | #include <Adaptor2d_HCurve2d.hxx> |
68 | #include <Geom2dInt_TheProjPCurOfGInter.hxx> |
69 | |
70 | static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine, |
71 | const Standard_Integer theRank, |
72 | const Handle(Adaptor3d_HSurface)& theSurface, |
73 | const Handle(Adaptor3d_TopolTool)& theDomain, |
74 | const Standard_Real theTolArc); |
75 | |
76 | static |
77 | Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine, |
78 | const Handle(Adaptor2d_HCurve2d)& theArc, |
79 | const Standard_Integer theRank); |
80 | |
81 | static |
82 | Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine, |
83 | const Standard_Integer theRank, |
84 | const Handle(Adaptor3d_HSurface)& theSurface, |
85 | const Handle(Adaptor3d_TopolTool)& theDomain, |
86 | const Standard_Real theTolArc); |
87 | |
88 | static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin, |
89 | const Handle(Adaptor3d_HSurface)& theSurface1, |
90 | const Handle(Adaptor3d_TopolTool)& theDomain1, |
91 | const Handle(Adaptor3d_HSurface)& theSurface2, |
92 | const Handle(Adaptor3d_TopolTool)& theDomain2, |
93 | const Standard_Real theTolArc); |
94 | // modified by NIZHNY-MKK Mon Apr 2 12:14:38 2001.END |
95 | |
96 | // modified by NIZHNY-OFV Fri Mar 29 12:37:21 2002.BEGIN |
97 | #include <TColgp_SequenceOfPnt.hxx> |
98 | #include <TopExp.hxx> |
99 | #include <TColStd_SequenceOfReal.hxx> |
100 | #include <Extrema_ExtPS.hxx> |
101 | #include <Extrema_ExtPC.hxx> |
102 | #include <Extrema_POnSurf.hxx> |
103 | #include <GeomAdaptor_Curve.hxx> |
104 | static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin, |
105 | const Handle(Adaptor3d_HSurface)& theSurface1, |
106 | const Handle(Adaptor3d_TopolTool)& theDomain1, |
107 | const Handle(Adaptor3d_HSurface)& theSurface2, |
108 | const Handle(Adaptor3d_TopolTool)& theDomain2, |
109 | const Standard_Real theTolArc); |
110 | //------------------------------------------------------------------------------------------------ |
111 | static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin, |
112 | const Standard_Integer& theRankS, |
113 | const Handle(Adaptor3d_HSurface)& theSurfaceObj, |
114 | const Handle(Adaptor3d_TopolTool)& theDomainObj, |
115 | const Handle(Adaptor3d_HSurface)& theSurfaceTool, |
116 | const gp_Pnt& theTestPoint, |
117 | Standard_Real& theVrtxTol, |
118 | Handle(IntSurf_LineOn2S)& theLineOn2S, |
119 | Standard_Real& theFirst, |
120 | Standard_Real& theLast); |
121 | //------------------------------------------------------------------------------------------------ |
122 | static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt, |
123 | const Adaptor3d_Surface& theTestSurface, |
124 | const Standard_Real& theTol); |
125 | //------------------------------------------------------------------------------------------------- |
126 | static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt, |
127 | const Adaptor3d_Surface& theTestSurface, |
128 | const Standard_Real& theTol, |
129 | Extrema_POnSurf& theResultPoint); |
130 | //------------------------------------------------------------------------------------------------------------------------- |
131 | static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin, |
132 | const Standard_Real& theVrtxTol, |
133 | const Handle(IntSurf_LineOn2S)& theLineOn2S); |
134 | //--------------------------------------------------------------------------------------------------------------------------- |
135 | // modified by NIZHNY-OFV Fri Mar 29 12:41:02 2002.END |
136 | |
137 | //======================================================================= |
138 | //function : TopOpeBRep_FacesIntersector |
139 | //purpose : |
140 | //======================================================================= |
141 | TopOpeBRep_FacesIntersector::TopOpeBRep_FacesIntersector () |
142 | { |
143 | ResetIntersection(); |
144 | myTol1 = myTol2 = Precision::Confusion(); |
145 | myForceTolerances = Standard_False; |
146 | mySurface1 = new BRepAdaptor_HSurface(); |
147 | mySurface2 = new BRepAdaptor_HSurface(); |
148 | myDomain1 = new BRepTopAdaptor_TopolTool(); |
149 | myDomain2 = new BRepTopAdaptor_TopolTool(); |
150 | } |
151 | |
152 | //======================================================================= |
153 | //function : Perform |
154 | //purpose : |
155 | //======================================================================= |
156 | void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2, |
157 | const Bnd_Box& B1,const Bnd_Box& B2) |
158 | { |
159 | #ifdef DEB |
160 | if (TopOpeBRep_GettraceSAVFF()) SAVFF(TopoDS::Face(F1),TopoDS::Face(F2)); |
161 | #endif |
162 | |
163 | ResetIntersection(); |
164 | if (!myForceTolerances) ShapeTolerances(F1,F2); |
165 | |
166 | myFace1 = TopoDS::Face(F1); myFace1.Orientation(TopAbs_FORWARD); |
167 | myFace2 = TopoDS::Face(F2); myFace2.Orientation(TopAbs_FORWARD); |
168 | BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1); |
169 | BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2); |
170 | mySurfaceType1 = S1.GetType(); |
171 | mySurfaceType2 = S2.GetType(); |
172 | myDomain1->Initialize(mySurface1); |
173 | myDomain2->Initialize(mySurface2); |
174 | |
175 | #ifdef DEB |
176 | if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Start(); |
177 | #endif |
178 | |
179 | Standard_Real Deflection=0.01,MaxUV=0.01; |
180 | if (!myForceTolerances) { |
181 | FTOL_FaceTolerances3d(B1,B2,myFace1,myFace2,S1,S2, |
182 | myTol1,myTol2,Deflection,MaxUV); |
183 | myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1; |
184 | myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2; |
185 | } |
186 | |
187 | Standard_Real tol1 = myTol1; |
188 | Standard_Real tol2 = myTol2; |
189 | GLOBAL_tolFF = Max(tol1,tol2); |
190 | |
191 | #ifdef DEB |
192 | if (TopOpeBRep_GettraceFITOL()) { |
193 | cout<<"FacesIntersector : Perform tol1 = "<<tol1<<endl; |
194 | cout<<" tol2 = "<<tol2<<endl; |
195 | cout<<" defl = "<<Deflection<<" MaxUV = "<<MaxUV<<endl; |
196 | } |
197 | #endif |
198 | |
199 | myIntersector.SetTolerances(myTol1,myTol2,MaxUV,Deflection); |
200 | myIntersector.Perform(mySurface1,myDomain1,mySurface2,myDomain2,myTol1,myTol2); |
201 | |
202 | #ifdef DEB |
203 | if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFF.Stop(); |
204 | #endif |
205 | |
206 | //xpu180998 : cto900Q1 |
207 | Standard_Boolean done = myIntersector.IsDone(); |
208 | if (!done) return; |
209 | |
210 | PrepareLines(); |
211 | myIntersectionDone = Standard_True; |
212 | |
213 | // mySurfacesSameOriented : a mettre dans IntPatch NYI |
214 | if ( SameDomain() ) { |
215 | mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2); |
216 | } |
217 | |
218 | // build the map of edges found as RESTRICTION |
219 | for (InitLine(); MoreLine(); NextLine()) { |
220 | TopOpeBRep_LineInter& L = CurrentLine(); |
221 | if (L.TypeLineCurve() == TopOpeBRep_RESTRICTION) { |
7fd59977 |
222 | const TopoDS_Shape& E = L.Arc(); |
223 | myEdgeRestrictionMap.Add(E); |
224 | } |
225 | } |
226 | |
227 | #ifdef DEB |
228 | if (TopOpeBRep_GettraceFI()) cout<<"Perform : isempty "<<IsEmpty()<<endl; |
229 | #endif |
230 | } |
231 | |
232 | //======================================================================= |
233 | //function : Perform |
234 | //purpose : |
235 | //======================================================================= |
236 | |
237 | void TopOpeBRep_FacesIntersector::Perform(const TopoDS_Shape& F1,const TopoDS_Shape& F2) |
238 | { |
239 | Bnd_Box B1,B2; |
240 | Perform(F1,F2,B1,B2); |
241 | } |
242 | |
243 | |
244 | //======================================================================= |
245 | //function : IsEmpty |
246 | //purpose : |
247 | //======================================================================= |
248 | |
249 | Standard_Boolean TopOpeBRep_FacesIntersector::IsEmpty () |
250 | { |
251 | if ( ! myIntersectionDone ) return Standard_False; |
252 | Standard_Boolean done = myIntersector.IsDone(); |
253 | Standard_Boolean empty = myIntersector.IsEmpty(); |
254 | if ( !done || empty ) return Standard_True; |
255 | else { |
256 | // ElemIntersector is done and is not empty |
257 | // returns True if at least one VPoint is found |
258 | empty = Standard_True; |
259 | for ( InitLine(); MoreLine(); NextLine() ) { |
260 | empty = (CurrentLine().NbVPoint() == 0); |
261 | if ( ! empty ) break; |
262 | } |
263 | return empty; |
264 | } |
265 | } |
266 | |
267 | //======================================================================= |
268 | //function : IsDone |
269 | //purpose : |
270 | //======================================================================= |
271 | |
272 | Standard_Boolean TopOpeBRep_FacesIntersector::IsDone () const |
273 | { |
274 | return myIntersectionDone; |
275 | } |
276 | |
277 | //======================================================================= |
278 | //function : SameDomain |
279 | //purpose : |
280 | //======================================================================= |
281 | |
282 | Standard_Boolean TopOpeBRep_FacesIntersector::SameDomain () const |
283 | { |
284 | if (!myIntersectionDone) |
285 | Standard_ProgramError::Raise("FacesIntersector : bad SameDomain"); |
286 | |
287 | Standard_Boolean sd = myIntersector.TangentFaces(); |
6e6cd5d9 |
288 | |
289 | //Standard_Boolean plpl = (mySurfaceType1 == GeomAbs_Plane) && (mySurfaceType2 == GeomAbs_Plane); |
290 | |
7fd59977 |
291 | // if (!plpl) return Standard_False; |
292 | return sd; |
293 | } |
294 | |
295 | |
296 | //======================================================================= |
297 | //function : Face |
298 | //purpose : |
299 | //======================================================================= |
300 | |
301 | const TopoDS_Shape& TopOpeBRep_FacesIntersector::Face |
302 | (const Standard_Integer Index) const |
303 | { |
304 | if ( Index == 1 ) return myFace1; |
305 | else if ( Index == 2 ) return myFace2; |
306 | else Standard_ProgramError::Raise("TopOpeBRep_FacesIntersector::Face"); |
307 | |
308 | return myNullShape; |
309 | } |
310 | |
311 | |
312 | //======================================================================= |
313 | //function : SurfacesSameOriented |
314 | //purpose : |
315 | //======================================================================= |
316 | |
317 | Standard_Boolean TopOpeBRep_FacesIntersector::SurfacesSameOriented () const |
318 | { |
319 | if ( SameDomain() ) { |
320 | return mySurfacesSameOriented; |
321 | } |
322 | Standard_ProgramError::Raise("FacesIntersector : bad SurfacesSameOriented"); |
323 | return Standard_False; |
324 | } |
325 | |
326 | //======================================================================= |
327 | //function : IsRestriction |
328 | //purpose : |
329 | //======================================================================= |
330 | |
331 | Standard_Boolean TopOpeBRep_FacesIntersector::IsRestriction |
332 | (const TopoDS_Shape& E) const |
333 | { |
334 | Standard_Boolean isrest = myEdgeRestrictionMap.Contains(E); |
335 | return isrest; |
336 | } |
337 | |
338 | //======================================================================= |
339 | //function : Restrictions |
340 | //purpose : |
341 | //======================================================================= |
342 | |
343 | const TopTools_IndexedMapOfShape& TopOpeBRep_FacesIntersector::Restrictions |
344 | () const |
345 | { |
346 | return myEdgeRestrictionMap; |
347 | } |
348 | |
349 | //======================================================================= |
350 | //function : PrepareLines |
351 | //purpose : |
352 | //======================================================================= |
353 | |
354 | void TopOpeBRep_FacesIntersector::PrepareLines() |
355 | { |
356 | myLineNb = 0; |
357 | Standard_Integer n = myIntersector.NbLines(); |
358 | myHAL = new TopOpeBRep_HArray1OfLineInter(0,n); |
359 | BRepAdaptor_Surface& S1 = *((BRepAdaptor_Surface*)&(mySurface1->Surface())); |
360 | BRepAdaptor_Surface& S2 = *((BRepAdaptor_Surface*)&(mySurface2->Surface())); |
361 | |
362 | // modified by NIZHNY-MKK Mon Apr 2 12:14:58 2001.BEGIN |
363 | if(n==0) |
364 | return; |
365 | // modified by NIZHNY-MKK Mon Apr 2 12:15:09 2001.END |
366 | |
367 | Standard_Boolean newV = Standard_True; |
368 | |
369 | if (!newV) { |
370 | /*for ( Standard_Integer i=1; i<=n; i++) { |
371 | TopOpeBRep_LineInter& LI = myHAL->ChangeValue(i); |
372 | const Handle(IntPatch_Line)& L = myIntersector.Line(i); |
373 | LI.SetLine(L,S1,S2); |
374 | LI.Index(i); |
375 | myLineNb++;; |
376 | }*/} |
377 | |
378 | if (newV) { |
379 | //-- lbr |
380 | |
381 | // modified by NIZHNY-MKK Mon Apr 2 12:16:04 2001 |
382 | IntPatch_SequenceOfLine aSeqOfLines, aSeqOfResultLines; |
383 | |
384 | Standard_Integer i ; |
385 | // Standard_Integer nbl=0; |
386 | IntPatch_LineConstructor **Ptr = |
387 | (IntPatch_LineConstructor **)malloc(n*sizeof(IntPatch_LineConstructor *)); |
388 | for( i=1;i<=n;i++) { |
389 | Ptr[i-1]=new IntPatch_LineConstructor(2); |
390 | Ptr[i-1]->Perform(myIntersector.SequenceOfLine(), |
391 | myIntersector.Line(i), |
392 | mySurface1,myDomain1, |
393 | mySurface2,myDomain2, |
394 | myTol1); |
395 | // modified by NIZHNY-MKK Mon Apr 2 12:16:26 2001.BEGIN |
396 | aSeqOfLines.Clear(); |
397 | for(Standard_Integer k=1; k<=Ptr[i-1]->NbLines(); k++) { |
398 | aSeqOfLines.Append(Ptr[i-1]->Line(k)); |
399 | } |
400 | |
401 | TestWLinesToAnArc(aSeqOfLines, mySurface1, myDomain1, mySurface2, myDomain2, myTol1); |
402 | |
403 | for(Standard_Integer j=1; j<=aSeqOfLines.Length(); j++) { |
404 | aSeqOfResultLines.Append(aSeqOfLines.Value(j)); |
405 | } |
406 | delete Ptr[i-1]; |
407 | // nbl+=Ptr[i-1]->NbLines(); |
408 | // modified by NIZHNY-MKK Mon Apr 2 12:16:31 2001.END |
409 | } |
410 | |
411 | // modified by NIZHNY-MKK Mon Apr 2 12:17:22 2001.BEGIN |
412 | // myHAL = new TopOpeBRep_HArray1OfLineInter(0,nbl); |
413 | myLineNb = aSeqOfResultLines.Length(); |
414 | |
415 | //Fun_ConvertWLinesToRLine(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1); |
416 | MergeWLinesIfAllSegmentsAlongRestriction(aSeqOfResultLines,mySurface1, myDomain1, mySurface2, myDomain2, myTol1); |
417 | myLineNb = aSeqOfResultLines.Length(); |
418 | |
419 | |
420 | if(myLineNb > 0) { |
421 | myHAL = new TopOpeBRep_HArray1OfLineInter(1, myLineNb); |
422 | for(Standard_Integer index = 1; index <= myLineNb; index++) { |
423 | TopOpeBRep_LineInter& LI = myHAL->ChangeValue(index); |
424 | const Handle(IntPatch_Line)& L = aSeqOfResultLines.Value(index); |
425 | LI.SetLine(L,S1,S2); |
426 | LI.Index(index); |
427 | } |
428 | } |
429 | |
430 | // nbl=1; |
431 | // for(i=1;i<=n;i++) { |
432 | // for(Standard_Integer k=1;k<=Ptr[i-1]->NbLines();k++) { |
433 | // TopOpeBRep_LineInter& LI = myHAL->ChangeValue(nbl); |
434 | // const Handle(IntPatch_Line)& L = Ptr[i-1]->Line(k); |
435 | // LI.SetLine(L,S1,S2); |
436 | // LI.Index(nbl); |
437 | // myLineNb++; |
438 | // nbl++; |
439 | // } |
440 | // delete Ptr[i-1]; |
441 | // } |
442 | // modified by NIZHNY-MKK Mon Apr 2 12:17:57 2001.END |
443 | free(Ptr); |
444 | } |
445 | } |
446 | |
447 | //======================================================================= |
448 | //function : Lines |
449 | //purpose : |
450 | //======================================================================= |
451 | |
452 | Handle(TopOpeBRep_HArray1OfLineInter) TopOpeBRep_FacesIntersector::Lines() |
453 | { |
454 | return myHAL; |
455 | } |
456 | |
457 | //======================================================================= |
458 | //function : NbLines |
459 | //purpose : |
460 | //======================================================================= |
461 | |
462 | Standard_Integer TopOpeBRep_FacesIntersector::NbLines()const |
463 | { |
464 | return myLineNb; |
465 | } |
466 | |
467 | //======================================================================= |
468 | //function : InitLine |
469 | //purpose : |
470 | //======================================================================= |
471 | |
472 | void TopOpeBRep_FacesIntersector::InitLine() |
473 | { |
474 | myLineIndex = 1; |
475 | FindLine(); |
476 | } |
477 | |
478 | //======================================================================= |
479 | //function : FindLine |
480 | //purpose : |
481 | //======================================================================= |
482 | |
483 | void TopOpeBRep_FacesIntersector::FindLine() |
484 | { |
485 | myLineFound = Standard_False; |
486 | if ( ! myIntersectionDone ) return; |
487 | |
488 | while (myLineIndex <= myLineNb) { |
489 | const TopOpeBRep_LineInter& L = myHAL->Value(myLineIndex); |
490 | myLineFound = L.OK(); |
491 | if (myLineFound) break; |
492 | else myLineIndex++; |
493 | } |
494 | } |
495 | |
496 | //======================================================================= |
497 | //function : MoreLine |
498 | //purpose : |
499 | //======================================================================= |
500 | |
501 | Standard_Boolean TopOpeBRep_FacesIntersector::MoreLine()const |
502 | { |
503 | return myLineFound; |
504 | } |
505 | |
506 | |
507 | //======================================================================= |
508 | //function : NextLine |
509 | //purpose : |
510 | //======================================================================= |
511 | |
512 | void TopOpeBRep_FacesIntersector::NextLine() |
513 | { |
514 | myLineIndex++; |
515 | FindLine(); |
516 | } |
517 | |
518 | //======================================================================= |
519 | //function : CurrentLine |
520 | //purpose : |
521 | //======================================================================= |
522 | |
523 | TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::CurrentLine() |
524 | { |
525 | TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(myLineIndex); |
526 | return TLI; |
527 | } |
528 | |
529 | |
530 | //======================================================================= |
531 | //function : CurrentLineIndex |
532 | //purpose : |
533 | //======================================================================= |
534 | |
535 | Standard_Integer TopOpeBRep_FacesIntersector::CurrentLineIndex()const |
536 | { |
537 | return myLineIndex; |
538 | } |
539 | |
540 | //======================================================================= |
541 | //function : Line |
542 | //purpose : |
543 | //======================================================================= |
544 | |
545 | TopOpeBRep_LineInter& TopOpeBRep_FacesIntersector::ChangeLine(const Standard_Integer IL) |
546 | { |
547 | TopOpeBRep_LineInter& TLI = myHAL->ChangeValue(IL); |
548 | return TLI; |
549 | } |
550 | |
551 | //======================================================================= |
552 | //function : ResetIntersection |
553 | //purpose : |
554 | //======================================================================= |
555 | |
556 | void TopOpeBRep_FacesIntersector::ResetIntersection() |
557 | { |
558 | myIntersectionDone = Standard_False; |
559 | myLineIndex = 1; |
560 | myLineNb = 0; |
561 | myEdgeRestrictionMap.Clear(); |
562 | myLineFound = Standard_False; |
563 | } |
564 | |
565 | |
566 | //======================================================================= |
567 | //function : ForceTolerances |
568 | //purpose : |
569 | //======================================================================= |
570 | |
571 | void TopOpeBRep_FacesIntersector::ForceTolerances(const Standard_Real Tol1, |
572 | const Standard_Real Tol2) |
573 | { |
574 | myTol1 = Tol1; |
575 | myTol2 = Tol2; |
576 | myForceTolerances = Standard_True; |
577 | #ifdef DEB |
578 | if (TopOpeBRep_GettraceFITOL()) |
579 | cout<<"ForceTolerances : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl; |
580 | #endif |
581 | } |
582 | |
583 | //======================================================================= |
584 | //function : GetTolerances |
585 | //purpose : |
586 | //======================================================================= |
587 | |
588 | void TopOpeBRep_FacesIntersector::GetTolerances(Standard_Real& Tol1, |
589 | Standard_Real& Tol2) const |
590 | { |
591 | Tol1 = myTol1; |
592 | Tol2 = myTol2; |
593 | } |
594 | |
595 | //======================================================================= |
596 | //function : ShapeTolerances |
597 | //purpose : (private) |
598 | //======================================================================= |
599 | |
600 | #ifdef DEB |
601 | void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& S1, |
602 | const TopoDS_Shape& S2) |
603 | #else |
604 | void TopOpeBRep_FacesIntersector::ShapeTolerances(const TopoDS_Shape& , |
605 | const TopoDS_Shape& ) |
606 | #endif |
607 | { |
608 | // myTol1 = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE)); |
609 | myTol1 = Precision::Confusion(); |
610 | myTol2 = myTol1; |
611 | myForceTolerances = Standard_False; |
612 | #ifdef DEB |
613 | if (TopOpeBRep_GettraceFITOL()) { |
614 | cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout); |
615 | cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout); |
616 | cout<<" : myTol1,myTol2 = "<<myTol1<<","<<myTol2<<endl; |
617 | } |
618 | #endif |
619 | } |
620 | |
621 | //======================================================================= |
622 | //function : ToleranceMax |
623 | //purpose : (private) |
624 | //======================================================================= |
625 | |
626 | Standard_Real TopOpeBRep_FacesIntersector::ToleranceMax |
627 | (const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const |
628 | { |
629 | TopExp_Explorer e(S,T); |
630 | if ( ! e.More() ) return Precision::Intersection(); |
631 | else { |
632 | Standard_Real tol = RealFirst(); |
633 | for (; e.More(); e.Next()) |
634 | tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current())); |
635 | return tol; |
636 | } |
637 | } |
638 | |
639 | |
640 | // modified by NIZHNY-MKK Mon Apr 2 12:18:30 2001.BEGIN |
641 | // ================================================================================================ |
642 | // static function: TestWLineAlongRestriction |
643 | // purpose: |
644 | // ================================================================================================ |
645 | static Standard_Boolean TestWLineAlongRestriction(const Handle(IntPatch_WLine)& theWLine, |
646 | const Standard_Integer theRank, |
647 | const Handle(Adaptor3d_HSurface)& theSurface, |
648 | const Handle(Adaptor3d_TopolTool)& theDomain, |
649 | const Standard_Real theTolArc) { |
650 | |
651 | Standard_Boolean result = Standard_False; |
652 | Standard_Integer NbPnts = theWLine->NbPnts(); |
653 | Standard_Integer along = 0; |
654 | |
655 | for(Standard_Integer i=1; i<=NbPnts; i++) { |
656 | const IntSurf_PntOn2S& Pmid = theWLine->Point(i); |
657 | Standard_Real u=0., v=0.; |
658 | if(theRank==1) Pmid.ParametersOnS1(u, v); |
659 | else Pmid.ParametersOnS2(u, v); |
660 | //------------------------------------------ |
661 | gp_Pnt ap; |
662 | gp_Vec ad1u, ad1v; |
663 | //Standard_Real nad1u, nad1v, tolu, tolv; |
664 | |
665 | theSurface->D1(u, v, ap, ad1u, ad1v); |
666 | //nad1u=ad1u.Magnitude(); |
667 | //nad1v=ad1v.Magnitude(); |
668 | //if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1; |
669 | //if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1; |
670 | //if(tolu>tolv) tolu=tolv; |
671 | //------------------------------------------ |
672 | |
673 | //if(theDomain->IsThePointOn(gp_Pnt2d(u, v),tolu)) { |
674 | // along++; |
675 | //} |
676 | |
677 | if(theDomain->IsThePointOn(gp_Pnt2d(u, v),theTolArc)) along++; |
678 | //if(along!=i) break; |
679 | } |
680 | if(along==NbPnts) result = Standard_True; |
681 | return result; |
682 | } |
683 | |
684 | |
685 | // ================================================================================================ |
686 | // static function: BuildRLineBasedOnWLine |
687 | // purpose: |
688 | // ================================================================================================ |
689 | static |
690 | Handle(IntPatch_RLine) BuildRLineBasedOnWLine(const Handle(IntPatch_WLine)& theWLine, |
691 | const Handle(Adaptor2d_HCurve2d)& theArc, |
692 | const Standard_Integer theRank) { |
693 | Handle(IntPatch_RLine) anRLine; |
694 | |
695 | if((theRank != 1) && (theRank != 2)) |
696 | return anRLine; |
697 | |
698 | gp_Pnt2d aPOnLine; |
699 | Standard_Real u=0., v=0.; |
700 | Standard_Integer nbvtx = theWLine->NbVertex(); |
701 | const IntPatch_Point& Vtx1 = theWLine->Vertex(1); |
702 | const IntPatch_Point& Vtx2 = theWLine->Vertex(nbvtx); |
703 | |
704 | if(theRank == 1) { |
705 | Vtx1.ParametersOnS1(u, v); |
706 | } |
707 | else { |
708 | Vtx1.ParametersOnS2(u, v); |
709 | } |
710 | |
711 | aPOnLine = gp_Pnt2d(u, v); |
712 | Standard_Real par1 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7); |
713 | |
714 | if(theRank == 1) { |
715 | Vtx2.ParametersOnS1(u, v); |
716 | } |
717 | else { |
718 | Vtx2.ParametersOnS2(u, v); |
719 | } |
720 | aPOnLine = gp_Pnt2d(u, v); |
721 | Standard_Real par2 = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), aPOnLine, 1.e-7); |
722 | |
723 | Standard_Real tol = (Vtx1.Tolerance() > Vtx2.Tolerance()) ? Vtx1.Tolerance() : Vtx2.Tolerance(); |
724 | |
725 | if(Abs(par1 - par2) < theArc->Resolution(tol)) |
726 | return anRLine; |
727 | |
728 | Standard_Boolean IsOnFirst = (theRank == 1); |
7fd59977 |
729 | |
730 | Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); |
731 | const Handle(IntSurf_LineOn2S)& Lori = theWLine->Curve(); |
732 | IntSurf_Transition TransitionUndecided; |
733 | |
734 | anRLine = new IntPatch_RLine(Standard_False, theWLine->TransitionOnS1(), theWLine->TransitionOnS2()); |
735 | |
736 | if(IsOnFirst) { |
737 | anRLine->SetArcOnS1(theArc); |
738 | } |
739 | else { |
740 | anRLine->SetArcOnS2(theArc); |
741 | } |
742 | |
743 | Standard_Integer k = 0; |
744 | if(par1 < par2) { |
745 | |
746 | for(k = 1; k <= Lori->NbPoints(); k++) { |
747 | aLineOn2S->Add(Lori->Value(k)); |
748 | } |
749 | anRLine->Add(aLineOn2S); |
750 | IntPatch_Point VtxFirst = Vtx1; |
751 | |
752 | VtxFirst.SetArc(IsOnFirst, //-- On First |
753 | theArc, |
754 | par1, |
755 | TransitionUndecided, |
756 | TransitionUndecided); |
757 | VtxFirst.SetParameter(par1); |
758 | anRLine->AddVertex(VtxFirst); |
759 | |
760 | for(k = 2; k < nbvtx; k++) { |
761 | IntPatch_Point Vtx = theWLine->Vertex(k); |
762 | if(theRank == 1) { |
763 | Vtx.ParametersOnS1(u, v); |
764 | } |
765 | else { |
766 | Vtx.ParametersOnS2(u, v); |
767 | } |
768 | gp_Pnt2d atmpPoint(u, v); |
769 | Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7); |
770 | Vtx.SetParameter(apar); |
771 | anRLine->AddVertex(Vtx); |
772 | } |
773 | |
774 | IntPatch_Point VtxLast = Vtx2; |
775 | VtxLast.SetArc(IsOnFirst, //-- On First |
776 | theArc, |
777 | par2, |
778 | TransitionUndecided, |
779 | TransitionUndecided); |
780 | VtxLast.SetParameter(par2); |
781 | anRLine->AddVertex(VtxLast); |
782 | anRLine->SetFirstPoint(1); |
783 | anRLine->SetLastPoint(nbvtx); |
784 | anRLine->ComputeVertexParameters(Precision::Confusion()); |
785 | } |
786 | else { |
787 | |
788 | for(k = Lori->NbPoints(); k >= 1; k--) { |
789 | aLineOn2S->Add(Lori->Value(k)); |
790 | } |
791 | anRLine->Add(aLineOn2S); |
792 | |
793 | IntPatch_Point VtxFirst = Vtx2; |
794 | VtxFirst.SetArc(IsOnFirst, //-- On First |
795 | theArc, |
796 | par2, |
797 | TransitionUndecided, |
798 | TransitionUndecided); |
799 | VtxFirst.SetParameter(par2); |
800 | anRLine->AddVertex(VtxFirst); |
801 | |
802 | for(k = nbvtx - 1; k >= 2; k--) { |
803 | IntPatch_Point Vtx = theWLine->Vertex(k); |
804 | Vtx.ReverseTransition(); |
805 | if(theRank == 1) { |
806 | Vtx.ParametersOnS1(u, v); |
807 | } |
808 | else { |
809 | Vtx.ParametersOnS2(u, v); |
810 | } |
811 | gp_Pnt2d atmpPoint(u, v); |
812 | Standard_Real apar = Geom2dInt_TheProjPCurOfGInter::FindParameter(theArc->Curve2d(), atmpPoint, 1.e-7); |
813 | Vtx.SetParameter(apar); |
814 | anRLine->AddVertex(Vtx); |
815 | } |
816 | IntPatch_Point VtxLast = Vtx1; |
817 | VtxLast.SetArc(IsOnFirst, //-- On First |
818 | theArc, |
819 | par1, |
820 | TransitionUndecided, |
821 | TransitionUndecided); |
822 | VtxLast.SetParameter(par1); |
823 | anRLine->AddVertex(VtxLast); |
824 | anRLine->SetFirstPoint(1); |
825 | anRLine->SetLastPoint(nbvtx); |
826 | anRLine->ComputeVertexParameters(Precision::Confusion()); |
827 | } |
828 | |
829 | return anRLine; |
830 | } |
831 | |
832 | // ================================================================================================ |
833 | // static function: BuildRLine |
834 | // purpose: build rline based on group of wlines |
835 | // return null handle if it is not possible to build rline |
836 | // ================================================================================================ |
837 | static |
838 | Handle(IntPatch_RLine) BuildRLine(const IntPatch_SequenceOfLine& theSeqOfWLine, |
839 | const Standard_Integer theRank, |
840 | const Handle(Adaptor3d_HSurface)& theSurface, |
841 | const Handle(Adaptor3d_TopolTool)& theDomain, |
842 | const Standard_Real theTolArc) { |
843 | Handle(IntPatch_RLine) anRLine; |
844 | const Handle(IntPatch_WLine)& aWLine1 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(1))); |
845 | const Handle(IntPatch_WLine)& aWLine2 = *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(theSeqOfWLine.Length()))); |
846 | const IntPatch_Point& P1 = aWLine1->Vertex(1); |
847 | const IntPatch_Point& P2 = aWLine2->Vertex(aWLine2->NbVertex()); |
848 | const Handle(Adaptor3d_HVertex)& aV1 = (theRank==1) ? P1.VertexOnS1() : P1.VertexOnS2(); |
849 | const Handle(Adaptor3d_HVertex)& aV2 = (theRank==1) ? P2.VertexOnS1() : P2.VertexOnS2(); |
850 | |
851 | // avoid closed and degenerated edges |
852 | if(aV1->IsSame(aV2)) |
853 | return anRLine; |
854 | |
855 | for(theDomain->Init(); theDomain->More(); theDomain->Next()) { |
856 | theDomain->Initialize(theDomain->Value()); |
857 | Standard_Boolean foundVertex1 = Standard_False; |
858 | Standard_Boolean foundVertex2 = Standard_False; |
859 | |
860 | for(theDomain->InitVertexIterator(); (!foundVertex1 || !foundVertex2) && theDomain->MoreVertex(); theDomain->NextVertex()) { |
861 | |
862 | if(!foundVertex1 && aV1->IsSame(theDomain->Vertex())) |
863 | foundVertex1 = Standard_True; |
864 | if(!foundVertex2 && aV2->IsSame(theDomain->Vertex())) |
865 | foundVertex2 = Standard_True; |
866 | } |
867 | |
868 | if(foundVertex1 && foundVertex2) { |
869 | Standard_Boolean buildrline = (theSeqOfWLine.Length() > 0); |
870 | |
871 | for(Standard_Integer i = 1; buildrline && i<=theSeqOfWLine.Length(); i++) { |
872 | const Handle(IntPatch_WLine)& aWLine = |
873 | *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(i))); |
874 | |
875 | Standard_Integer indexpnt = aWLine->NbPnts()/2; |
876 | if(indexpnt < 1) |
877 | buildrline = Standard_False; |
878 | else { |
879 | Standard_Real u = RealLast(), v = RealLast(); |
880 | const IntSurf_PntOn2S& POn2S = aWLine->Point(indexpnt); |
881 | if(theRank==1) { |
882 | POn2S.ParametersOnS1(u, v); |
883 | } |
884 | else { |
885 | POn2S.ParametersOnS2(u, v); |
886 | } |
887 | gp_Pnt2d aPOnArc, aPOnLine(u, v); |
888 | Standard_Real par = Geom2dInt_TheProjPCurOfGInter::FindParameter(theDomain->Value()->Curve2d(), aPOnLine, 1e-7); |
889 | aPOnArc = theDomain->Value()->Value(par); |
890 | gp_Pnt ap; |
891 | gp_Vec ad1u, ad1v; |
892 | Standard_Real nad1u, nad1v, tolu, tolv; |
893 | |
894 | theSurface->D1(u, v, ap, ad1u, ad1v); |
895 | nad1u=ad1u.Magnitude(); |
896 | nad1v=ad1v.Magnitude(); |
897 | if(nad1u>1e-12) tolu=theTolArc/nad1u; else tolu=0.1; |
898 | if(nad1v>1e-12) tolv=theTolArc/nad1v; else tolv=0.1; |
899 | Standard_Real aTolerance = (tolu > tolv) ? tolv : tolu; |
900 | |
901 | if(aPOnArc.Distance(aPOnLine) > aTolerance) { |
902 | buildrline = Standard_False; |
903 | } |
904 | } |
905 | } //end for |
906 | |
907 | if(buildrline) { |
908 | IntSurf_TypeTrans trans1 = IntSurf_Undecided, trans2 = IntSurf_Undecided; |
909 | |
910 | Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); |
911 | |
912 | for(Standard_Integer j = 1; j<=theSeqOfWLine.Length(); j++) { |
913 | const Handle(IntPatch_WLine)& atmpWLine = |
914 | *((Handle(IntPatch_WLine) *)& (theSeqOfWLine.Value(j))); |
915 | |
916 | const Handle(IntSurf_LineOn2S)& Lori = atmpWLine->Curve(); |
917 | |
918 | if(atmpWLine->TransitionOnS1()!=IntSurf_Undecided && atmpWLine->TransitionOnS1()!=IntSurf_Touch) { |
919 | trans1 = atmpWLine->TransitionOnS1(); |
920 | } |
921 | if(atmpWLine->TransitionOnS2()!=IntSurf_Undecided && atmpWLine->TransitionOnS2()!=IntSurf_Touch) { |
922 | trans2 = atmpWLine->TransitionOnS2(); |
923 | } |
924 | |
925 | Standard_Integer ParamMinOnLine = (Standard_Integer) atmpWLine->Vertex(1).ParameterOnLine(); |
926 | Standard_Integer ParamMaxOnLine = (Standard_Integer) atmpWLine->Vertex(atmpWLine->NbVertex()).ParameterOnLine(); |
927 | |
928 | for(Standard_Integer k = ParamMinOnLine; k <= ParamMaxOnLine; k++) { |
929 | aLineOn2S->Add(Lori->Value(k)); |
930 | } |
931 | } |
932 | |
933 | Handle(IntPatch_WLine) emulatedWLine = |
934 | new IntPatch_WLine(aLineOn2S, Standard_False, trans1, trans2); |
935 | |
936 | IntPatch_Point aFirstVertex = P1; |
937 | IntPatch_Point aLastVertex = P2; |
938 | aFirstVertex.SetParameter(1); |
939 | aLastVertex.SetParameter(aLineOn2S->NbPoints()); |
940 | |
941 | emulatedWLine->AddVertex(aFirstVertex); |
942 | Standard_Integer apointindex = 0; |
943 | |
944 | for(apointindex = 2; apointindex <= aWLine1->NbVertex(); apointindex++) { |
945 | IntPatch_Point aPoint = aWLine1->Vertex(apointindex); |
946 | Standard_Real aTolerance = (aPoint.Tolerance() > P1.Tolerance()) ? aPoint.Tolerance() : P1.Tolerance(); |
947 | if(aPoint.Value().IsEqual(P1.Value(), aTolerance)) { |
948 | aPoint.SetParameter(1); |
949 | emulatedWLine->AddVertex(aPoint); |
950 | } |
951 | } |
952 | |
953 | for(apointindex = 1; apointindex < aWLine2->NbVertex(); apointindex++) { |
954 | IntPatch_Point aPoint = aWLine2->Vertex(apointindex); |
955 | Standard_Real aTolerance = (aPoint.Tolerance() > P2.Tolerance()) ? aPoint.Tolerance() : P2.Tolerance(); |
956 | if(aPoint.Value().IsEqual(P2.Value(), aTolerance)) { |
957 | aPoint.SetParameter(aLineOn2S->NbPoints()); |
958 | emulatedWLine->AddVertex(aPoint); |
959 | } |
960 | } |
961 | |
962 | emulatedWLine->AddVertex(aLastVertex); |
963 | |
964 | anRLine = BuildRLineBasedOnWLine(emulatedWLine, theDomain->Value(), theRank); |
965 | |
966 | break; |
967 | } |
968 | } |
969 | } //end for |
970 | |
971 | return anRLine; |
972 | } |
973 | |
974 | // ================================================================================================ |
975 | // static function: TestWLinesToAnArc |
976 | // purpose: test if possible to replace group of wlines by rline and replace in the sequence slin |
977 | // ================================================================================================ |
978 | static void TestWLinesToAnArc(IntPatch_SequenceOfLine& slin, |
979 | const Handle(Adaptor3d_HSurface)& theSurface1, |
980 | const Handle(Adaptor3d_TopolTool)& theDomain1, |
981 | const Handle(Adaptor3d_HSurface)& theSurface2, |
982 | const Handle(Adaptor3d_TopolTool)& theDomain2, |
983 | const Standard_Real theTolArc) { |
984 | |
985 | IntPatch_SequenceOfLine aSeqOfWLine; |
986 | IntPatch_SequenceOfLine aSeqOfRLine; |
987 | for(Standard_Integer rank = 1; rank <= 2; rank++) { |
988 | for(Standard_Integer i=1; i<=slin.Length(); i++) { |
989 | if(slin.Value(i)->ArcType()!=IntPatch_Walking) |
990 | continue; |
991 | const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (slin.Value(i))); |
992 | Standard_Integer nbvtx = aWLine->NbVertex(); |
993 | const IntPatch_Point& Vtx1 = aWLine->Vertex(1); |
994 | const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx); |
995 | Standard_Boolean isvertex = Standard_False, wlineWasAppended = Standard_False; |
996 | |
997 | |
998 | if(rank==1) |
999 | isvertex = Vtx1.IsVertexOnS1(); |
1000 | else |
1001 | isvertex = Vtx1.IsVertexOnS2(); |
1002 | |
1003 | if(isvertex) { |
1004 | Standard_Boolean appendwline = Standard_True; |
1005 | if(rank==1) { |
1006 | if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) { |
1007 | appendwline = Standard_False; |
1008 | } |
1009 | } |
1010 | if(rank==2) { |
1011 | if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) { |
1012 | appendwline = Standard_False; |
1013 | } |
1014 | } |
1015 | wlineWasAppended = appendwline; |
1016 | if(appendwline) |
1017 | aSeqOfWLine.Append(aWLine); |
1018 | } |
1019 | else { |
1020 | if(aSeqOfWLine.Length()==0) |
1021 | continue; |
1022 | const Handle(IntPatch_WLine)& aLastWLine = |
1023 | *((Handle(IntPatch_WLine) *)& (aSeqOfWLine.Value(aSeqOfWLine.Length()))); |
1024 | const IntPatch_Point& aLastPoint = aLastWLine->Vertex(aLastWLine->NbVertex()); |
1025 | Standard_Real aTolerance = (aLastPoint.Tolerance() > Vtx1.Tolerance()) ? aLastPoint.Tolerance() : Vtx1.Tolerance(); |
1026 | if(aLastPoint.Value().IsEqual(Vtx1.Value(), aTolerance)) { |
1027 | Standard_Boolean appendwline = Standard_True; |
1028 | if(rank==1) { |
1029 | if(!aWLine->HasArcOnS1() && !TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc)) { |
1030 | appendwline = Standard_False; |
1031 | } |
1032 | } |
1033 | if(rank==2) { |
1034 | if(!aWLine->HasArcOnS2() && !TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc)) { |
1035 | appendwline = Standard_False; |
1036 | } |
1037 | } |
1038 | wlineWasAppended = appendwline; |
1039 | if(appendwline) |
1040 | aSeqOfWLine.Append(aWLine); |
1041 | } |
1042 | else { |
1043 | aSeqOfWLine.Clear(); |
1044 | } |
1045 | } |
1046 | |
1047 | isvertex = Standard_False; |
1048 | if(rank==1) |
1049 | isvertex = Vtx2.IsVertexOnS1(); |
1050 | else |
1051 | isvertex = Vtx2.IsVertexOnS2(); |
1052 | |
1053 | if(wlineWasAppended && isvertex) { |
1054 | // build rline based on sequence of wlines. |
1055 | Handle(IntPatch_RLine) anRLine; |
1056 | if(rank==1) { |
1057 | anRLine = BuildRLine(aSeqOfWLine, rank, theSurface1, theDomain1, theTolArc); |
1058 | } |
1059 | else { |
1060 | anRLine = BuildRLine(aSeqOfWLine, rank, theSurface2, theDomain2, theTolArc); |
1061 | } |
1062 | |
1063 | if(!anRLine.IsNull()) { |
1064 | aSeqOfRLine.Append(anRLine); |
1065 | for(Standard_Integer k=1; k<=aSeqOfWLine.Length(); k++) { |
1066 | for(Standard_Integer j=1; j<=slin.Length(); j++) { |
1067 | if(aSeqOfWLine(k)==slin(j)) { |
1068 | slin.Remove(j); |
1069 | break; |
1070 | } |
1071 | } |
1072 | } |
1073 | } |
1074 | aSeqOfWLine.Clear(); |
1075 | } |
1076 | } |
1077 | } |
1078 | |
1079 | for(Standard_Integer i=1; i<=aSeqOfRLine.Length(); i++) { |
1080 | slin.Append(aSeqOfRLine.Value(i)); |
1081 | } |
1082 | } |
1083 | // modified by NIZHNY-MKK Mon Apr 2 12:18:34 2001.END |
1084 | |
1085 | //==================================================================================== |
1086 | // function: MergeWLinesIfAllSegmentsAlongRestriction |
1087 | // |
1088 | // purpose: If the result of LineConstructor is a set of WLines segments which are |
1089 | // placed along RESTRICTION, we can suppose that this result is not correct: |
1090 | // here we should have a RLine. If it is not possible to construct RLine |
1091 | // we should merge segments of WLines into single WLine equals to the same |
1092 | // RLine. |
1093 | //==================================================================================== |
1094 | static void MergeWLinesIfAllSegmentsAlongRestriction(IntPatch_SequenceOfLine& theSlin, |
1095 | const Handle(Adaptor3d_HSurface)& theSurface1, |
1096 | const Handle(Adaptor3d_TopolTool)& theDomain1, |
1097 | const Handle(Adaptor3d_HSurface)& theSurface2, |
1098 | const Handle(Adaptor3d_TopolTool)& theDomain2, |
1099 | const Standard_Real theTolArc) |
1100 | { |
1101 | Standard_Integer i = 0, rank = 0; |
1102 | Standard_Real tol = 1.e-9; |
1103 | |
1104 | // here we check that all segments of WLines placed along restriction |
1105 | Standard_Integer WLOnRS1 = 0; |
1106 | Standard_Integer WLOnRS2 = 0; |
1107 | Standard_Integer NbWLines = 0; |
1108 | TColgp_SequenceOfPnt sqVertexPoints; |
1109 | |
1110 | for(rank = 1; rank <= 2; rank++) |
1111 | { |
1112 | NbWLines = 0; |
1113 | for(i = 1; i <= theSlin.Length(); i++) |
1114 | { |
1115 | if( theSlin.Value(i)->ArcType() != IntPatch_Walking ) |
1116 | continue; |
1117 | NbWLines++; |
1118 | const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i))); |
1119 | Standard_Integer nbvtx = aWLine->NbVertex(); |
1120 | const IntPatch_Point& Vtx1 = aWLine->Vertex(1); |
1121 | const IntPatch_Point& Vtx2 = aWLine->Vertex(nbvtx); |
1122 | if( rank==1 ) |
1123 | { |
1124 | sqVertexPoints.Append(Vtx1.Value()); |
1125 | sqVertexPoints.Append(Vtx2.Value()); |
1126 | if( TestWLineAlongRestriction(aWLine, rank, theSurface1, theDomain1, theTolArc) ) |
1127 | WLOnRS1++; |
1128 | } |
1129 | else |
1130 | { |
1131 | if( TestWLineAlongRestriction(aWLine, rank, theSurface2, theDomain2, theTolArc) ) |
1132 | WLOnRS2++; |
1133 | } |
1134 | } |
1135 | if( NbWLines == WLOnRS1 || NbWLines == WLOnRS2 ) break; |
1136 | } |
1137 | |
1138 | Standard_Integer WLineRank = 0; // not possible to merge WLines |
1139 | |
1140 | if( WLOnRS1 == NbWLines ) |
1141 | WLineRank = 1; // create merged WLine based on arc of S1 |
1142 | else if( WLOnRS2 == NbWLines ) |
1143 | WLineRank = 2; // create merged WLine based on arc of S2 |
1144 | else |
1145 | return; |
1146 | |
1147 | // avoid closed (degenerated) edges |
1148 | if( sqVertexPoints.Length() <= 2 ) |
1149 | return; |
1150 | if( sqVertexPoints.Value(1).IsEqual(sqVertexPoints.Value(sqVertexPoints.Length()),tol) ) |
1151 | return; |
1152 | |
1153 | Standard_Real TolVrtx = 1.e-5; |
1154 | Standard_Integer testPointIndex = ( sqVertexPoints.Length() > 3 ) ? ((Standard_Integer) sqVertexPoints.Length() / 2) : 2; |
1155 | gp_Pnt testPoint = sqVertexPoints.Value( testPointIndex ); |
1156 | Standard_Real Fp = 0., Lp = 0.; |
1157 | |
1158 | |
1159 | if( WLineRank == 1 ) |
1160 | { |
1161 | Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); |
1162 | Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface1,theDomain1,theSurface2,testPoint,TolVrtx,aLineOn2S,Fp,Lp); |
1163 | |
1164 | if( arcnumber == 0 ) |
1165 | return; |
1166 | |
1167 | Handle(IntPatch_WLine) anWLine = NULL; |
1168 | anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S); |
1169 | #ifdef DEB |
1170 | cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S1 to WLine ***" << endl; |
1171 | #endif |
1172 | theSlin.Clear(); |
1173 | theSlin.Append(anWLine); |
1174 | } |
1175 | else |
1176 | { |
1177 | Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S(); |
1178 | Standard_Integer arcnumber = GetArc(theSlin,WLineRank,theSurface2,theDomain2,theSurface1,testPoint,TolVrtx,aLineOn2S,Fp,Lp); |
1179 | |
1180 | if( arcnumber == 0 ) |
1181 | return; |
1182 | |
1183 | Handle(IntPatch_WLine) anWLine = NULL; |
1184 | anWLine = GetMergedWLineOnRestriction(theSlin,TolVrtx,aLineOn2S); |
1185 | #ifdef DEB |
1186 | cout << "*** TopOpeBRep_FaceIntersector: Merge WLines on Restriction S2 to WLine***" << endl; |
1187 | #endif |
1188 | theSlin.Clear(); |
1189 | theSlin.Append(anWLine); |
1190 | } |
1191 | } |
1192 | |
1193 | //========================================================================================= |
1194 | // function: GetArc |
1195 | // |
1196 | // purpose: Define arc on (OBJ) surface which all WLine segments are placed along. |
1197 | // Check states of points in the gaps between segments on (TOOL). If those states |
1198 | // are IN or ON return the LineOn2S based on points3D were given from detected arc. |
1199 | // Returns 0 if it is not possible to create merged WLine. |
1200 | //======================================================================================== |
1201 | static Standard_Integer GetArc(IntPatch_SequenceOfLine& theSlin, |
1202 | const Standard_Integer& theRankS, |
1203 | const Handle(Adaptor3d_HSurface)& theSurfaceObj, |
1204 | const Handle(Adaptor3d_TopolTool)& theDomainObj, |
1205 | const Handle(Adaptor3d_HSurface)& theSurfaceTool, |
1206 | const gp_Pnt& theTestPoint, |
1207 | Standard_Real& theVrtxTol, |
1208 | Handle(IntSurf_LineOn2S)& theLineOn2S, |
1209 | Standard_Real& theFirst, |
1210 | Standard_Real& theLast) |
1211 | { |
1212 | // 1. find number of arc (edge) on which the WLine segments are placed. |
1213 | |
1214 | Standard_Real MinDistance2 = 1.e+200, firstES1 = 0., lastES1 = 0.; |
1215 | Standard_Integer ArcNumber = 0, CurArc = 0, i = 0, j = 0; |
1216 | theFirst = 0.; |
1217 | theLast = 0.; |
1218 | |
1219 | for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next()) |
1220 | { |
1221 | CurArc++; |
1222 | Standard_Address anEAddress = theDomainObj->Edge(); |
1223 | |
1224 | if( anEAddress == NULL ) |
1225 | continue; |
1226 | |
1227 | TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; |
1228 | Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1); |
1229 | if ( aCEdge.IsNull() ) // e.g. degenerated edge, see OCC21770 |
1230 | continue; |
1231 | GeomAdaptor_Curve CE; |
1232 | CE.Load(aCEdge); |
1233 | Extrema_ExtPC epc(theTestPoint, CE, 1.e-7); |
1234 | |
1235 | if( epc.IsDone() ) |
1236 | { |
1237 | for( i = 1; i <= epc.NbExt(); i++ ) |
1238 | { |
1239 | if( epc.SquareDistance( i ) < MinDistance2 ) |
1240 | { |
1241 | MinDistance2 = epc.SquareDistance( i ); |
1242 | ArcNumber = CurArc; |
1243 | } |
1244 | } |
1245 | } |
1246 | } |
1247 | |
1248 | if( ArcNumber == 0 ) |
1249 | return 0; |
1250 | |
1251 | // 2. load parameters of founded edge and its arc. |
1252 | CurArc = 0; |
1253 | TColgp_SequenceOfPnt PointsFromArc; |
1254 | Handle(Adaptor2d_HCurve2d) arc = NULL; |
1255 | Standard_Real tol = 1.e-7; |
1256 | TColStd_SequenceOfReal WLVertexParameters; |
1257 | Standard_Boolean classifyOK = Standard_True; |
1258 | Standard_Real CheckTol = 1.e-5; |
1259 | |
1260 | for(theDomainObj->Init(); theDomainObj->More(); theDomainObj->Next()) |
1261 | { |
1262 | CurArc++; |
1263 | if( CurArc != ArcNumber ) |
1264 | continue; |
1265 | |
1266 | arc = theDomainObj->Value(); |
1267 | |
1268 | for(i = 1; i <= theSlin.Length(); i++) |
1269 | { |
1270 | if( theSlin.Value(i)->ArcType() != IntPatch_Walking ) |
1271 | continue; |
1272 | |
1273 | const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i))); |
1274 | |
1275 | Standard_Integer nbpnts = aWLine->NbPnts(); |
1276 | const IntSurf_PntOn2S& POn2S_F = aWLine->Point(1); |
1277 | const IntSurf_PntOn2S& POn2S_L = aWLine->Point(nbpnts); |
1278 | |
1279 | Standard_Real Upf = 0., Vpf = 0., Upl = 0., Vpl = 0.; |
1280 | |
1281 | if(theRankS == 1) |
1282 | { |
1283 | POn2S_F.ParametersOnS1(Upf, Vpf); |
1284 | POn2S_L.ParametersOnS1(Upl, Vpl); |
1285 | } |
1286 | else |
1287 | { |
1288 | POn2S_F.ParametersOnS2(Upf, Vpf); |
1289 | POn2S_L.ParametersOnS2(Upl, Vpl); |
1290 | } |
1291 | |
1292 | gp_Pnt2d aPOnLine_F(Upf, Vpf); |
1293 | gp_Pnt2d aPOnLine_L(Upl, Vpl); |
1294 | |
1295 | Standard_Real par_F = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_F, tol); |
1296 | Standard_Real par_L = Geom2dInt_TheProjPCurOfGInter::FindParameter(arc->Curve2d(), aPOnLine_L, tol); |
1297 | |
1298 | WLVertexParameters.Append(par_F); |
1299 | WLVertexParameters.Append(par_L); |
1300 | } |
1301 | |
1302 | for(i = 1; i <= WLVertexParameters.Length(); i++) |
1303 | { |
1304 | for(j = i; j <= WLVertexParameters.Length(); j++) |
1305 | { |
1306 | if(j == i) |
1307 | continue; |
1308 | |
1309 | if(WLVertexParameters.Value(i) > WLVertexParameters.Value(j)) |
1310 | { |
1311 | Standard_Real pol = WLVertexParameters.Value(i); |
1312 | WLVertexParameters.SetValue(i, WLVertexParameters.Value(j)); |
1313 | WLVertexParameters.SetValue(j, pol); |
1314 | } |
1315 | } |
1316 | } |
1317 | |
1318 | Standard_Address anEAddress = theDomainObj->Edge(); |
1319 | TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; |
1320 | TopoDS_Vertex V1, V2; |
1321 | TopExp::Vertices(*anE,V1,V2); |
1322 | Standard_Real MaxVertexTol = Max(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2)); |
1323 | theVrtxTol = MaxVertexTol; |
1324 | Standard_Real EdgeTol = BRep_Tool::Tolerance(*anE); |
1325 | CheckTol = Max(MaxVertexTol, EdgeTol); |
1326 | Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, firstES1, lastES1); |
1327 | // classification gaps |
1328 | // a. min - first |
1329 | if(Abs(firstES1 - WLVertexParameters.Value(1)) > arc->Resolution(MaxVertexTol)) |
1330 | { |
1331 | Standard_Real param = (firstES1 + WLVertexParameters.Value(1)) / 2.; |
1332 | gp_Pnt point; |
1333 | aCEdge->D0(param, point); |
1334 | if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) ) |
1335 | { |
1336 | classifyOK = Standard_False; |
1337 | break; |
1338 | } |
1339 | } |
1340 | // b. max - last |
1341 | if(Abs(lastES1 - WLVertexParameters.Value(WLVertexParameters.Length())) > arc->Resolution(MaxVertexTol)) |
1342 | { |
1343 | Standard_Real param = (lastES1 + WLVertexParameters.Value(WLVertexParameters.Length())) / 2.; |
1344 | gp_Pnt point; |
1345 | aCEdge->D0(param, point); |
1346 | if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) ) |
1347 | { |
1348 | classifyOK = Standard_False; |
1349 | break; |
1350 | } |
1351 | } |
1352 | // c. all middle gaps |
1353 | Standard_Integer NbChkPnts = theSlin.Length() - 1; |
1354 | for(i = 1; i <= NbChkPnts; i++) |
1355 | { |
1356 | if( Abs(WLVertexParameters.Value(i*2+1) - WLVertexParameters.Value(i*2)) > arc->Resolution(MaxVertexTol)) |
1357 | { |
1358 | Standard_Real param = (WLVertexParameters.Value(i*2) + WLVertexParameters.Value(i*2+1)) / 2.; |
1359 | gp_Pnt point; |
1360 | aCEdge->D0(param, point); |
1361 | if( !IsPointOK(point, theSurfaceTool->Surface(), CheckTol) ) |
1362 | { |
1363 | classifyOK = Standard_False; |
1364 | break; |
1365 | } |
1366 | } |
1367 | } |
1368 | |
1369 | if( !classifyOK ) |
1370 | break; |
1371 | |
1372 | // if classification gaps OK, fill sequence by the points from arc (edge) |
1373 | Standard_Real ParamFirst = WLVertexParameters.Value(1); |
1374 | Standard_Real ParamLast = WLVertexParameters.Value(WLVertexParameters.Length()); |
1375 | Standard_Real dParam = Abs(ParamLast - ParamFirst) / 100.; |
1376 | Standard_Real cParam = ParamFirst; |
1377 | for( i = 0; i < 100; i++ ) |
1378 | { |
1379 | if( i == 99 ) |
1380 | cParam = ParamLast; |
1381 | |
1382 | gp_Pnt cPnt; |
1383 | aCEdge->D0(cParam, cPnt); |
1384 | PointsFromArc.Append(cPnt); |
1385 | cParam += dParam; |
1386 | } |
1387 | theFirst = ParamFirst; |
1388 | theLast = ParamLast; |
1389 | |
1390 | } |
1391 | |
1392 | if( !classifyOK ) |
1393 | return 0; |
1394 | |
1395 | // create IntSurf_LineOn2S from points < PointsFromArc > |
1396 | for( i = 1; i <= PointsFromArc.Length(); i++ ) |
1397 | { |
1398 | Extrema_POnSurf pOnS1; |
1399 | Extrema_POnSurf pOnS2; |
1400 | gp_Pnt arcpoint = PointsFromArc.Value( i ); |
1401 | Standard_Boolean isOnS1 = GetPointOn2S( arcpoint, theSurfaceObj->Surface(), CheckTol, pOnS1 ); |
1402 | Standard_Boolean isOnS2 = GetPointOn2S( arcpoint, theSurfaceTool->Surface(), CheckTol, pOnS2 ); |
1403 | if( isOnS1 && isOnS2 ) |
1404 | { |
1405 | Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; |
1406 | pOnS1.Parameter(u1, v1); |
1407 | pOnS2.Parameter(u2, v2); |
1408 | IntSurf_PntOn2S pOn2S; |
1409 | pOn2S.SetValue(arcpoint, u1, v1, u2, v2 ); |
1410 | theLineOn2S->Add( pOn2S ); |
1411 | } |
1412 | } |
1413 | |
1414 | return ArcNumber; |
1415 | } |
1416 | |
1417 | //========================================================================================= |
1418 | // function: IsPointOK |
1419 | // |
1420 | // purpose: returns the state of testPoint on OTHER face. |
1421 | //======================================================================================== |
1422 | static Standard_Boolean IsPointOK(const gp_Pnt& theTestPnt, |
1423 | const Adaptor3d_Surface& theTestSurface, |
1424 | const Standard_Real& theTol) |
1425 | { |
1426 | Standard_Boolean result = Standard_False; |
1427 | Standard_Real ExtTol = theTol;//1.e-7; |
1428 | Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol); |
1429 | if( extPS.IsDone() && extPS.NbExt() > 0 ) |
1430 | { |
1431 | Standard_Integer i = 0, minext = 1; |
1432 | Standard_Real MinDist2 = 1.e+200; |
1433 | for(i = 1; i <= extPS.NbExt(); i++) |
1434 | { |
1435 | if( extPS.SquareDistance(i) < MinDist2 ) |
1436 | { |
1437 | minext = i; |
1438 | MinDist2 = extPS.SquareDistance(i); |
1439 | } |
1440 | } |
1441 | if( MinDist2 <= theTol * theTol ) |
1442 | result = Standard_True; |
1443 | } |
1444 | return result; |
1445 | } |
1446 | |
1447 | //========================================================================================= |
1448 | // function: GetPointOn2S |
1449 | // |
1450 | // purpose: check state of testPoint and returns result point if state is OK. |
1451 | //======================================================================================== |
1452 | static Standard_Boolean GetPointOn2S(const gp_Pnt& theTestPnt, |
1453 | const Adaptor3d_Surface& theTestSurface, |
1454 | const Standard_Real& theTol, |
1455 | Extrema_POnSurf& theResultPoint) |
1456 | { |
1457 | Standard_Boolean result = Standard_False; |
1458 | Standard_Real ExtTol = theTol;//1.e-7; |
1459 | Extrema_ExtPS extPS(theTestPnt,theTestSurface,ExtTol,ExtTol); |
1460 | if( extPS.IsDone() && extPS.NbExt() > 0 ) |
1461 | { |
1462 | Standard_Integer i = 0, minext = 1; |
1463 | Standard_Real MinDist2 = 1.e+200; |
1464 | for(i = 1; i <= extPS.NbExt(); i++) |
1465 | { |
1466 | if( extPS.SquareDistance(i) < MinDist2 ) |
1467 | { |
1468 | minext = i; |
1469 | MinDist2 = extPS.SquareDistance(i); |
1470 | } |
1471 | } |
1472 | if( MinDist2 <= theTol * theTol ) |
1473 | { |
1474 | result = Standard_True; |
1475 | theResultPoint = extPS.Point(minext); |
1476 | } |
1477 | } |
1478 | return result; |
1479 | } |
1480 | |
1481 | //========================================================================================= |
1482 | // function: GetMergedWLineOnRestriction |
1483 | // |
1484 | // purpose: merge sequence of WLines all placed along restriction if the conditions of |
1485 | // merging are OK. |
1486 | //======================================================================================== |
1487 | static Handle(IntPatch_WLine) GetMergedWLineOnRestriction(IntPatch_SequenceOfLine& theSlin, |
1488 | const Standard_Real& theVrtxTol, |
1489 | const Handle(IntSurf_LineOn2S)& theLineOn2S) |
1490 | { |
1491 | IntSurf_TypeTrans trans1 = IntSurf_Undecided; |
1492 | IntSurf_TypeTrans trans2 = IntSurf_Undecided; |
1493 | Standard_Integer i = 0; |
1494 | |
1495 | for(i = 1; i <= theSlin.Length(); i++) |
1496 | { |
1497 | if( theSlin.Value(i)->ArcType() != IntPatch_Walking ) |
1498 | continue; |
1499 | |
1500 | const Handle(IntPatch_WLine)& aWLine = *((Handle(IntPatch_WLine) *)& (theSlin.Value(i))); |
1501 | |
1502 | if( aWLine->TransitionOnS1() != IntSurf_Undecided && aWLine->TransitionOnS1() != IntSurf_Touch ) |
1503 | trans1 = aWLine->TransitionOnS1(); |
1504 | if( aWLine->TransitionOnS2() != IntSurf_Undecided && aWLine->TransitionOnS2() != IntSurf_Touch ) |
1505 | trans2 = aWLine->TransitionOnS2(); |
1506 | } |
1507 | |
1508 | Handle(IntPatch_WLine) mWLine = new IntPatch_WLine(theLineOn2S, Standard_False, trans1, trans2); |
1509 | |
1510 | Standard_Integer NbPnts = mWLine->NbPnts(); |
1511 | IntPatch_Point aFirstVertex, aLastVertex; |
1512 | |
1513 | aFirstVertex.SetValue(mWLine->Point(1).Value(),theVrtxTol,Standard_False); |
1514 | aLastVertex.SetValue(mWLine->Point(NbPnts).Value(),theVrtxTol,Standard_False); |
1515 | |
1516 | Standard_Real u1 = 0., v1 = 0., u2 = 0., v2 = 0.; |
1517 | |
1518 | mWLine->Point(1).Parameters(u1, v1, u2, v2); |
1519 | aFirstVertex.SetParameters(u1, v1, u2, v2); |
1520 | |
1521 | mWLine->Point(NbPnts).Parameters(u1, v1, u2, v2); |
1522 | aLastVertex.SetParameters(u1, v1, u2, v2); |
1523 | |
1524 | aFirstVertex.SetParameter(1); |
1525 | aLastVertex.SetParameter(theLineOn2S->NbPoints()); |
1526 | |
1527 | mWLine->AddVertex(aFirstVertex); |
1528 | mWLine->AddVertex(aLastVertex); |
1529 | |
1530 | mWLine->ComputeVertexParameters(theVrtxTol); |
1531 | |
1532 | return mWLine; |
1533 | } |