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