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