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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455
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>
24 #include <BOPTools_AlgoTools.hxx>
25 #include <BRep_Builder.hxx>
26 #include <BRep_CurveRepresentation.hxx>
27 #include <BRep_GCurve.hxx>
28 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
29 #include <BRep_TEdge.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRepAdaptor_Curve.hxx>
32 #include <BRepAdaptor_Curve2d.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34 #include <BRepAlgo_AsDes.hxx>
35 #include <BRepLib.hxx>
36 #include <BRepLib_MakeVertex.hxx>
37 #include <BRepOffset_Analyse.hxx>
38 #include <BRepOffset_Inter2d.hxx>
39 #include <BRepOffset_Offset.hxx>
40 #include <BRepOffset_Tool.hxx>
41 #include <BRepTools.hxx>
42 #include <BRepTools_WireExplorer.hxx>
43 #include <Geom2d_BezierCurve.hxx>
44 #include <Geom2d_BSplineCurve.hxx>
45 #include <Geom2d_Line.hxx>
46 #include <Geom2d_TrimmedCurve.hxx>
47 #include <Geom2dAdaptor_HCurve.hxx>
48 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
49 #include <Geom2dInt_GInter.hxx>
50 #include <Geom_BSplineCurve.hxx>
51 #include <Geom_BSplineSurface.hxx>
52 #include <Geom_ConicalSurface.hxx>
53 #include <Geom_CylindricalSurface.hxx>
54 #include <Geom_Line.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_TrimmedCurve.hxx>
57 #include <GeomAdaptor_HSurface.hxx>
58 #include <GeomAdaptor_Surface.hxx>
59 #include <GeomAPI_ProjectPointOnCurve.hxx>
60 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
61 #include <GeomLib.hxx>
62 #include <GeomProjLib.hxx>
64 #include <IntRes2d_IntersectionPoint.hxx>
65 #include <IntRes2d_IntersectionSegment.hxx>
66 #include <Precision.hxx>
67 #include <TColGeom2d_SequenceOfCurve.hxx>
68 #include <TColgp_Array1OfPnt2d.hxx>
69 #include <TColgp_SequenceOfPnt.hxx>
71 #include <TopExp_Explorer.hxx>
73 #include <TopoDS_Edge.hxx>
74 #include <TopoDS_Face.hxx>
75 #include <TopoDS_Iterator.hxx>
76 #include <TopoDS_Vertex.hxx>
77 #include <TopoDS_Wire.hxx>
78 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
79 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <TopTools_ListOfShape.hxx>
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>
90 Standard_Boolean Inter2dAffichInt2d;
91 static Standard_Integer NbF2d = 0;
92 static Standard_Integer NbE2d = 0;
93 static Standard_Integer NbNewVertices = 0;
96 //=======================================================================
97 //function : CommonVertex
99 //=======================================================================
101 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
104 TopoDS_Vertex V1[2],V2[2],V;
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.
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];
116 static Standard_Boolean IsOrientationChanged(TopTools_IndexedMapOfShape& theMap,
117 const TopoDS_Edge& theEdge)
119 Standard_Boolean IsOrChanged = Standard_False;
121 if (!theMap.Contains(theEdge))
125 Standard_Integer anInd = theMap.FindIndex(theEdge);
126 const TopoDS_Shape& anEdge = theMap(anInd);
127 if (theEdge.Orientation() != anEdge.Orientation())
129 theMap.Substitute( anInd, theEdge );
130 IsOrChanged = Standard_True;
138 //=======================================================================
140 //purpose : Store the vertices <theLV> into AsDes for the edge <theEdge>.
141 // The vertices are added despite of the coincidence with
142 // already added vertices. When all vertices for all edges
143 // are added the coinciding chains of vertices should be fused
144 // using FuseVertices() method.
145 //=======================================================================
146 static void Store(const TopoDS_Edge& theEdge,
147 const TopTools_ListOfShape& theLV,
148 const Standard_Real theTol,
149 const Standard_Boolean IsToUpdate,
150 Handle(BRepAlgo_AsDes) theAsDes2d,
151 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
153 const TopTools_ListOfShape& aLVEx = theAsDes2d->Descendant(theEdge);
154 if (!IsToUpdate && aLVEx.IsEmpty()) {
155 if (theLV.Extent()) theAsDes2d->Add(theEdge, theLV);
159 GeomAPI_ProjectPointOnCurve aProjPC;
161 Standard_Real aT1, aT2;
162 const Handle(Geom_Curve)& aC = BRep_Tool::Curve(theEdge, aT1, aT2);
163 aProjPC.Init(aC, aT1, aT2);
166 TopTools_MapOfShape aMV;
167 TopTools_ListIteratorOfListOfShape aIt(theLV);
168 for (; aIt.More(); aIt.Next()) {
169 const TopoDS_Vertex& aV = TopoDS::Vertex(aIt.Value());
174 const gp_Pnt& aP = BRep_Tool::Pnt(aV);
176 TopTools_ListOfShape aLVC;
177 TopTools_ListIteratorOfListOfShape aItEx(aLVEx);
178 for (; aItEx.More(); aItEx.Next()) {
179 const TopoDS_Vertex& aVEx = TopoDS::Vertex(aItEx.Value());
180 if (aV.IsSame(aVEx)) {
183 const gp_Pnt& aPEx = BRep_Tool::Pnt(aVEx);
184 if (aP.IsEqual(aPEx, theTol)) {
194 // get parameter of the vertex on the edge
196 if (!aProjPC.NbPoints()) {
200 if (aProjPC.LowerDistance() > theTol) {
204 Standard_Real aT = aProjPC.LowerDistanceParameter();
205 TopoDS_Shape aLocalShape = aV.Oriented(TopAbs_INTERNAL);
206 BRep_Builder().UpdateVertex(TopoDS::Vertex(aLocalShape), aT, theEdge, theTol);
209 BRep_Builder().UpdateVertex(aV, theTol);
213 TopTools_ListIteratorOfListOfShape aItLV(aLVC);
214 for (; aItLV.More(); aItLV.Next()) {
215 const TopoDS_Shape& aVC = aItLV.Value();
216 TopTools_ListOfShape* pLV = theDMVV.ChangeSeek(aVC);
218 pLV = &theDMVV(theDMVV.Add(aVC, TopTools_ListOfShape()));
223 TopTools_ListOfShape* pLV = theDMVV.ChangeSeek(aV);
225 pLV = &theDMVV(theDMVV.Add(aV, TopTools_ListOfShape()));
229 theAsDes2d->Add(theEdge, aV);
233 //=======================================================================
235 //purpose : Store the intersection vertices between two edges into AsDes
236 //=======================================================================
237 static void Store (const TopoDS_Edge& theE1,
238 const TopoDS_Edge& theE2,
239 const TopTools_ListOfShape& theLV1,
240 const TopTools_ListOfShape& theLV2,
241 const Standard_Real theTol,
242 Handle(BRepAlgo_AsDes) theAsDes2d,
243 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
245 for (Standard_Integer i = 0; i < 2; ++i) {
246 const TopoDS_Edge& aE = !i ? theE1 : theE2;
247 const TopTools_ListOfShape& aLV = !i ? theLV1 : theLV2;
248 Store(aE, aLV, theTol, Standard_False, theAsDes2d, theDMVV);
252 //=======================================================================
253 //function : EdgeInter
255 //=======================================================================
257 static void EdgeInter(const TopoDS_Face& F,
258 const BRepAdaptor_Surface& BAsurf,
259 const TopoDS_Edge& E1,
260 const TopoDS_Edge& E2,
261 const Handle(BRepAlgo_AsDes)& AsDes,
263 Standard_Boolean WithOri,
264 TopTools_IndexedDataMapOfShapeListOfShape& aDMVV)
267 if (Inter2dAffichInt2d) {
269 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
271 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
279 Standard_Real f[3],l[3];
280 Standard_Real TolDub = 1.e-7;
283 BRep_Tool::Range(E1, f[1], l[1]);
284 BRep_Tool::Range(E2, f[2], l[2]);
286 BRepAdaptor_Curve CE1(E1,F);
287 BRepAdaptor_Curve CE2(E2,F);
289 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
290 TopTools_ListOfShape LV1;
291 TopTools_ListOfShape LV2;
295 if (!TopExp::CommonVertex( E1, E2, CV ))
297 BRepLib::BuildCurve3d(E1);
298 BRepLib::BuildCurve3d(E2);
300 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
301 TolSum = Max( TolSum, 1.e-5 );
303 TColgp_SequenceOfPnt ResPoints;
304 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
306 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
310 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
311 TopoDS_Iterator iter( EI[ideg] );
314 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
315 DegPoint = BRep_Tool::Pnt(vdeg);
319 BRepAdaptor_Curve CEdeg( EI[ideg], F );
320 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
324 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
325 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
326 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
327 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
328 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
329 for (i = 1; i <= Inter2d.NbPoints(); i++)
336 gp_Pnt2d P2d = Inter2d.Point(i).Value();
337 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
339 ResPoints.Append( P3d );
340 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
341 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
344 for (i = 1; i <= ResPoints.Length(); i++)
346 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
347 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
348 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
351 std::cout << "Inter2d : Solution rejected due to infinite parameter"<<std::endl;
356 gp_Pnt P = ResPoints(i); //ponc1.Value();
357 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
358 aNewVertex.Orientation(TopAbs_INTERNAL);
359 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
360 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
361 gp_Pnt P1 = CE1.Value(aT1);
362 gp_Pnt P2 = CE2.Value(aT2);
363 Standard_Real dist1, dist2, dist3;
364 dist1 = P1.Distance(P);
365 dist2 = P2.Distance(P);
366 dist3 = P1.Distance(P2);
367 dist1 = Max( dist1, dist2 );
368 dist1 = Max( dist1, dist3 );
369 B.UpdateVertex( aNewVertex, dist1 );
372 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
374 std::cout << "out of limit"<<std::endl;
375 std::cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<std::endl;
377 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
379 std::cout << "out of limit"<<std::endl;
380 std::cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<std::endl;
382 Standard_Real MilTol2 = 1000*Tol*Tol;
383 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
385 std::cout << "Inter2d : Solution rejected "<<std::endl;
386 std::cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<std::endl;
387 std::cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<std::endl;
388 std::cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<std::endl;
389 std::cout<<"MaxDist = "<<dist1<<std::endl;
392 //define the orientation of a new vertex
393 TopAbs_Orientation OO1 = TopAbs_REVERSED;
394 TopAbs_Orientation OO2 = TopAbs_REVERSED;
397 BRepAdaptor_Curve2d PCE1( E1, F );
398 BRepAdaptor_Curve2d PCE2( E2, F );
400 gp_Vec2d V1, V2, V1or, V2or;
401 PCE1.D1( aT1, P2d1, V1 );
402 PCE2.D1( aT2, P2d2, V2 );
403 V1or = V1; V2or = V2;
404 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
405 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
406 Standard_Real CrossProd = V2or ^ V1;
408 if (Abs(CrossProd) <= gp::Resolution())
409 std::cout<<std::endl<<"CrossProd = "<<CrossProd<<std::endl;
412 OO1 = TopAbs_FORWARD;
413 CrossProd = V1or ^ V2;
415 OO2 = TopAbs_FORWARD;
417 LV1.Append( aNewVertex.Oriented(OO1) );
418 LV2.Append( aNewVertex.Oriented(OO2) );
422 //----------------------------------
424 //---------------------------------
426 Standard_Real TolConf = Tol;
427 TopoDS_Vertex V1[2],V2[2];
428 TopExp::Vertices(E1,V1[0],V1[1]);
429 TopExp::Vertices(E2,V2[0],V2[1]);
432 for (j = 0; j < 2; j++) {
433 if (V1[j].IsNull()) continue;
434 for (Standard_Integer k = 0; k < 2; k++) {
435 if (V2[k].IsNull()) continue;
436 if (V1[j].IsSame(V2[k])) {
437 if (AsDes->HasAscendant(V1[j])) {
442 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
443 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
444 Standard_Real Dist = P1.Distance(P2);
445 if (Dist < TolConf) {
447 Max(BRep_Tool::Tolerance(V1[j]), BRep_Tool::Tolerance(V2[k]));
448 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
449 U1 = (j == 0) ? f[1] : l[1];
450 U2 = (k == 0) ? f[2] : l[2];
452 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
453 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
454 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
456 LV1.Prepend(V.Oriented(V1[j].Orientation()));
457 LV2.Prepend(V.Oriented(V2[k].Orientation()));
462 Standard_Boolean AffichPurge = Standard_False;
464 if ( !LV1.IsEmpty()) {
465 //----------------------------------
466 // Remove all vertices.
467 // There can be doubles
468 //----------------------------------
469 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
471 Standard_Boolean Purge = Standard_True;
475 Purge = Standard_False;
476 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
477 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
479 it2LV1.Initialize(LV1);
481 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
482 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
483 // Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
484 // if (P1.IsEqual(P2,10*Tol)) {
487 aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
488 BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
489 if (P1.IsEqual(P2,aTol)) {
490 // Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
493 if (AffichPurge) std::cout <<"Doubles removed in EdgeInter."<<std::endl;
494 Purge = Standard_True;
504 //---------------------------------
505 // Vertex storage in DS.
506 //---------------------------------
507 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
508 TolStore = Max(TolStore, 10.*Tol);
509 Store (E1,E2,LV1,LV2,TolStore,AsDes, aDMVV);
512 //=======================================================================
513 //function : EdgeInter
515 //=======================================================================
517 static void RefEdgeInter(const TopoDS_Face& F,
518 const BRepAdaptor_Surface& BAsurf,
519 const TopoDS_Edge& E1,
520 const TopoDS_Edge& E2,
521 const Handle(BRepAlgo_AsDes)& AsDes,
523 Standard_Boolean WithOri,
525 TopTools_IndexedDataMapOfShapeListOfShape& aDMVV,
526 Standard_Boolean& theCoincide)
529 if (Inter2dAffichInt2d) {
531 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
533 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
538 theCoincide = Standard_False;
543 Standard_Real f[3],l[3];
544 Standard_Real TolDub = 1.e-7;
547 //BRep_Tool::Range(E1, f[1], l[1]);
548 //BRep_Tool::Range(E2, f[2], l[2]);
550 BRepAdaptor_Curve CE1(E1,F);
551 BRepAdaptor_Curve CE2(E2,F);
553 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
554 TopTools_ListOfShape LV1;
555 TopTools_ListOfShape LV2;
558 BRepLib::BuildCurve3d(E1);
559 BRepLib::BuildCurve3d(E2);
561 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
562 TolSum = Max( TolSum, 1.e-5 );
564 TColgp_SequenceOfPnt ResPoints;
565 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
567 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
571 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
572 TopoDS_Iterator iter( EI[ideg] );
575 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
576 DegPoint = BRep_Tool::Pnt(vdeg);
580 BRepAdaptor_Curve CEdeg( EI[ideg], F );
581 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
585 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
586 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
587 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
588 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
589 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
591 if (!Inter2d.IsDone() || !Inter2d.NbPoints()) {
592 theCoincide = (Inter2d.NbSegments() &&
593 (GAC1.GetType() == GeomAbs_Line) &&
594 (GAC2.GetType() == GeomAbs_Line));
598 for (i = 1; i <= Inter2d.NbPoints(); i++)
605 gp_Pnt2d P2d = Inter2d.Point(i).Value();
606 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
608 ResPoints.Append( P3d );
609 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
610 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
613 for (i = 1; i <= ResPoints.Length(); i++)
615 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
616 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
617 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
620 std::cout << "Inter2d : Solution rejected due to infinite parameter"<<std::endl;
625 gp_Pnt P = ResPoints(i); //ponc1.Value();
626 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
627 aNewVertex.Orientation(TopAbs_INTERNAL);
628 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
629 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
630 gp_Pnt P1 = CE1.Value(aT1);
631 gp_Pnt P2 = CE2.Value(aT2);
632 Standard_Real dist1, dist2, dist3;
633 dist1 = P1.Distance(P);
634 dist2 = P2.Distance(P);
635 dist3 = P1.Distance(P2);
636 dist1 = Max( dist1, dist2 );
637 dist1 = Max( dist1, dist3 );
638 B.UpdateVertex( aNewVertex, dist1 );
641 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
643 std::cout << "out of limit"<<std::endl;
644 std::cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<std::endl;
646 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
648 std::cout << "out of limit"<<std::endl;
649 std::cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<std::endl;
651 Standard_Real MilTol2 = 1000*Tol*Tol;
652 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
654 std::cout << "Inter2d : Solution rejected"<<std::endl;
655 std::cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<std::endl;
656 std::cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<std::endl;
657 std::cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<std::endl;
658 std::cout<<"MaxDist = "<<dist1<<std::endl;
661 //define the orientation of a new vertex
662 TopAbs_Orientation OO1 = TopAbs_REVERSED;
663 TopAbs_Orientation OO2 = TopAbs_REVERSED;
666 BRepAdaptor_Curve2d PCE1( E1, F );
667 BRepAdaptor_Curve2d PCE2( E2, F );
669 gp_Vec2d V1, V2, V1or, V2or;
670 PCE1.D1( aT1, P2d1, V1 );
671 PCE2.D1( aT2, P2d2, V2 );
672 V1or = V1; V2or = V2;
673 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
674 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
675 Standard_Real CrossProd = V2or ^ V1;
677 if (Abs(CrossProd) <= gp::Resolution())
678 std::cout<<std::endl<<"CrossProd = "<<CrossProd<<std::endl;
681 OO1 = TopAbs_FORWARD;
682 CrossProd = V1or ^ V2;
684 OO2 = TopAbs_FORWARD;
686 LV1.Append( aNewVertex.Oriented(OO1) );
687 LV2.Append( aNewVertex.Oriented(OO2) );
690 //----------------------------------
692 //---------------------------------
694 Standard_Real TolConf = Tol;
695 TopoDS_Vertex V1[2],V2[2];
696 TopExp::Vertices(E1,V1[0],V1[1]);
697 TopExp::Vertices(E2,V2[0],V2[1]);
700 for (j = 0; j < 2; j++) {
701 if (V1[j].IsNull()) continue;
702 for (Standard_Integer k = 0; k < 2; k++) {
703 if (V2[k].IsNull()) continue;
704 if (V1[j].IsSame(V2[k])) {
705 if (AsDes->HasAscendant(V1[j])) {
710 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
711 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
712 Standard_Real Dist = P1.Distance(P2);
713 if (Dist < TolConf) {
714 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
715 U1 = (j == 0) ? f[1] : l[1];
716 U2 = (k == 0) ? f[2] : l[2];
717 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
718 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
719 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
720 LV1.Prepend(V.Oriented(V1[j].Orientation()));
721 LV2.Prepend(V.Oriented(V2[k].Orientation()));
726 Standard_Boolean AffichPurge = Standard_False;
728 if ( !LV1.IsEmpty()) {
729 //----------------------------------
730 // Remove all vertices.
731 // there can be doubles
732 //----------------------------------
733 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
735 Standard_Boolean Purge = Standard_True;
739 Purge = Standard_False;
740 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
741 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
743 it2LV1.Initialize(LV1);
745 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
746 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
747 if (P1.IsEqual(P2,10*Tol)) {
750 if (AffichPurge) std::cout <<"Doubles removed in EdgeInter."<<std::endl;
751 Purge = Standard_True;
761 //---------------------------------
762 // Vertex storage in SD.
763 //---------------------------------
764 ////-----------------------------------------------------
765 if(LV1.Extent() > 1) {
766 //std::cout << "IFV - RefEdgeInter: remove vertex" << std::endl;
767 Standard_Real dmin = RealLast();
769 for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
770 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
771 Standard_Real d = P.SquareDistance(Pref);
774 Vmin = TopoDS::Vertex(it1LV1.Value());
777 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
778 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
779 if(!Vmin.IsSame(it1LV1.Value())) {
782 if(!it1LV1.More()) break;
787 ////-----------------------------------------------------
788 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
789 TolStore = Max(TolStore, 10.*Tol);
790 Store (E1,E2,LV1,LV2,TolStore,AsDes, aDMVV);
795 //======================================================================
796 //function : EvaluateMaxSegment
797 //purpose : return MaxSegment to pass in approximation
798 //======================================================================
800 static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurveOnSurface)
802 Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface();
803 Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
805 Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
807 if (aSurf->GetType() == GeomAbs_BSplineSurface) {
808 Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
809 aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
811 if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
812 aNbC2dKnots = aCurv2d->NbKnots();
814 Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ;
819 //=======================================================================
820 //function : ExtendPCurve
822 //=======================================================================
824 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
825 const Standard_Real anEf,
826 const Standard_Real anEl,
827 const Standard_Real a2Offset,
828 Handle(Geom2d_Curve)& NewPCurve)
831 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
832 NewPCurve = Handle(Geom2d_TrimmedCurve)::DownCast (NewPCurve)->BasisCurve();
834 Standard_Real FirstPar = NewPCurve->FirstParameter();
835 Standard_Real LastPar = NewPCurve->LastParameter();
837 if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
838 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
840 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
842 Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast (NewPCurve);
843 if (aBezier->NbPoles() == 2)
845 TColgp_Array1OfPnt2d thePoles(1,2);
846 aBezier->Poles(thePoles);
847 gp_Vec2d aVec(thePoles(1), thePoles(2));
848 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
849 return Standard_True;
852 else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
854 Handle(Geom2d_BSplineCurve) aBSpline = Handle(Geom2d_BSplineCurve)::DownCast (NewPCurve);
855 if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
857 TColgp_Array1OfPnt2d thePoles(1,2);
858 aBSpline->Poles(thePoles);
859 gp_Vec2d aVec(thePoles(1), thePoles(2));
860 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
861 return Standard_True;
866 FirstPar = aPCurve->FirstParameter();
867 LastPar = aPCurve->LastParameter();
868 Handle(Geom2d_TrimmedCurve) aTrCurve =
869 new Geom2d_TrimmedCurve(aPCurve, FirstPar, LastPar);
871 // The curve is not prolonged on begin or end.
872 // Trying to prolong it adding a segment to its bound.
877 Handle(Geom2d_Line) aLin;
878 Handle(Geom2d_TrimmedCurve) aSegment;
879 Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
880 Standard_Real aTol = Precision::Confusion();
881 Standard_Real aDelta = Max(a2Offset, 1.);
883 if (FirstPar > anEf - a2Offset) {
884 aPCurve->D1(FirstPar, aPBnd, aVBnd);
885 aDBnd.SetXY(aVBnd.XY());
886 aPBeg = aPBnd.Translated(gp_Vec2d(-aDelta*aDBnd.XY()));
887 aLin = new Geom2d_Line(aPBeg, aDBnd);
888 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
890 if (!aCompCurve.Add(aSegment, aTol))
891 return Standard_False;
894 if (LastPar < anEl + a2Offset) {
895 aPCurve->D1(LastPar, aPBeg, aVBnd);
896 aDBnd.SetXY(aVBnd.XY());
897 aLin = new Geom2d_Line(aPBeg, aDBnd);
898 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
900 if (!aCompCurve.Add(aSegment, aTol))
901 return Standard_False;
904 NewPCurve = aCompCurve.BSplineCurve();
905 return Standard_True;
908 //=======================================================================
909 //function : ExtentEdge
911 //=======================================================================
913 // Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
914 //static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE)
915 void BRepOffset_Inter2d::ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
917 //BRepLib::BuildCurve3d(E);
919 TopoDS_Shape aLocalShape = E.EmptyCopied();
922 Standard_Real a2Offset = 2.*Abs(theOffset);
924 Standard_Integer i, j;
926 BRep_Tool::Range(E, anEf, anEl);
927 NE = TopoDS::Edge(aLocalShape);
928 // NE = TopoDS::Edge(E.EmptyCopied());
929 // Enough for analytic edges, for general case reconstruct the
930 // geometry of the edge recalculating the intersection of surfaces.
932 //BRepLib::BuildCurve3d(E);
934 Standard_Integer NbPCurves = 0;
935 Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
936 Handle(Geom2d_Curve) MinPC;
937 Handle(Geom_Surface) MinSurf;
938 TopLoc_Location MinLoc;
940 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
941 for (; itr.More(); itr.Next())
943 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
944 Standard_Real FirstPar, LastPar;
945 if (CurveRep->IsCurveOnSurface())
948 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
949 FirstPar = theCurve->FirstParameter();
950 LastPar = theCurve->LastParameter();
952 if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
953 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
955 Handle(Geom2d_Curve) NewPCurve;
956 if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
958 CurveRep->PCurve(NewPCurve);
959 FirstPar = NewPCurve->FirstParameter();
960 LastPar = NewPCurve->LastParameter();
961 if (CurveRep->IsCurveOnClosedSurface())
963 Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
964 if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
965 CurveRep->PCurve2(NewPCurve);
969 else if (theCurve->IsPeriodic())
971 Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
973 FirstPar = anEf - delta;
974 LastPar = anEl + delta;
976 else if (theCurve->IsClosed())
977 LastPar -= 0.05*(LastPar - FirstPar);
979 //check FirstPar and LastPar: the pcurve should be in its surface
980 theCurve = CurveRep->PCurve();
981 Handle(Geom_Surface) theSurf = CurveRep->Surface();
982 Standard_Real Umin, Umax, Vmin, Vmax;
983 theSurf->Bounds(Umin, Umax, Vmin, Vmax);
984 TColGeom2d_SequenceOfCurve BoundLines;
985 if (!Precision::IsInfinite(Vmin))
987 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
989 BoundLines.Append(aLine);
991 if (!Precision::IsInfinite(Umin))
993 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
995 BoundLines.Append(aLine);
997 if (!Precision::IsInfinite(Vmax))
999 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
1000 gp_Dir2d( 1., 0. ));
1001 BoundLines.Append(aLine);
1003 if (!Precision::IsInfinite(Umax))
1005 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
1006 gp_Dir2d( 0., 1. ));
1007 BoundLines.Append(aLine);
1010 TColStd_SequenceOfReal params;
1011 Geom2dInt_GInter IntCC;
1012 Geom2dAdaptor_Curve GAcurve(theCurve);
1013 for (i = 1; i <= BoundLines.Length(); i++)
1015 Geom2dAdaptor_Curve GAline( BoundLines(i) );
1016 IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
1019 for (j = 1; j <= IntCC.NbPoints(); j++)
1021 const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
1022 gp_Pnt2d aPoint = ip.Value();
1023 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1024 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1025 params.Append( ip.ParamOnFirst() );
1027 for (j = 1; j <= IntCC.NbSegments(); j++)
1029 const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
1030 if (is.HasFirstPoint())
1032 const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
1033 gp_Pnt2d aPoint = ip.Value();
1034 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1035 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1036 params.Append( ip.ParamOnFirst() );
1038 if (is.HasLastPoint())
1040 const IntRes2d_IntersectionPoint& ip = is.LastPoint();
1041 gp_Pnt2d aPoint = ip.Value();
1042 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1043 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1044 params.Append( ip.ParamOnFirst() );
1049 if (!params.IsEmpty())
1051 if (params.Length() == 1)
1053 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
1054 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
1055 PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
1057 if (LastPar > params(1))
1058 LastPar = params(1);
1060 else if (FirstPar < params(1))
1061 FirstPar = params(1);
1065 Standard_Real fpar = RealLast(), lpar = RealFirst();
1066 for (i = 1; i <= params.Length(); i++)
1068 if (params(i) < fpar)
1070 if (params(i) > lpar)
1073 if (FirstPar < fpar)
1079 //// end of check ////
1080 (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
1081 //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
1082 //gp_Pnt2d Plast = theCurve->Value(LastPar);
1083 //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
1085 //update FirstParOnPC and LastParOnPC
1086 if (FirstPar > FirstParOnPC)
1088 FirstParOnPC = FirstPar;
1091 MinLoc = CurveRep->Location();
1093 if (LastPar < LastParOnPC)
1095 LastParOnPC = LastPar;
1098 MinLoc = CurveRep->Location();
1104 Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
1107 MinLoc = E.Location() * MinLoc;
1110 if (MinPC->IsClosed())
1115 else if (C3d->IsPeriodic())
1117 Standard_Real delta = (C3d->Period() - (l - f))*0.5;
1122 else if (C3d->IsClosed())
1128 GeomAPI_ProjectPointOnCurve Projector;
1129 if (!Precision::IsInfinite(FirstParOnPC))
1131 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
1132 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
1133 P1.Transform(MinLoc.Transformation());
1134 Projector.Init( P1, C3d );
1135 if (Projector.NbPoints() > 0)
1136 f = Projector.LowerDistanceParameter();
1139 std::cout<<"ProjectPointOnCurve not done"<<std::endl;
1142 if (!Precision::IsInfinite(LastParOnPC))
1144 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
1145 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
1146 P2.Transform(MinLoc.Transformation());
1147 Projector.Init( P2, C3d );
1148 if (Projector.NbPoints() > 0)
1149 l = Projector.LowerDistanceParameter();
1152 std::cout<<"ProjectPointOnCurve not done"<<std::endl;
1156 BB.Range( NE, f, l );
1157 if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
1158 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1160 else if (!BRep_Tool::Degenerated(E)) //no 3d curve
1162 MinSurf = Handle(Geom_Surface)::DownCast
1163 (MinSurf->Transformed(MinLoc.Transformation()));
1164 Standard_Real max_deviation = 0.;
1165 if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
1167 if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1169 Standard_Boolean IsLine = Standard_False;
1170 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1171 IsLine = Standard_True;
1172 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
1173 MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
1175 Handle(Geom2d_Line) theLine = Handle(Geom2d_Line)::DownCast (MinPC);
1176 gp_Dir2d LineDir = theLine->Direction();
1177 if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
1178 IsLine = Standard_True;
1182 gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
1183 gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
1184 gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
1185 gp_Vec aVec(P1, P2);
1186 C3d = new Geom_Line( P1, aVec );
1192 Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
1193 GeomAdaptor_Surface GAsurf( MinSurf );
1194 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
1195 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
1196 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
1197 Standard_Real /*max_deviation,*/ average_deviation;
1198 GeomAbs_Shape Continuity = GeomAbs_C1;
1199 Standard_Integer MaxDegree = 14;
1200 Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
1201 GeomLib::BuildCurve3d(Precision::Confusion(),
1202 ConS, FirstParOnPC, LastParOnPC,
1203 C3d, max_deviation, average_deviation,
1204 Continuity, MaxDegree, MaxSegment);
1206 BB.UpdateEdge( NE, C3d, max_deviation );
1207 //BB.Range( NE, FirstParOnPC, LastParOnPC );
1208 Standard_Boolean ProjectionSuccess = Standard_True;
1210 //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1211 for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
1215 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
1216 Standard_Real FirstPar, LastPar;
1217 if (CurveRep->IsCurveOnSurface())
1219 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
1220 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1221 TopLoc_Location theLoc = CurveRep->Location();
1222 if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
1224 FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
1225 LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
1226 if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
1227 Abs(LastPar - LastParOnPC) > Precision::PConfusion())
1229 theLoc = E.Location() * theLoc;
1230 theSurf = Handle(Geom_Surface)::DownCast
1231 (theSurf->Transformed(theLoc.Transformation()));
1233 if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
1234 theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
1236 gp_Dir2d theDir = Handle(Geom2d_Line)::DownCast (theCurve)->Direction();
1237 if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
1238 theDir.IsParallel(gp::DY2d(), Precision::Angular()))
1240 Standard_Real U1, U2, V1, V2;
1241 theSurf->Bounds(U1, U2, V1, V2);
1242 gp_Pnt2d Origin = Handle(Geom2d_Line)::DownCast (theCurve)->Location();
1243 if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
1244 Abs(Origin.X()-U2) <= Precision::Confusion() ||
1245 Abs(Origin.Y()-V1) <= Precision::Confusion() ||
1246 Abs(Origin.Y()-V2) <= Precision::Confusion())
1248 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1254 Handle(Geom2d_Curve) ProjPCurve =
1255 GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
1256 if (ProjPCurve.IsNull())
1257 ProjectionSuccess = Standard_False;
1259 CurveRep->PCurve( ProjPCurve );
1263 if (ProjectionSuccess)
1264 BB.Range( NE, FirstParOnPC, LastParOnPC );
1267 BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
1268 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1274 Standard_Real FirstPar = C3d->FirstParameter();
1275 Standard_Real LastPar = C3d->LastParameter();
1277 if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
1278 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
1280 Handle(Geom_TrimmedCurve) aTrCurve =
1281 new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
1283 // The curve is not prolonged on begin or end.
1284 // Trying to prolong it adding a segment to its bound.
1289 Handle(Geom_Line) aLin;
1290 Handle(Geom_TrimmedCurve) aSegment;
1291 GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
1292 Standard_Real aTol = Precision::Confusion();
1293 Standard_Real aDelta = Max(a2Offset, 1.);
1295 if (FirstPar > anEf - a2Offset) {
1296 C3d->D1(FirstPar, aPBnd, aVBnd);
1297 aDBnd.SetXYZ(aVBnd.XYZ());
1298 aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
1299 aLin = new Geom_Line(aPBeg, aDBnd);
1300 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1302 if (!aCompCurve.Add(aSegment, aTol))
1306 if (LastPar < anEl + a2Offset) {
1307 C3d->D1(LastPar, aPBeg, aVBnd);
1308 aDBnd.SetXYZ(aVBnd.XYZ());
1309 aLin = new Geom_Line(aPBeg, aDBnd);
1310 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1312 if (!aCompCurve.Add(aSegment, aTol))
1316 C3d = aCompCurve.BSplineCurve();
1317 FirstPar = C3d->FirstParameter();
1318 LastPar = C3d->LastParameter();
1319 BB.UpdateEdge(NE, C3d, Precision::Confusion());
1321 else if (C3d->IsPeriodic())
1323 Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
1325 FirstPar = anEf - delta;
1326 LastPar = anEl + delta;
1328 else if (C3d->IsClosed())
1329 LastPar -= 0.05*(LastPar - FirstPar);
1331 BB.Range( NE, FirstPar, LastPar );
1334 // Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
1337 //=======================================================================
1338 //function : UpdateVertex
1340 //=======================================================================
1342 static Standard_Boolean UpdateVertex(TopoDS_Vertex V,
1345 Standard_Real TolConf)
1347 BRepAdaptor_Curve OC(OE);
1348 BRepAdaptor_Curve NC(NE);
1349 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
1350 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
1351 Standard_Real U = 0.;
1352 Standard_Real ParTol = Precision::PConfusion();
1353 gp_Pnt P = BRep_Tool::Pnt(V);
1354 Standard_Boolean OK = Standard_False;
1356 if (P.Distance(OC.Value(Of)) < TolConf) {
1357 if (Of >= Nf + ParTol && Of <= Nl + ParTol && P.Distance(NC.Value(Of)) < TolConf) {
1362 if (P.Distance(OC.Value(Ol)) < TolConf) {
1363 if (Ol >= Nf + ParTol && Ol <= Nl + ParTol && P.Distance(NC.Value(Ol)) < TolConf) {
1370 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
1371 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
1372 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
1373 aLocalShape = V.Oriented(TopAbs_INTERNAL);
1374 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
1375 U,NE,BRep_Tool::Tolerance(NE));
1376 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
1377 // U,NE,BRep_Tool::Tolerance(NE));
1382 //=======================================================================
1383 //function : Compute
1385 //=======================================================================
1387 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
1388 const TopoDS_Face& F,
1389 const TopTools_IndexedMapOfShape& NewEdges,
1390 const Standard_Real Tol,
1391 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
1398 //Do not intersect the edges of face
1399 TopTools_MapOfShape EdgesOfFace;
1400 TopExp_Explorer Explo( F, TopAbs_EDGE );
1401 for (; Explo.More(); Explo.Next())
1402 EdgesOfFace.Add( Explo.Current() );
1404 //-----------------------------------------------------------
1405 // calculate intersections2d on faces touched by
1407 //---------------------------------------------------------
1408 TopTools_ListIteratorOfListOfShape it1LE ;
1409 TopTools_ListIteratorOfListOfShape it2LE ;
1411 //-----------------------------------------------
1412 // Intersection of edges 2*2.
1413 //-----------------------------------------------
1414 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
1415 TopoDS_Vertex V1,V2;
1416 Standard_Integer j, i = 1;
1417 BRepAdaptor_Surface BAsurf(F);
1419 for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
1420 const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
1422 it2LE.Initialize(LE);
1424 while (j < i && it2LE.More()) {
1425 const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
1426 //--------------------------------------------------------------
1427 // Intersections of New edges obtained by intersection
1428 // between them and with edges of restrictions
1429 //------------------------------------------------------
1430 if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
1431 (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
1432 TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
1433 EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True, theDMVV);
1434 // EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
1443 //=======================================================================
1444 //function : ConnexIntByInt
1446 //=======================================================================
1447 void BRepOffset_Inter2d::ConnexIntByInt
1448 (const TopoDS_Face& FI,
1449 BRepOffset_Offset& OFI,
1450 TopTools_DataMapOfShapeShape& MES,
1451 const TopTools_DataMapOfShapeShape& Build,
1452 const Handle(BRepAlgo_AsDes)& AsDes2d,
1453 const Standard_Real Offset,
1454 const Standard_Real Tol,
1455 const BRepOffset_Analyse& Analyse,
1456 TopTools_IndexedMapOfShape& FacesWithVerts,
1457 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
1460 TopTools_DataMapOfShapeListOfShape MVE;
1461 BRepOffset_Tool::MapVertexEdges(FI,MVE);
1463 //---------------------
1464 // Extension of edges.
1465 //---------------------
1467 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
1468 for ( ; it.More(); it.Next()) {
1469 const TopTools_ListOfShape& L = it.Value();
1470 Standard_Boolean YaBuild = 0;
1471 TopTools_ListIteratorOfListOfShape itL(L);
1472 for (; itL.More(); itL.Next()) {
1473 YaBuild = Build.IsBound(itL.Value());
1477 for (itL.Initialize(L); itL.More(); itL.Next()) {
1478 const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
1479 if (EI.Orientation() != TopAbs_FORWARD &&
1480 EI.Orientation() != TopAbs_REVERSED)
1482 TopoDS_Shape aLocalShape = OFI.Generated(EI);
1483 const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
1484 if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
1485 ExtentEdge(OE,NE, Offset);
1492 TopoDS_Face FIO = TopoDS::Face(OFI.Face());
1493 if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
1495 BRepAdaptor_Surface BAsurf(FIO);
1497 TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1498 for (; exp.More(); exp.Next()) {
1499 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
1500 BRepTools_WireExplorer wexp;
1501 Standard_Boolean end = Standard_False ;
1502 TopoDS_Edge FirstE,CurE,NextE;
1504 TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1505 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1506 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
1508 continue; // Protection from case when explorer does not contain edges.
1509 CurE = FirstE = wexp.Current();
1510 TopTools_IndexedMapOfShape Edges;
1511 Standard_Boolean ToReverse1, ToReverse2;
1512 ToReverse1 = IsOrientationChanged(Edges, CurE);
1516 NextE = wexp.Current();
1519 NextE = FirstE; end = Standard_True;
1521 if (CurE.IsSame(NextE)) continue;
1523 ToReverse2 = IsOrientationChanged(Edges, NextE);
1525 TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
1526 gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1528 CurE = Analyse.EdgeReplacement (FI, CurE);
1529 NextE = Analyse.EdgeReplacement (FI, NextE);
1531 TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1532 TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1533 aLocalShape = OFI.Generated(NextE);
1534 TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1535 //------------------------------------------
1536 // Inter processing of images of CurE NextE.
1537 //------------------------------------------
1538 TopTools_ListOfShape LV1,LV2;
1539 Standard_Boolean DoInter = 1;
1540 TopoDS_Shape NE1,NE2;
1542 if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
1546 else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
1550 else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
1553 Standard_Boolean Tmp = ToReverse1;
1554 ToReverse1 = ToReverse2;
1561 //------------------------------------
1562 // NE1,NE2 can be a compound of Edges.
1563 //------------------------------------
1564 Standard_Boolean bCoincide;
1565 TopExp_Explorer Exp1, Exp2;
1566 for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
1567 TopoDS_Edge aE1 = TopoDS::Edge(Exp1.Current());
1568 for (Exp2.Init(NE2, TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1569 TopoDS_Edge aE2 = TopoDS::Edge(Exp2.Current());
1571 //Correct orientation of edges
1576 //////////////////////////////
1578 RefEdgeInter(FIO, BAsurf, aE1, aE2, AsDes2d,
1579 Tol, Standard_True, Pref, theDMVV, bCoincide);
1583 // check if some of the offset edges have been
1584 // generated out of the common vertex
1585 if (Build.IsBound(Vref)) {
1586 FacesWithVerts.Add(FI);
1590 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1593 if (MES.IsBound(CEO)) {
1594 UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
1595 AsDes2d->Add (MES(CEO),V);
1597 if (MES.IsBound(NEO)) {
1598 UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
1599 AsDes2d->Add (MES(NEO),V);
1603 CurE = wexp.Current();
1604 ToReverse1 = ToReverse2;
1609 //=======================================================================
1610 //function : ConnexIntByIntInVert
1611 //purpose : Intersection of the edges generated out of vertices
1612 //=======================================================================
1613 void BRepOffset_Inter2d::ConnexIntByIntInVert
1614 (const TopoDS_Face& FI,
1615 BRepOffset_Offset& OFI,
1616 TopTools_DataMapOfShapeShape& MES,
1617 const TopTools_DataMapOfShapeShape& Build,
1618 const Handle(BRepAlgo_AsDes)& AsDes,
1619 const Handle(BRepAlgo_AsDes)& AsDes2d,
1620 const Standard_Real Tol,
1621 const BRepOffset_Analyse& Analyse,
1622 TopTools_IndexedDataMapOfShapeListOfShape& theDMVV)
1624 TopoDS_Face FIO = TopoDS::Face(OFI.Face());
1625 if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
1627 TopTools_MapOfShape aME;
1628 const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO);
1629 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1630 for (; aItLE.More(); aItLE.Next()) {
1631 const TopoDS_Shape& aE = aItLE.Value();
1635 BRepAdaptor_Surface BAsurf(FIO);
1637 TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1638 for (; exp.More(); exp.Next()) {
1639 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
1641 BRepTools_WireExplorer wexp;
1642 Standard_Boolean end = Standard_False ;
1643 TopoDS_Edge FirstE,CurE,NextE;
1645 TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1646 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1647 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
1649 continue; // Protection from case when explorer does not contain edges.
1651 CurE = FirstE = wexp.Current();
1655 NextE = wexp.Current();
1658 NextE = FirstE; end = Standard_True;
1660 if (CurE.IsSame(NextE)) continue;
1662 TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
1663 gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1664 if (!Build.IsBound(Vref)) {
1669 CurE = Analyse.EdgeReplacement (FI, CurE);
1670 NextE = Analyse.EdgeReplacement (FI, NextE);
1672 TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1673 TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1674 aLocalShape = OFI.Generated(NextE);
1675 TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1677 TopoDS_Shape NE1,NE2;
1679 if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
1683 else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
1687 else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
1692 CurE = wexp.Current();
1696 TopExp_Explorer Exp1, Exp2;
1697 Standard_Boolean bCoincide;
1698 // intersect edges generated from vertex with the edges of the face
1699 TopoDS_Shape NE3 = Build(Vref);
1701 for (Exp2.Init(NE3, TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1702 const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current();
1703 if (!aME.Contains(aE3)) {
1707 // intersection with first edge
1708 for (Exp1.Init(NE1, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
1709 const TopoDS_Edge& aE1 = TopoDS::Edge(Exp1.Current());
1710 RefEdgeInter(FIO, BAsurf, aE1, aE3, AsDes2d,
1711 Tol, Standard_True, Pref, theDMVV, bCoincide);
1713 // in case of coincidence trim the edge E3 the same way as E1
1714 Store(aE3, AsDes2d->Descendant(aE1), Tol, Standard_True, AsDes2d, theDMVV);
1718 // intersection with second edge
1719 for (Exp1.Init(NE2, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
1720 const TopoDS_Edge& aE2 = TopoDS::Edge(Exp1.Current());
1721 RefEdgeInter(FIO, BAsurf, aE2, aE3, AsDes2d,
1722 Tol, Standard_True, Pref, theDMVV, bCoincide);
1724 // in case of coincidence trim the edge E3 the same way as E2
1725 Store(aE3, AsDes2d->Descendant(aE2), Tol, Standard_True, AsDes2d, theDMVV);
1729 // intersection of the edges generated from vertex
1731 for (Exp1.Init(NE3, TopAbs_EDGE); Exp1.More(); Exp1.Next()) {
1732 if (aE3.IsSame(Exp1.Current())) {
1737 for (Exp1.Next(); Exp1.More(); Exp1.Next()) {
1738 const TopoDS_Edge& aE3Next = TopoDS::Edge(Exp1.Current());
1739 if (aME.Contains(aE3Next)) {
1740 RefEdgeInter(FIO, BAsurf, aE3Next, aE3, AsDes2d,
1741 Tol, Standard_True, Pref, theDMVV, bCoincide);
1745 CurE = wexp.Current();
1750 //=======================================================================
1751 //function : MakeChain
1753 //=======================================================================
1754 static void MakeChain(const TopoDS_Shape& theV,
1755 const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
1756 TopTools_MapOfShape& theMDone,
1757 TopTools_ListOfShape& theChain)
1759 if (theMDone.Add(theV)) {
1760 theChain.Append(theV);
1761 const TopTools_ListOfShape* pLV = theDMVV.Seek(theV);
1763 TopTools_ListIteratorOfListOfShape aIt(*pLV);
1764 for (; aIt.More(); aIt.Next()) {
1765 MakeChain(aIt.Value(), theDMVV, theMDone, theChain);
1771 //=======================================================================
1772 //function : FuseVertices
1774 //=======================================================================
1775 void BRepOffset_Inter2d::FuseVertices(const TopTools_IndexedDataMapOfShapeListOfShape& theDMVV,
1776 const Handle(BRepAlgo_AsDes)& theAsDes)
1779 TopTools_MapOfShape aMVDone;
1780 Standard_Integer i, aNb = theDMVV.Extent();
1781 for (i = 1; i <= aNb; ++i) {
1782 const TopoDS_Vertex& aV = TopoDS::Vertex(theDMVV.FindKey(i));
1784 // find chain of vertices
1785 TopTools_ListOfShape aLVChain;
1786 MakeChain(aV, theDMVV, aMVDone, aLVChain);
1788 if (aLVChain.Extent() < 2) {
1793 TopoDS_Vertex aVNew;
1794 BOPTools_AlgoTools::MakeVertex(aLVChain, aVNew);
1796 TopoDS_Vertex aVNewInt = TopoDS::Vertex(aVNew.Oriented(TopAbs_INTERNAL));
1798 TopTools_ListIteratorOfListOfShape aIt(aLVChain);
1799 for (; aIt.More(); aIt.Next()) {
1800 const TopoDS_Shape& aVOld = aIt.Value();
1801 // update the parameters on edges
1802 TopoDS_Vertex aVOldInt = TopoDS::Vertex(aVOld.Oriented(TopAbs_INTERNAL));
1803 const TopTools_ListOfShape& aLE = theAsDes->Ascendant(aVOld);
1805 TopTools_ListIteratorOfListOfShape aItLE(aLE);
1806 for (; aItLE.More(); aItLE.Next()) {
1807 const TopoDS_Edge& aE = TopoDS::Edge(aItLE.Value());
1808 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1809 Standard_Real aT = BRep_Tool::Parameter(aVOldInt, aE);
1810 aBB.UpdateVertex(aVNewInt, aT, aE, aTolE);
1812 // and replace the vertex
1813 theAsDes->Replace(aVOld, aVNew);