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