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