0027974: Visualization, ray tracing - Improve ray tracing engine
[occt.git] / src / BRepOffset / BRepOffset_Inter2d.cxx
CommitLineData
b311480e 1// Created on: 1996-09-03
2// Created by: Yves FRICAUD
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455
18
42cf5bc1 19#include <Adaptor2d_HCurve2d.hxx>
20#include <Adaptor3d_CurveOnSurface.hxx>
21#include <Adaptor3d_HSurface.hxx>
22#include <Bnd_Box.hxx>
23#include <BndLib_Add3dCurve.hxx>
7fd59977 24#include <BRep_Builder.hxx>
42cf5bc1 25#include <BRep_CurveRepresentation.hxx>
26#include <BRep_GCurve.hxx>
27#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
28#include <BRep_TEdge.hxx>
7fd59977 29#include <BRep_Tool.hxx>
7fd59977 30#include <BRepAdaptor_Curve.hxx>
42cf5bc1 31#include <BRepAdaptor_Curve2d.hxx>
7fd59977 32#include <BRepAdaptor_Surface.hxx>
42cf5bc1 33#include <BRepAlgo_AsDes.hxx>
34#include <BRepLib.hxx>
35#include <BRepLib_MakeVertex.hxx>
36#include <BRepOffset_Inter2d.hxx>
37#include <BRepOffset_Offset.hxx>
38#include <BRepOffset_Tool.hxx>
39#include <BRepTools.hxx>
7fd59977 40#include <BRepTools_WireExplorer.hxx>
7fd59977 41#include <Geom2d_BezierCurve.hxx>
42#include <Geom2d_BSplineCurve.hxx>
43#include <Geom2d_Line.hxx>
42cf5bc1 44#include <Geom2d_TrimmedCurve.hxx>
45#include <Geom2dAdaptor_HCurve.hxx>
7fd59977 46#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
42cf5bc1 47#include <Geom2dInt_GInter.hxx>
48#include <Geom_BSplineCurve.hxx>
7fd59977 49#include <Geom_BSplineSurface.hxx>
7fd59977 50#include <Geom_ConicalSurface.hxx>
42cf5bc1 51#include <Geom_CylindricalSurface.hxx>
52#include <Geom_Line.hxx>
53#include <Geom_Plane.hxx>
54#include <Geom_TrimmedCurve.hxx>
7fd59977 55#include <GeomAdaptor_HSurface.hxx>
42cf5bc1 56#include <GeomAdaptor_Surface.hxx>
57#include <GeomAPI_ProjectPointOnCurve.hxx>
58#include <GeomConvert_CompCurveToBSplineCurve.hxx>
7fd59977 59#include <GeomLib.hxx>
60#include <GeomProjLib.hxx>
42cf5bc1 61#include <gp_Pnt.hxx>
62#include <IntRes2d_IntersectionPoint.hxx>
63#include <IntRes2d_IntersectionSegment.hxx>
64#include <Precision.hxx>
65#include <TColGeom2d_SequenceOfCurve.hxx>
7fd59977 66#include <TColgp_Array1OfPnt2d.hxx>
42cf5bc1 67#include <TColgp_SequenceOfPnt.hxx>
68#include <TopExp.hxx>
69#include <TopExp_Explorer.hxx>
70#include <TopoDS.hxx>
71#include <TopoDS_Edge.hxx>
72#include <TopoDS_Face.hxx>
73#include <TopoDS_Iterator.hxx>
74#include <TopoDS_Vertex.hxx>
75#include <TopoDS_Wire.hxx>
76#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
77#include <TopTools_ListIteratorOfListOfShape.hxx>
78#include <TopTools_ListOfShape.hxx>
b0fbc579 79#include <BOPCol_ListOfShape.hxx>
80#include <BOPTools_AlgoTools.hxx>
7fd59977 81
42cf5bc1 82#include <stdio.h>
1896126e 83#ifdef DRAW
84#include <DBRep.hxx>
ec357c5c 85#include <Geom2d_BoundedCurve.hxx>
86#include <Geom_BoundedSurface.hxx>
87#include <Geom_BoundedCurve.hxx>
88#include <BRep_CurveOnSurface.hxx>
89#include <Geom_Surface.hxx>
b0091bc9 90Standard_Boolean Inter2dAffichInt2d;
1896126e 91static Standard_Integer NbF2d = 0;
92static Standard_Integer NbE2d = 0;
93static Standard_Integer NbNewVertices = 0;
94#endif
7fd59977 95
96//=======================================================================
97//function : CommonVertex
98//purpose :
99//=======================================================================
100
101static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
102 TopoDS_Edge& E2)
103{
104 TopoDS_Vertex V1[2],V2[2],V;
b0fbc579 105 //
7fd59977 106 TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
107 TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
108 // The first edge is the current one, the second edge is the next one.
109 // We check last vertex of the first edge first.
7fd59977 110 if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
111 if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
b0fbc579 112 //
7fd59977 113 return V;
114}
115
116//=======================================================================
117//function : Store
b0fbc579 118//purpose : The vertices are added despite of the coincidence with
119// already added vertices. When all vertices for all edges
120// are added the coinciding chains of vertices should be fused
121// using FuseVertices() method.
7fd59977 122//=======================================================================
b0fbc579 123static void Store (const TopoDS_Edge& E1,
124 const TopoDS_Edge& E2,
125 const TopTools_ListOfShape& LV1,
126 const TopTools_ListOfShape& LV2,
127 Handle(BRepAlgo_AsDes) AsDes,
128 Standard_Real Tol,
129 TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
7fd59977 130{
b0fbc579 131 BRep_Builder aBB;
132 for (Standard_Integer i = 0; i < 2; ++i) {
133 const TopoDS_Edge& aE = !i ? E1 : E2;
134 const TopTools_ListOfShape& aLV = !i ? LV1 : LV2;
135 const TopTools_ListOfShape& aLVEx = AsDes->Descendant(aE);
136 if (aLVEx.IsEmpty()) {
137 if (aLV.Extent()) AsDes->Add(aE, aLV);
138 continue;
7fd59977 139 }
b0fbc579 140 //
141 TopTools_MapOfShape aMV;
142 TopTools_ListIteratorOfListOfShape aIt(aLV);
143 for (; aIt.More(); aIt.Next()) {
144 const TopoDS_Vertex& aV = TopoDS::Vertex(aIt.Value());
145 if (!aMV.Add(aV)) {
146 continue;
7fd59977 147 }
b0fbc579 148 gp_Pnt aP = BRep_Tool::Pnt(aV);
149 //
150 TopTools_ListOfShape aLVC;
151 TopTools_ListIteratorOfListOfShape aItEx(aLVEx);
152 for (; aItEx.More(); aItEx.Next()) {
153 const TopoDS_Vertex& aVEx = TopoDS::Vertex(aItEx.Value());
154 if (aV.IsSame(aVEx)) {
9b7f3f83 155 break;
156 }
b0fbc579 157 gp_Pnt aPEx = BRep_Tool::Pnt(aVEx);
158 //
159 if (aP.IsEqual(aPEx, Tol)) {
160 aLVC.Append(aVEx);
9b7f3f83 161 }
7fd59977 162 }
b0fbc579 163 //
164 if (aItEx.More()) {
165 continue;
7fd59977 166 }
b0fbc579 167 //
168 if (aLVC.Extent()) {
169 TopTools_ListOfShape aLVN;
170 aLVN.Append(aV);
171 //
172 TopTools_ListIteratorOfListOfShape aItLV(aLVC);
173 for (; aItLV.More(); aItLV.Next()) {
174 const TopoDS_Shape& aVC = aItLV.Value();
175 TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aVC);
176 if (!pLV) {
177 aDMVV.Add(aVC, aLVN);
178 }
179 else {
180 pLV->Append(aV);
181 }
182 }
183 //
184 TopTools_ListOfShape* pLV = aDMVV.ChangeSeek(aV);
185 if (!pLV) {
186 aDMVV.Add(aV, aLVC);
187 }
188 else {
189 pLV->Append(aLVC);
190 }
7fd59977 191 }
b0fbc579 192 //
193 aBB.UpdateVertex(aV, Tol);
194 AsDes->Add(aE, aV);
7fd59977 195 }
7fd59977 196 }
7fd59977 197}
198
7fd59977 199//=======================================================================
200//function : EdgeInter
201//purpose :
202//=======================================================================
203
204static void EdgeInter(const TopoDS_Face& F,
9b7f3f83 205 const BRepAdaptor_Surface& BAsurf,
206 const TopoDS_Edge& E1,
207 const TopoDS_Edge& E2,
208 const Handle(BRepAlgo_AsDes)& AsDes,
209 Standard_Real Tol,
b0fbc579 210 Standard_Boolean WithOri,
211 TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
7fd59977 212{
213#ifdef DRAW
b0091bc9 214 if (Inter2dAffichInt2d) {
1896126e 215 char name[256];
7fd59977 216 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
217 DBRep::Set(name,E1);
218 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
219 DBRep::Set(name,E2);
220 }
221#endif
222
223 if (E1.IsSame(E2))
224 return;
225
226 Standard_Real f[3],l[3];
975ec82a 227 Standard_Real TolDub = 1.e-7;
7fd59977 228 Standard_Integer i;
229
230 BRep_Tool::Range(E1, f[1], l[1]);
231 BRep_Tool::Range(E2, f[2], l[2]);
232
233 BRepAdaptor_Curve CE1(E1,F);
234 BRepAdaptor_Curve CE2(E2,F);
235
236 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
237 TopTools_ListOfShape LV1;
238 TopTools_ListOfShape LV2;
239 BRep_Builder B;
240
241 TopoDS_Vertex CV;
242 if (!TopExp::CommonVertex( E1, E2, CV ))
243 {
244 BRepLib::BuildCurve3d(E1);
245 BRepLib::BuildCurve3d(E2);
246
247 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
248 TolSum = Max( TolSum, 1.e-5 );
249
250 TColgp_SequenceOfPnt ResPoints;
251 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
252 gp_Pnt DegPoint;
253 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
254
255 if (WithDegen)
9b7f3f83 256 {
257 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
258 TopoDS_Iterator iter( EI[ideg] );
259 if (iter.More())
260 {
261 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
262 DegPoint = BRep_Tool::Pnt(vdeg);
263 }
264 else
265 {
266 BRepAdaptor_Curve CEdeg( EI[ideg], F );
267 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
268 }
269 }
270 //
7fd59977 271 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
272 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
273 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
274 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
275 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
276 for (i = 1; i <= Inter2d.NbPoints(); i++)
9b7f3f83 277 {
278 gp_Pnt P3d;
279 if (WithDegen)
280 P3d = DegPoint;
281 else
282 {
283 gp_Pnt2d P2d = Inter2d.Point(i).Value();
284 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
285 }
286 ResPoints.Append( P3d );
287 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
288 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
289 }
7fd59977 290
291 for (i = 1; i <= ResPoints.Length(); i++)
9b7f3f83 292 {
293 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
294 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
295 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
296 {
0797d9d3 297#ifdef OCCT_DEBUG
9b7f3f83 298 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
7fd59977 299#endif
9b7f3f83 300 continue;
301 }
302
303 gp_Pnt P = ResPoints(i); //ponc1.Value();
304 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
975ec82a 305 aNewVertex.Orientation(TopAbs_INTERNAL);
9b7f3f83 306 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
307 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
308 gp_Pnt P1 = CE1.Value(aT1);
309 gp_Pnt P2 = CE2.Value(aT2);
310 Standard_Real dist1, dist2, dist3;
311 dist1 = P1.Distance(P);
312 dist2 = P2.Distance(P);
313 dist3 = P1.Distance(P2);
314 dist1 = Max( dist1, dist2 );
315 dist1 = Max( dist1, dist3 );
316 B.UpdateVertex( aNewVertex, dist1 );
317
0797d9d3 318#ifdef OCCT_DEBUG
9b7f3f83 319 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
320 {
321 cout << "out of limit"<<endl;
322 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
323 }
324 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
325 {
326 cout << "out of limit"<<endl;
327 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
328 }
498ce76b 329 Standard_Real MilTol2 = 1000*Tol*Tol;
9b7f3f83 330 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
331 {
332 cout << "Inter2d : Solution rejected "<<endl;
333 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
334 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
335 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
336 cout<<"MaxDist = "<<dist1<<endl;
337 }
7fd59977 338#endif
9b7f3f83 339 //define the orientation of a new vertex
340 TopAbs_Orientation OO1 = TopAbs_REVERSED;
341 TopAbs_Orientation OO2 = TopAbs_REVERSED;
342 if (WithOri)
343 {
344 BRepAdaptor_Curve2d PCE1( E1, F );
345 BRepAdaptor_Curve2d PCE2( E2, F );
346 gp_Pnt2d P2d1, P2d2;
347 gp_Vec2d V1, V2, V1or, V2or;
348 PCE1.D1( aT1, P2d1, V1 );
349 PCE2.D1( aT2, P2d2, V2 );
350 V1or = V1; V2or = V2;
351 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
352 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
353 Standard_Real CrossProd = V2or ^ V1;
0797d9d3 354#ifdef OCCT_DEBUG
9b7f3f83 355 if (Abs(CrossProd) <= gp::Resolution())
356 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
7fd59977 357#endif
9b7f3f83 358 if (CrossProd > 0.)
359 OO1 = TopAbs_FORWARD;
360 CrossProd = V1or ^ V2;
361 if (CrossProd > 0.)
362 OO2 = TopAbs_FORWARD;
363 }
364 LV1.Append( aNewVertex.Oriented(OO1) );
365 LV2.Append( aNewVertex.Oriented(OO2) );
366 }
7fd59977 367 }
368
369 //----------------------------------
0d969553 370 // Test at end.
7fd59977 371 //---------------------------------
372 Standard_Real U1,U2;
373 Standard_Real TolConf = Tol;
374 TopoDS_Vertex V1[2],V2[2];
375 TopExp::Vertices(E1,V1[0],V1[1]);
376 TopExp::Vertices(E2,V2[0],V2[1]);
377
378 Standard_Integer j;
379 for (j = 0; j < 2; j++) {
380 if (V1[j].IsNull()) continue;
381 for (Standard_Integer k = 0; k < 2; k++) {
382 if (V2[k].IsNull()) continue;
b0fbc579 383 if (V1[j].IsSame(V2[k])) {
384 if (AsDes->HasAscendant(V1[j])) {
385 continue;
386 }
387 }
388 //
7fd59977 389 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
390 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
391 Standard_Real Dist = P1.Distance(P2);
392 if (Dist < TolConf) {
b0fbc579 393 Standard_Real aTol =
394 Max(BRep_Tool::Tolerance(V1[j]), BRep_Tool::Tolerance(V2[k]));
9b7f3f83 395 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
396 U1 = (j == 0) ? f[1] : l[1];
397 U2 = (k == 0) ? f[2] : l[2];
b0fbc579 398 //
9b7f3f83 399 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
9b7f3f83 400 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
401 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
b0fbc579 402 //
9b7f3f83 403 LV1.Prepend(V.Oriented(V1[j].Orientation()));
404 LV2.Prepend(V.Oriented(V2[k].Orientation()));
7fd59977 405 }
406 }
407 }
408
409 Standard_Boolean AffichPurge = Standard_False;
410
411 if ( !LV1.IsEmpty()) {
412 //----------------------------------
0d969553
Y
413 // Remove all vertices.
414 // There can be doubles
7fd59977 415 //----------------------------------
416 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
417 gp_Pnt P1,P2;
418 Standard_Boolean Purge = Standard_True;
419
420 while (Purge) {
421 i = 1;
422 Purge = Standard_False;
423 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
9b7f3f83 424 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
425 j = 1;
426 it2LV1.Initialize(LV1);
427 while (j < i) {
428 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
429 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
7fd59977 430// Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
9b7f3f83 431// if (P1.IsEqual(P2,10*Tol)) {
432 Standard_Real aTol;
7fd59977 433
9b7f3f83 434 aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
435 BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
436 if (P1.IsEqual(P2,aTol)) {
7fd59977 437// Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
9b7f3f83 438 LV1.Remove(it1LV1);
439 LV2.Remove(it1LV2);
440 if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
441 Purge = Standard_True;
442 break;
443 }
444 j++;
445 it2LV1.Next();
446 }
447 if (Purge) break;
448 i++;
7fd59977 449 }
450 }
451 //---------------------------------
0d969553 452 // Vertex storage in DS.
7fd59977 453 //---------------------------------
7fd59977 454 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
7fd59977 455 TolStore = Max(TolStore, 10.*Tol);
b0fbc579 456 Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
7fd59977 457 }
458}
459//=======================================================================
460//function : EdgeInter
461//purpose :
462//=======================================================================
463
464static void RefEdgeInter(const TopoDS_Face& F,
9b7f3f83 465 const BRepAdaptor_Surface& BAsurf,
466 const TopoDS_Edge& E1,
467 const TopoDS_Edge& E2,
468 const Handle(BRepAlgo_AsDes)& AsDes,
469 Standard_Real Tol,
470 Standard_Boolean WithOri,
b0fbc579 471 gp_Pnt& Pref,
472 TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
7fd59977 473{
474#ifdef DRAW
b0091bc9 475 if (Inter2dAffichInt2d) {
1896126e 476 char name[256];
7fd59977 477 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
478 DBRep::Set(name,E1);
479 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
480 DBRep::Set(name,E2);
481 }
482#endif
483
484 if (E1.IsSame(E2))
485 return;
486
487 Standard_Real f[3],l[3];
975ec82a 488 Standard_Real TolDub = 1.e-7;
7fd59977 489 Standard_Integer i;
490
491 //BRep_Tool::Range(E1, f[1], l[1]);
492 //BRep_Tool::Range(E2, f[2], l[2]);
493
494 BRepAdaptor_Curve CE1(E1,F);
495 BRepAdaptor_Curve CE2(E2,F);
496
497 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
498 TopTools_ListOfShape LV1;
499 TopTools_ListOfShape LV2;
500 BRep_Builder B;
501
502 BRepLib::BuildCurve3d(E1);
503 BRepLib::BuildCurve3d(E2);
504
505 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
506 TolSum = Max( TolSum, 1.e-5 );
507
508 TColgp_SequenceOfPnt ResPoints;
509 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
510 gp_Pnt DegPoint;
511 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
512
513 if (WithDegen)
514 {
515 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
516 TopoDS_Iterator iter( EI[ideg] );
517 if (iter.More())
9b7f3f83 518 {
519 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
520 DegPoint = BRep_Tool::Pnt(vdeg);
521 }
7fd59977 522 else
9b7f3f83 523 {
524 BRepAdaptor_Curve CEdeg( EI[ideg], F );
525 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
526 }
7fd59977 527 }
9b7f3f83 528 //
7fd59977 529 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
530 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
531 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
532 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
533 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
534 for (i = 1; i <= Inter2d.NbPoints(); i++)
535 {
536 gp_Pnt P3d;
537 if (WithDegen)
9b7f3f83 538 P3d = DegPoint;
7fd59977 539 else
9b7f3f83 540 {
541 gp_Pnt2d P2d = Inter2d.Point(i).Value();
542 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
543 }
7fd59977 544 ResPoints.Append( P3d );
545 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
546 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
547 }
548
549 for (i = 1; i <= ResPoints.Length(); i++)
550 {
551 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
552 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
553 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
9b7f3f83 554 {
0797d9d3 555#ifdef OCCT_DEBUG
9b7f3f83 556 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
7fd59977 557#endif
9b7f3f83 558 continue;
559 }
7fd59977 560
561 gp_Pnt P = ResPoints(i); //ponc1.Value();
562 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
975ec82a 563 aNewVertex.Orientation(TopAbs_INTERNAL);
7fd59977 564 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
565 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
566 gp_Pnt P1 = CE1.Value(aT1);
567 gp_Pnt P2 = CE2.Value(aT2);
568 Standard_Real dist1, dist2, dist3;
569 dist1 = P1.Distance(P);
570 dist2 = P2.Distance(P);
571 dist3 = P1.Distance(P2);
572 dist1 = Max( dist1, dist2 );
573 dist1 = Max( dist1, dist3 );
574 B.UpdateVertex( aNewVertex, dist1 );
575
0797d9d3 576#ifdef OCCT_DEBUG
7fd59977 577 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
9b7f3f83 578 {
579 cout << "out of limit"<<endl;
580 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
581 }
7fd59977 582 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
9b7f3f83 583 {
584 cout << "out of limit"<<endl;
585 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
586 }
498ce76b 587 Standard_Real MilTol2 = 1000*Tol*Tol;
7fd59977 588 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
9b7f3f83 589 {
590 cout << "Inter2d : Solution rejected"<<endl;
591 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
592 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
593 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
594 cout<<"MaxDist = "<<dist1<<endl;
595 }
7fd59977 596#endif
597 //define the orientation of a new vertex
598 TopAbs_Orientation OO1 = TopAbs_REVERSED;
599 TopAbs_Orientation OO2 = TopAbs_REVERSED;
600 if (WithOri)
9b7f3f83 601 {
602 BRepAdaptor_Curve2d PCE1( E1, F );
603 BRepAdaptor_Curve2d PCE2( E2, F );
604 gp_Pnt2d P2d1, P2d2;
605 gp_Vec2d V1, V2, V1or, V2or;
606 PCE1.D1( aT1, P2d1, V1 );
607 PCE2.D1( aT2, P2d2, V2 );
608 V1or = V1; V2or = V2;
609 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
610 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
611 Standard_Real CrossProd = V2or ^ V1;
0797d9d3 612#ifdef OCCT_DEBUG
9b7f3f83 613 if (Abs(CrossProd) <= gp::Resolution())
614 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
7fd59977 615#endif
9b7f3f83 616 if (CrossProd > 0.)
617 OO1 = TopAbs_FORWARD;
618 CrossProd = V1or ^ V2;
619 if (CrossProd > 0.)
620 OO2 = TopAbs_FORWARD;
621 }
7fd59977 622 LV1.Append( aNewVertex.Oriented(OO1) );
623 LV2.Append( aNewVertex.Oriented(OO2) );
624 }
625
626 //----------------------------------
0d969553 627 // Test at end.
7fd59977 628 //---------------------------------
629 Standard_Real U1,U2;
630 Standard_Real TolConf = Tol;
631 TopoDS_Vertex V1[2],V2[2];
632 TopExp::Vertices(E1,V1[0],V1[1]);
633 TopExp::Vertices(E2,V2[0],V2[1]);
634
635 Standard_Integer j;
636 for (j = 0; j < 2; j++) {
637 if (V1[j].IsNull()) continue;
638 for (Standard_Integer k = 0; k < 2; k++) {
639 if (V2[k].IsNull()) continue;
b0fbc579 640 if (V1[j].IsSame(V2[k])) {
641 if (AsDes->HasAscendant(V1[j])) {
642 continue;
643 }
644 }
645 //
7fd59977 646 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
647 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
648 Standard_Real Dist = P1.Distance(P2);
649 if (Dist < TolConf) {
9b7f3f83 650 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
651 U1 = (j == 0) ? f[1] : l[1];
652 U2 = (k == 0) ? f[2] : l[2];
653 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
654 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
655 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
9b7f3f83 656 LV1.Prepend(V.Oriented(V1[j].Orientation()));
657 LV2.Prepend(V.Oriented(V2[k].Orientation()));
7fd59977 658 }
659 }
660 }
661
662 Standard_Boolean AffichPurge = Standard_False;
663
664 if ( !LV1.IsEmpty()) {
665 //----------------------------------
0d969553
Y
666 // Remove all vertices.
667 // there can be doubles
7fd59977 668 //----------------------------------
669 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
670 gp_Pnt P1,P2;
671 Standard_Boolean Purge = Standard_True;
672
673 while (Purge) {
674 i = 1;
675 Purge = Standard_False;
676 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
9b7f3f83 677 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
678 j = 1;
679 it2LV1.Initialize(LV1);
680 while (j < i) {
681 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
682 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
683 if (P1.IsEqual(P2,10*Tol)) {
684 LV1.Remove(it1LV1);
685 LV2.Remove(it1LV2);
686 if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
687 Purge = Standard_True;
688 break;
689 }
690 j++;
691 it2LV1.Next();
692 }
693 if (Purge) break;
694 i++;
7fd59977 695 }
696 }
697 //---------------------------------
0d969553 698 // Vertex storage in SD.
7fd59977 699 //---------------------------------
700////-----------------------------------------------------
701 if(LV1.Extent() > 1) {
702 //cout << "IFV - RefEdgeInter: remove vertex" << endl;
703 Standard_Real dmin = RealLast();
704 TopoDS_Vertex Vmin;
705 for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
9b7f3f83 706 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
707 Standard_Real d = P.SquareDistance(Pref);
708 if(d < dmin) {
709 dmin = d;
710 Vmin = TopoDS::Vertex(it1LV1.Value());
711 }
7fd59977 712 }
713 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
9b7f3f83 714 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
715 if(!Vmin.IsSame(it1LV1.Value())) {
716 LV1.Remove(it1LV1);
717 LV2.Remove(it1LV2);
718 if(!it1LV1.More()) break;
719 }
7fd59977 720 }
721 }
722
723////-----------------------------------------------------
7fd59977 724 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
7fd59977 725 TolStore = Max(TolStore, 10.*Tol);
b0fbc579 726 Store (E1,E2,LV1,LV2,AsDes,TolStore, aDMVV);
7fd59977 727 }
728}
729
730
731//======================================================================
732//function : EvaluateMaxSegment
733//purpose : return MaxSegment to pass in approximation
734//======================================================================
735
736static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurveOnSurface)
737{
738 Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface();
739 Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
740
741 Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
742
743 if (aSurf->GetType() == GeomAbs_BSplineSurface) {
744 Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
745 aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
746 }
747 if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
748 aNbC2dKnots = aCurv2d->NbKnots();
749 }
750 Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ;
751 return aReturn;
752}
753
754
755//=======================================================================
756//function : ExtendPCurve
757//purpose :
758//=======================================================================
759
760static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
9b7f3f83 761 const Standard_Real anEf,
762 const Standard_Real anEl,
763 const Standard_Real a2Offset,
764 Handle(Geom2d_Curve)& NewPCurve)
7fd59977 765{
766 NewPCurve = aPCurve;
767 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
c5f3a425 768 NewPCurve = Handle(Geom2d_TrimmedCurve)::DownCast (NewPCurve)->BasisCurve();
7fd59977 769
770 Standard_Real FirstPar = NewPCurve->FirstParameter();
771 Standard_Real LastPar = NewPCurve->LastParameter();
772
773 if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
774 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
775 {
776 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
9b7f3f83 777 {
778 Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast (NewPCurve);
779 if (aBezier->NbPoles() == 2)
780 {
781 TColgp_Array1OfPnt2d thePoles(1,2);
782 aBezier->Poles(thePoles);
783 gp_Vec2d aVec(thePoles(1), thePoles(2));
784 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
785 return Standard_True;
786 }
787 }
7fd59977 788 else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
9b7f3f83 789 {
790 Handle(Geom2d_BSplineCurve) aBSpline = Handle(Geom2d_BSplineCurve)::DownCast (NewPCurve);
791 if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
792 {
793 TColgp_Array1OfPnt2d thePoles(1,2);
794 aBSpline->Poles(thePoles);
795 gp_Vec2d aVec(thePoles(1), thePoles(2));
796 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
797 return Standard_True;
798 }
799 }
7fd59977 800 }
801
802 FirstPar = aPCurve->FirstParameter();
803 LastPar = aPCurve->LastParameter();
804 Handle(Geom2d_TrimmedCurve) aTrCurve =
805 new Geom2d_TrimmedCurve(aPCurve, FirstPar, LastPar);
806
807 // The curve is not prolonged on begin or end.
808 // Trying to prolong it adding a segment to its bound.
809 gp_Pnt2d aPBnd;
810 gp_Vec2d aVBnd;
811 gp_Pnt2d aPBeg;
812 gp_Dir2d aDBnd;
813 Handle(Geom2d_Line) aLin;
814 Handle(Geom2d_TrimmedCurve) aSegment;
815 Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
816 Standard_Real aTol = Precision::Confusion();
817 Standard_Real aDelta = Max(a2Offset, 1.);
818
819 if (FirstPar > anEf - a2Offset) {
820 aPCurve->D1(FirstPar, aPBnd, aVBnd);
821 aDBnd.SetXY(aVBnd.XY());
822 aPBeg = aPBnd.Translated(gp_Vec2d(-aDelta*aDBnd.XY()));
823 aLin = new Geom2d_Line(aPBeg, aDBnd);
824 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
825
826 if (!aCompCurve.Add(aSegment, aTol))
827 return Standard_False;
828 }
829
830 if (LastPar < anEl + a2Offset) {
831 aPCurve->D1(LastPar, aPBeg, aVBnd);
832 aDBnd.SetXY(aVBnd.XY());
833 aLin = new Geom2d_Line(aPBeg, aDBnd);
834 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
835
836 if (!aCompCurve.Add(aSegment, aTol))
837 return Standard_False;
838 }
839
840 NewPCurve = aCompCurve.BSplineCurve();
841 return Standard_True;
842}
843
844//=======================================================================
845//function : ExtentEdge
846//purpose :
847//=======================================================================
848
849// Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
850//static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE)
851static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
852{
853 //BRepLib::BuildCurve3d(E);
854
855 TopoDS_Shape aLocalShape = E.EmptyCopied();
856 Standard_Real anEf;
857 Standard_Real anEl;
858 Standard_Real a2Offset = 2.*Abs(theOffset);
859 BRep_Builder BB;
860 Standard_Integer i, j;
861
862 BRep_Tool::Range(E, anEf, anEl);
863 NE = TopoDS::Edge(aLocalShape);
864// NE = TopoDS::Edge(E.EmptyCopied());
0d969553
Y
865 // Enough for analytic edges, for general case reconstruct the
866 // geometry of the edge recalculating the intersection of surfaces.
7fd59977 867
868 //BRepLib::BuildCurve3d(E);
869
870 Standard_Integer NbPCurves = 0;
871 Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
872 Handle(Geom2d_Curve) MinPC;
873 Handle(Geom_Surface) MinSurf;
874 TopLoc_Location MinLoc;
875
876 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
877 for (; itr.More(); itr.Next())
878 {
879 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
880 Standard_Real FirstPar, LastPar;
881 if (CurveRep->IsCurveOnSurface())
9b7f3f83 882 {
883 NbPCurves++;
884 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
885 FirstPar = theCurve->FirstParameter();
886 LastPar = theCurve->LastParameter();
887
888 if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
889 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
890 {
891 Handle(Geom2d_Curve) NewPCurve;
892 if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
893 {
894 CurveRep->PCurve(NewPCurve);
895 FirstPar = NewPCurve->FirstParameter();
896 LastPar = NewPCurve->LastParameter();
897 if (CurveRep->IsCurveOnClosedSurface())
898 {
899 Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
900 if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
901 CurveRep->PCurve2(NewPCurve);
902 }
903 }
904 }
905 else if (theCurve->IsPeriodic())
906 {
907 Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
908 delta *= 0.95;
909 FirstPar = anEf - delta;
910 LastPar = anEl + delta;
911 }
912 else if (theCurve->IsClosed())
913 LastPar -= 0.05*(LastPar - FirstPar);
914
915 //check FirstPar and LastPar: the pcurve should be in its surface
916 theCurve = CurveRep->PCurve();
917 Handle(Geom_Surface) theSurf = CurveRep->Surface();
918 Standard_Real Umin, Umax, Vmin, Vmax;
919 theSurf->Bounds(Umin, Umax, Vmin, Vmax);
920 TColGeom2d_SequenceOfCurve BoundLines;
921 if (!Precision::IsInfinite(Vmin))
922 {
923 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
924 gp_Dir2d( 1., 0. ));
925 BoundLines.Append(aLine);
926 }
927 if (!Precision::IsInfinite(Umin))
928 {
929 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
930 gp_Dir2d( 0., 1. ));
931 BoundLines.Append(aLine);
932 }
933 if (!Precision::IsInfinite(Vmax))
934 {
935 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
936 gp_Dir2d( 1., 0. ));
937 BoundLines.Append(aLine);
938 }
939 if (!Precision::IsInfinite(Umax))
940 {
941 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
942 gp_Dir2d( 0., 1. ));
943 BoundLines.Append(aLine);
944 }
945
946 TColStd_SequenceOfReal params;
947 Geom2dInt_GInter IntCC;
948 Geom2dAdaptor_Curve GAcurve(theCurve);
949 for (i = 1; i <= BoundLines.Length(); i++)
950 {
951 Geom2dAdaptor_Curve GAline( BoundLines(i) );
952 IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
953 if (IntCC.IsDone())
954 {
955 for (j = 1; j <= IntCC.NbPoints(); j++)
956 {
957 const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
958 gp_Pnt2d aPoint = ip.Value();
959 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
960 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
961 params.Append( ip.ParamOnFirst() );
962 }
963 for (j = 1; j <= IntCC.NbSegments(); j++)
964 {
965 const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
966 if (is.HasFirstPoint())
967 {
968 const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
969 gp_Pnt2d aPoint = ip.Value();
970 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
971 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
972 params.Append( ip.ParamOnFirst() );
973 }
974 if (is.HasLastPoint())
975 {
976 const IntRes2d_IntersectionPoint& ip = is.LastPoint();
977 gp_Pnt2d aPoint = ip.Value();
978 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
979 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
980 params.Append( ip.ParamOnFirst() );
981 }
982 }
983 }
984 }
985 if (!params.IsEmpty())
986 {
987 if (params.Length() == 1)
988 {
989 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
990 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
991 PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
992 {
993 if (LastPar > params(1))
994 LastPar = params(1);
995 }
996 else if (FirstPar < params(1))
997 FirstPar = params(1);
998 }
999 else
1000 {
1001 Standard_Real fpar = RealLast(), lpar = RealFirst();
1002 for (i = 1; i <= params.Length(); i++)
1003 {
1004 if (params(i) < fpar)
1005 fpar = params(i);
1006 if (params(i) > lpar)
1007 lpar = params(i);
1008 }
1009 if (FirstPar < fpar)
1010 FirstPar = fpar;
1011 if (LastPar > lpar)
1012 LastPar = lpar;
1013 }
1014 }
1015 //// end of check ////
1016 (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
1017 //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
1018 //gp_Pnt2d Plast = theCurve->Value(LastPar);
1019 //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
1020
1021 //update FirstParOnPC and LastParOnPC
1022 if (FirstPar > FirstParOnPC)
1023 {
1024 FirstParOnPC = FirstPar;
1025 MinPC = theCurve;
1026 MinSurf = theSurf;
1027 MinLoc = CurveRep->Location();
1028 }
1029 if (LastPar < LastParOnPC)
1030 {
1031 LastParOnPC = LastPar;
1032 MinPC = theCurve;
1033 MinSurf = theSurf;
1034 MinLoc = CurveRep->Location();
1035 }
1036 }
7fd59977 1037 }
1038
1039 Standard_Real f, l;
1040 Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
1041 if (NbPCurves)
1042 {
1043 MinLoc = E.Location() * MinLoc;
1044 if (!C3d.IsNull())
9b7f3f83 1045 {
1046 if (MinPC->IsClosed())
1047 {
1048 f = FirstParOnPC;
1049 l = LastParOnPC;
1050 }
1051 else if (C3d->IsPeriodic())
1052 {
1053 Standard_Real delta = (C3d->Period() - (l - f))*0.5;
1054 delta *= 0.95;
1055 f -= delta;
1056 l += delta;
1057 }
1058 else if (C3d->IsClosed())
1059 l -= 0.05*(l - f);
1060 else
1061 {
1062 f = FirstParOnPC;
1063 l = LastParOnPC;
1064 GeomAPI_ProjectPointOnCurve Projector;
1065 if (!Precision::IsInfinite(FirstParOnPC))
1066 {
1067 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
1068 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
1069 P1.Transform(MinLoc.Transformation());
1070 Projector.Init( P1, C3d );
1071 if (Projector.NbPoints() > 0)
1072 f = Projector.LowerDistanceParameter();
0797d9d3 1073#ifdef OCCT_DEBUG
9b7f3f83 1074 else
1075 cout<<"ProjectPointOnCurve not done"<<endl;
7fd59977 1076#endif
9b7f3f83 1077 }
1078 if (!Precision::IsInfinite(LastParOnPC))
1079 {
1080 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
1081 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
1082 P2.Transform(MinLoc.Transformation());
1083 Projector.Init( P2, C3d );
1084 if (Projector.NbPoints() > 0)
1085 l = Projector.LowerDistanceParameter();
0797d9d3 1086#ifdef OCCT_DEBUG
9b7f3f83 1087 else
1088 cout<<"ProjectPointOnCurve not done"<<endl;
7fd59977 1089#endif
9b7f3f83 1090 }
1091 }
1092 BB.Range( NE, f, l );
1093 if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
1094 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1095 }
975ec82a 1096 else if (!BRep_Tool::Degenerated(E)) //no 3d curve
9b7f3f83 1097 {
1098 MinSurf = Handle(Geom_Surface)::DownCast
1099 (MinSurf->Transformed(MinLoc.Transformation()));
1100 Standard_Real max_deviation = 0.;
1101 if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
1102 {
1103 if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1104 {
1105 Standard_Boolean IsLine = Standard_False;
1106 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1107 IsLine = Standard_True;
1108 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
1109 MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
1110 {
1111 Handle(Geom2d_Line) theLine = Handle(Geom2d_Line)::DownCast (MinPC);
1112 gp_Dir2d LineDir = theLine->Direction();
1113 if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
1114 IsLine = Standard_True;
1115 }
1116 if (IsLine)
1117 {
1118 gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
1119 gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
1120 gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
1121 gp_Vec aVec(P1, P2);
1122 C3d = new Geom_Line( P1, aVec );
1123 }
1124 }
1125 }
1126 else
1127 {
1128 Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
1129 GeomAdaptor_Surface GAsurf( MinSurf );
1130 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
1131 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
1132 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
1133 Standard_Real /*max_deviation,*/ average_deviation;
1134 GeomAbs_Shape Continuity = GeomAbs_C1;
1135 Standard_Integer MaxDegree = 14;
1136 Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
1137 GeomLib::BuildCurve3d(Precision::Confusion(),
1138 ConS, FirstParOnPC, LastParOnPC,
1139 C3d, max_deviation, average_deviation,
1140 Continuity, MaxDegree, MaxSegment);
1141 }
1142 BB.UpdateEdge( NE, C3d, max_deviation );
1143 //BB.Range( NE, FirstParOnPC, LastParOnPC );
1144 Standard_Boolean ProjectionSuccess = Standard_True;
1145 if (NbPCurves > 1)
1146 //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1147 for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
1148 itr.More();
1149 itr.Next())
1150 {
1151 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
1152 Standard_Real FirstPar, LastPar;
1153 if (CurveRep->IsCurveOnSurface())
1154 {
1155 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
1156 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1157 TopLoc_Location theLoc = CurveRep->Location();
1158 if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
1159 continue;
1160 FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
1161 LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
1162 if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
1163 Abs(LastPar - LastParOnPC) > Precision::PConfusion())
1164 {
1165 theLoc = E.Location() * theLoc;
1166 theSurf = Handle(Geom_Surface)::DownCast
1167 (theSurf->Transformed(theLoc.Transformation()));
1168
1169 if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
1170 theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
1171 {
1172 gp_Dir2d theDir = Handle(Geom2d_Line)::DownCast (theCurve)->Direction();
1173 if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
1174 theDir.IsParallel(gp::DY2d(), Precision::Angular()))
1175 {
1176 Standard_Real U1, U2, V1, V2;
1177 theSurf->Bounds(U1, U2, V1, V2);
1178 gp_Pnt2d Origin = Handle(Geom2d_Line)::DownCast (theCurve)->Location();
1179 if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
1180 Abs(Origin.X()-U2) <= Precision::Confusion() ||
1181 Abs(Origin.Y()-V1) <= Precision::Confusion() ||
1182 Abs(Origin.Y()-V2) <= Precision::Confusion())
1183 {
1184 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1185 break;
1186 }
1187 }
1188 }
1189
1190 Handle(Geom2d_Curve) ProjPCurve =
1191 GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
1192 if (ProjPCurve.IsNull())
1193 ProjectionSuccess = Standard_False;
1194 else
1195 CurveRep->PCurve( ProjPCurve );
1196 }
1197 }
1198 }
1199 if (ProjectionSuccess)
1200 BB.Range( NE, FirstParOnPC, LastParOnPC );
1201 else
1202 {
1203 BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
1204 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1205 }
1206 }
7fd59977 1207 }
1208 else //no pcurves
1209 {
1210 Standard_Real FirstPar = C3d->FirstParameter();
1211 Standard_Real LastPar = C3d->LastParameter();
1212
1213 if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
9b7f3f83 1214 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
1215 {
1216 Handle(Geom_TrimmedCurve) aTrCurve =
1217 new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
1218
1219 // The curve is not prolonged on begin or end.
1220 // Trying to prolong it adding a segment to its bound.
1221 gp_Pnt aPBnd;
1222 gp_Vec aVBnd;
1223 gp_Pnt aPBeg;
1224 gp_Dir aDBnd;
1225 Handle(Geom_Line) aLin;
1226 Handle(Geom_TrimmedCurve) aSegment;
1227 GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
1228 Standard_Real aTol = Precision::Confusion();
1229 Standard_Real aDelta = Max(a2Offset, 1.);
1230
1231 if (FirstPar > anEf - a2Offset) {
1232 C3d->D1(FirstPar, aPBnd, aVBnd);
1233 aDBnd.SetXYZ(aVBnd.XYZ());
1234 aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
1235 aLin = new Geom_Line(aPBeg, aDBnd);
1236 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1237
1238 if (!aCompCurve.Add(aSegment, aTol))
1239 return;
1240 }
1241
1242 if (LastPar < anEl + a2Offset) {
1243 C3d->D1(LastPar, aPBeg, aVBnd);
1244 aDBnd.SetXYZ(aVBnd.XYZ());
1245 aLin = new Geom_Line(aPBeg, aDBnd);
1246 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1247
1248 if (!aCompCurve.Add(aSegment, aTol))
1249 return;
1250 }
1251
1252 C3d = aCompCurve.BSplineCurve();
1253 FirstPar = C3d->FirstParameter();
1254 LastPar = C3d->LastParameter();
1255 BB.UpdateEdge(NE, C3d, Precision::Confusion());
1256 }
7fd59977 1257 else if (C3d->IsPeriodic())
9b7f3f83 1258 {
1259 Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
1260 delta *= 0.95;
1261 FirstPar = anEf - delta;
1262 LastPar = anEl + delta;
1263 }
7fd59977 1264 else if (C3d->IsClosed())
9b7f3f83 1265 LastPar -= 0.05*(LastPar - FirstPar);
7fd59977 1266
1267 BB.Range( NE, FirstPar, LastPar );
1268 }
1269}
1270// Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
1271
1272
1273//=======================================================================
1274//function : UpdateVertex
1275//purpose :
1276//=======================================================================
1277
1278static Standard_Boolean UpdateVertex(TopoDS_Vertex V,
9b7f3f83 1279 TopoDS_Edge& OE,
1280 TopoDS_Edge& NE,
1281 Standard_Real TolConf)
7fd59977 1282{
1283 BRepAdaptor_Curve OC(OE);
1284 BRepAdaptor_Curve NC(NE);
1285 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
1286 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
7fd59977 1287 Standard_Real U = 0.;
7fd59977 1288 Standard_Real ParTol = Precision::PConfusion();
1289 gp_Pnt P = BRep_Tool::Pnt(V);
1290 Standard_Boolean OK = Standard_False;
1291
1292 if (P.Distance(OC.Value(Of)) < TolConf) {
1293 if (Of >= Nf + ParTol && Of <= Nl + ParTol && P.Distance(NC.Value(Of)) < TolConf) {
1294 OK = Standard_True;
1295 U = Of;
1296 }
1297 }
1298 if (P.Distance(OC.Value(Ol)) < TolConf) {
1299 if (Ol >= Nf + ParTol && Ol <= Nl + ParTol && P.Distance(NC.Value(Ol)) < TolConf) {
1300 OK = Standard_True;
1301 U = Ol;
1302 }
1303 }
1304 if (OK) {
1305 BRep_Builder B;
1306 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
1307 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
1308// TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
1309 aLocalShape = V.Oriented(TopAbs_INTERNAL);
1310 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
9b7f3f83 1311 U,NE,BRep_Tool::Tolerance(NE));
7fd59977 1312// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
9b7f3f83 1313// U,NE,BRep_Tool::Tolerance(NE));
7fd59977 1314 }
1315 return OK;
1316}
1317
1318//=======================================================================
1319//function : Compute
1320//purpose :
1321//=======================================================================
1322
975ec82a 1323void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
9b7f3f83 1324 const TopoDS_Face& F,
1325 const TopTools_IndexedMapOfShape& NewEdges,
b0fbc579 1326 const Standard_Real Tol,
1327 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
7fd59977 1328{
1896126e 1329#ifdef DRAW
7fd59977 1330 NbF2d++;
1331 NbE2d = 0;
1332#endif
1333
1334 //Do not intersect the edges of face
1335 TopTools_MapOfShape EdgesOfFace;
1336 TopExp_Explorer Explo( F, TopAbs_EDGE );
1337 for (; Explo.More(); Explo.Next())
1338 EdgesOfFace.Add( Explo.Current() );
1339
1340 //-----------------------------------------------------------
0d969553 1341 // calculate intersections2d on faces touched by
7fd59977 1342 // intersection3d
1343 //---------------------------------------------------------
1344 TopTools_ListIteratorOfListOfShape it1LE ;
1345 TopTools_ListIteratorOfListOfShape it2LE ;
1346
1347 //-----------------------------------------------
0d969553 1348 // Intersection of edges 2*2.
7fd59977 1349 //-----------------------------------------------
1350 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
1351 TopoDS_Vertex V1,V2;
1352 Standard_Integer j, i = 1;
9b7f3f83 1353 BRepAdaptor_Surface BAsurf(F);
1354 //
7fd59977 1355 for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
9b7f3f83 1356 const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
7fd59977 1357 j = 1;
1358 it2LE.Initialize(LE);
1359
1360 while (j < i && it2LE.More()) {
1361 const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
1362 //--------------------------------------------------------------
0d969553
Y
1363 // Intersections of New edges obtained by intersection
1364 // between them and with edges of restrictions
7fd59977 1365 //------------------------------------------------------
1366 if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
9b7f3f83 1367 (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
1368 TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
b0fbc579 1369 EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
9b7f3f83 1370// EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
7fd59977 1371 }
1372 it2LE.Next();
1373 j++;
1374 }
1375 i++;
1376 }
1377}
1378
1379//=======================================================================
1380//function : ConnexIntByInt
1381//purpose :
1382//=======================================================================
1383
1384// Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
1385// Add another parameter: offset value.
1386void BRepOffset_Inter2d::ConnexIntByInt
1387(const TopoDS_Face& FI,
1388 BRepOffset_Offset& OFI,
1389 TopTools_DataMapOfShapeShape& MES,
1390 const TopTools_DataMapOfShapeShape& Build,
9b7f3f83 1391 const Handle(BRepAlgo_AsDes)& AsDes,
1392 const Handle(BRepAlgo_AsDes)& AsDes2d,
7fd59977 1393 const Standard_Real Offset,
b0fbc579 1394 const Standard_Real Tol,
1395 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
7fd59977 1396// Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
1397{
1398
1399 TopTools_DataMapOfShapeListOfShape MVE;
1400 BRepOffset_Tool::MapVertexEdges(FI,MVE);
1401
1402 //---------------------
0d969553 1403 // Extension of edges.
7fd59977 1404 //---------------------
1405 TopoDS_Edge NE;
1406 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
1407 for ( ; it.More(); it.Next()) {
1408 const TopTools_ListOfShape& L = it.Value();
1409 Standard_Boolean YaBuild = 0;
1410 TopTools_ListIteratorOfListOfShape itL(L);
1411 for (; itL.More(); itL.Next()) {
1412 YaBuild = Build.IsBound(itL.Value());
1413 if (YaBuild) break;
1414 }
1415 if (YaBuild) {
1416 for (itL.Initialize(L); itL.More(); itL.Next()) {
9b7f3f83 1417 const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
1418 TopoDS_Shape aLocalShape = OFI.Generated(EI);
1419 const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
1420// const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
1421 if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
7fd59977 1422// Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin
9b7f3f83 1423// ExtentEdge(OE,NE);
1424 ExtentEdge(OE,NE, Offset);
7fd59977 1425// Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End
9b7f3f83 1426 MES.Bind (OE,NE);
1427 }
7fd59977 1428 }
1429 }
1430 }
1431
1432 TopoDS_Face FIO = TopoDS::Face(OFI.Face());
1433 if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
9b7f3f83 1434 //
1435 TopTools_MapOfShape aME;
1436 const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO);
1437 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1438 for (; aItLE.More(); aItLE.Next()) {
1439 const TopoDS_Shape& aE = aItLE.Value();
1440 aME.Add(aE);
1441 }
1442 //
1443 BRepAdaptor_Surface BAsurf(FIO);
1444
7fd59977 1445 TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1446 for (; exp.More(); exp.Next()) {
1447 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
1448 BRepTools_WireExplorer wexp;
1449 Standard_Boolean end = Standard_False ;
1450 TopoDS_Edge FirstE,CurE,NextE;
1451
1452 TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1453 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1454 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
d1d68ce7 1455 if (!wexp.More())
1456 continue; // Protection from case when explorer does not contain edges.
7fd59977 1457// wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
9b7f3f83 1458// TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
7fd59977 1459 CurE = FirstE = wexp.Current();
1460 while (!end) {
1461 wexp.Next();
1462 if (wexp.More()) {
9b7f3f83 1463 NextE = wexp.Current();
7fd59977 1464 }
1465 else {
9b7f3f83 1466 NextE = FirstE; end = Standard_True;
7fd59977 1467 }
1468 if (CurE.IsSame(NextE)) continue;
1469
1470 //IFV------------
1471 TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
1472 gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1473 //IFV------------
1474
1475 TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1476 TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1477 aLocalShape = OFI.Generated(NextE);
1478 TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1479// TopoDS_Edge CEO = TopoDS::Edge(OFI.Generated(CurE));
1480// TopoDS_Edge NEO = TopoDS::Edge(OFI.Generated(NextE));
1481 //------------------------------------------
0d969553 1482 // Inter processing of images of CurE NextE.
7fd59977 1483 //------------------------------------------
1484 TopTools_ListOfShape LV1,LV2;
1485 Standard_Boolean DoInter = 1;
1486 TopoDS_Shape NE1,NE2;
1487
1488 if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
9b7f3f83 1489 NE1 = Build(CurE );
1490 NE2 = Build(NextE);
7fd59977 1491 }
1492 else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
9b7f3f83 1493 NE1 = Build(CurE);
1494 NE2 = MES (NEO);
7fd59977 1495 }
1496 else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
9b7f3f83 1497 NE1 = Build(NextE);
1498 NE2 = MES(CEO);
7fd59977 1499 }
1500 else {
9b7f3f83 1501 DoInter = 0;
7fd59977 1502 }
1503 if (DoInter) {
9b7f3f83 1504 //------------------------------------
1505 // NE1,NE2 can be a compound of Edges.
1506 //------------------------------------
1507 TopExp_Explorer Exp1,Exp2;
1508 for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1509 for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
1510 RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
b0fbc579 1511 AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
9b7f3f83 1512 }
1513 }
1514 //
1515 if (Build.IsBound(Vref)) {
1516 TopoDS_Shape NE3 = Build(Vref);
1517 //
1518 for (Exp2.Init(NE3,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
1519 const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current();
1520 if (!aME.Contains(aE3)) {
1521 continue;
1522 }
1523 //
1524 for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1525 RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
b0fbc579 1526 AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
9b7f3f83 1527 }
1528 //
1529 for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1530 RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3,
b0fbc579 1531 AsDes2d,Tol,Standard_True/*Standard_False*/, Pref, theDMVV);
9b7f3f83 1532 }
1533 }
1534 }
7fd59977 1535 }
1536 else {
9b7f3f83 1537 if (MES.IsBound(CEO)) {
1538 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1539 UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
1540 AsDes2d->Add (MES(CEO),V);
1541 }
1542 else if (MES.IsBound(NEO)) {
1543 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1544 UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
1545 AsDes2d->Add (MES(NEO),V);
1546 }
7fd59977 1547 }
1548 CurE = NextE;
1549 }
1550 }
1551}
b0fbc579 1552
1553//=======================================================================
1554//function : MakeChain
1555//purpose :
1556//=======================================================================
1557static void MakeChain(const TopoDS_Shape& theV,
1558 const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
1559 TopTools_MapOfShape& theMDone,
1560 BOPCol_ListOfShape& theChain)
1561{
1562 if (theMDone.Add(theV)) {
1563 theChain.Append(theV);
1564 const TopTools_ListOfShape* pLV = theDMVV.Seek(theV);
1565 if (pLV) {
1566 TopTools_ListIteratorOfListOfShape aIt(*pLV);
1567 for (; aIt.More(); aIt.Next()) {
1568 MakeChain(aIt.Value(), theDMVV, theMDone, theChain);
1569 }
1570 }
1571 }
1572}
1573
1574//=======================================================================
1575//function : FuseVertices
1576//purpose :
1577//=======================================================================
1578void BRepOffset_Inter2d::FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
1579 const Handle(BRepAlgo_AsDes)& theAsDes)
1580{
1581 BRep_Builder aBB;
1582 TopTools_MapOfShape aMVDone;
1583 Standard_Integer i, aNb = theDMVV.Extent();
1584 for (i = 1; i <= aNb; ++i) {
1585 const TopoDS_Vertex& aV = TopoDS::Vertex(theDMVV.FindKey(i));
1586 //
1587 // find chain of vertices
1588 BOPCol_ListOfShape aLVChain;
1589 MakeChain(aV, theDMVV, aMVDone, aLVChain);
1590 //
1591 if (aLVChain.Extent() < 2) {
1592 continue;
1593 }
1594 //
1595 // make new vertex
1596 TopoDS_Vertex aVNew;
1597 BOPTools_AlgoTools::MakeVertex(aLVChain, aVNew);
1598 //
1599 TopoDS_Vertex aVNewInt = TopoDS::Vertex(aVNew.Oriented(TopAbs_INTERNAL));
1600 //
1601 BOPCol_ListIteratorOfListOfShape aIt(aLVChain);
1602 for (; aIt.More(); aIt.Next()) {
1603 const TopoDS_Shape& aVOld = aIt.Value();
1604 // update the parameters on edges
1605 TopoDS_Vertex aVOldInt = TopoDS::Vertex(aVOld.Oriented(TopAbs_INTERNAL));
1606 const TopTools_ListOfShape& aLE = theAsDes->Ascendant(aVOld);
1607 //
1608 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1609 for (; aItLE.More(); aItLE.Next()) {
1610 const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
1611 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1612 Standard_Real aT = BRep_Tool::Parameter(aVOldInt, aE);
1613 aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
1614 }
1615 // and replace the vertex
1616 theAsDes->Replace(aVOld, aVNew);
1617 }
1618 }
1619}