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
9 // under the terms of the GNU Lesser General Public 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
21 #include <BRepOffset_Inter2d.ixx>
22 #include <BRepAlgo_AsDes.hxx>
23 #include <BRepOffset_Offset.hxx>
24 #include <BRepOffset_Tool.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepLib_MakeVertex.hxx>
29 #include <BRepAdaptor_Curve.hxx>
30 #include <BRepAdaptor_Surface.hxx>
31 #include <BRepTools_WireExplorer.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopTools_ListOfShape.hxx>
41 #include <TopTools_ListIteratorOfListOfShape.hxx>
42 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
44 #include <BRep_TEdge.hxx>
45 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
46 #include <BRep_CurveRepresentation.hxx>
47 #include <BRep_GCurve.hxx>
54 extern Standard_Integer AffichInt2d;
56 Standard_IMPORT Standard_Boolean AffichInt2d;
58 static Standard_Integer NbF2d = 0;
59 static Standard_Integer NbE2d = 0;
60 static Standard_Integer NbNewVertices = 0;
63 #include <Geom_Line.hxx>
64 #include <Geom_TrimmedCurve.hxx>
65 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
66 #include <Precision.hxx>
67 #include <Geom2d_TrimmedCurve.hxx>
68 #include <Geom2d_BezierCurve.hxx>
69 #include <Geom2d_BSplineCurve.hxx>
70 #include <Geom2d_Line.hxx>
71 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
73 #include <BRepLib.hxx>
74 #include <BRepAdaptor_Curve2d.hxx>
75 #include <Adaptor3d_HSurface.hxx>
76 #include <Adaptor3d_CurveOnSurface.hxx>
77 #include <Geom_BSplineSurface.hxx>
78 #include <Geom_CylindricalSurface.hxx>
79 #include <Geom_ConicalSurface.hxx>
80 #include <Adaptor2d_HCurve2d.hxx>
81 #include <TColGeom2d_SequenceOfCurve.hxx>
82 #include <Geom2dInt_GInter.hxx>
83 #include <IntRes2d_IntersectionPoint.hxx>
84 #include <IntRes2d_IntersectionSegment.hxx>
85 #include <GeomAPI_ProjectPointOnCurve.hxx>
86 #include <GeomAdaptor_Surface.hxx>
87 #include <Geom2dAdaptor_HCurve.hxx>
88 #include <GeomAdaptor_HSurface.hxx>
89 #include <GeomLib.hxx>
90 #include <GeomProjLib.hxx>
91 #include <TColgp_SequenceOfPnt.hxx>
92 #include <TColgp_Array1OfPnt2d.hxx>
93 #include <Bnd_Box.hxx>
94 #include <BndLib_Add3dCurve.hxx>
95 #include <BRepTools.hxx>
98 //=======================================================================
99 //function : CommonVertex
101 //=======================================================================
103 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
106 TopoDS_Vertex V1[2],V2[2],V;
107 // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
108 // TopExp::Vertices(E1,V1[0],V1[1]);
109 // TopExp::Vertices(E2,V2[0],V2[1]);
111 TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
112 TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
113 // The first edge is the current one, the second edge is the next one.
114 // We check last vertex of the first edge first.
115 // if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
116 // if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
117 if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
118 if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
119 // Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
123 //=======================================================================
126 //=======================================================================
128 static void Store (const TopoDS_Edge& E1,
129 const TopoDS_Edge& E2,
130 TopTools_ListOfShape& LV1,
131 TopTools_ListOfShape& LV2,
132 Handle(BRepAlgo_AsDes) AsDes,
135 //-------------------------------------------------------------
136 // Test if the points of intersection correspond to existing
137 // vertices. Otherwise add edges in the descendants.
138 // Note: at this stage only vertices of intersection are in the descendants.
139 //-------------------------------------------------------------
140 const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
141 const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
142 TopTools_ListOfShape NewVOnE1;
143 TopTools_ListOfShape NewVOnE2;
146 TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
148 TopAbs_Orientation O1,O2;
150 Standard_Boolean OnE1,OnE2;
152 for (itLV1.Initialize(LV1),itLV2.Initialize(LV2);
154 itLV1.Next() ,itLV2.Next()) {
156 TopoDS_Vertex V = TopoDS::Vertex(itLV1.Value());
158 U1 = (BRep_Tool::Degenerated(E1))?
159 BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E1) :
160 BRep_Tool::Parameter(V, E1);
161 U2 = (BRep_Tool::Degenerated(E2))?
162 BRep_Tool::Parameter(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), E2) :
163 BRep_Tool::Parameter(V, E2);
164 O1 = V.Orientation();
165 O2 = itLV2.Value().Orientation();
166 P = BRep_Tool::Pnt(V);
167 OnE1 = OnE2 = Standard_False;
169 if (!VOnE1.IsEmpty()) {
170 //-----------------------------------------------------------------
171 // Find if the point of intersection corresponds to a vertex of E1.
172 //-----------------------------------------------------------------
173 for (it.Initialize(VOnE1); it.More(); it.Next()) {
174 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
175 if (P.IsEqual(P1,Tol)) {
176 V = TopoDS::Vertex(it.Value());
178 OnE1 = Standard_True;
183 if (!VOnE2.IsEmpty()) {
185 //-----------------------------------------------------------------
186 // Find if the vertex found on E1 is not already on E2.
187 //-----------------------------------------------------------------
188 for (it.Initialize(VOnE2); it.More(); it.Next()) {
189 if (it.Value().IsSame(V)) {
190 OnE2 = Standard_True;
196 for (it.Initialize(VOnE2); it.More(); it.Next()) {
197 //-----------------------------------------------------------------
198 // Find if the point of intersection corresponds to a vertex of E2.
199 //-----------------------------------------------------------------
200 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
201 if (P.IsEqual(P2,Tol)) {
202 V = TopoDS::Vertex(it.Value());
204 OnE2 = Standard_True;
210 if (!V1.IsSame(V2)) {
211 //---------------------------------------------------------------
212 // Two vertices are actually the same.
213 // V2 will be replaced by V1.
214 // update the parameters of vertex on edges.
215 //---------------------------------------------------------------
218 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
220 for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
221 EWE2 = TopoDS::Edge(it.Value());
222 TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
223 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
225 // BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
226 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
227 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
228 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
231 AsDes->Replace(V2,V1);
236 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
237 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
238 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
241 NewVOnE1.Append(V.Oriented(O1));
245 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
246 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
247 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
250 NewVOnE2.Append(V.Oriented(O2));
255 if (!OnE1 && !OnE2) {
257 char* name = new char[100];
258 sprintf(name,"VV_%d",NbNewVertices++);
264 if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
265 if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
269 //=======================================================================
270 //function : EdgeInter
272 //=======================================================================
274 static void EdgeInter(const TopoDS_Face& F,
275 const TopoDS_Edge& E1,
276 const TopoDS_Edge& E2,
277 const Handle(BRepAlgo_AsDes)& AsDes,
279 Standard_Boolean WithOri)
284 char* name = new char[100];
285 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
287 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
295 Standard_Real f[3],l[3];
296 Standard_Real TolDub = 1.e-7;
299 BRep_Tool::Range(E1, f[1], l[1]);
300 BRep_Tool::Range(E2, f[2], l[2]);
302 BRepAdaptor_Curve CE1(E1,F);
303 BRepAdaptor_Curve CE2(E2,F);
305 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
306 TopTools_ListOfShape LV1;
307 TopTools_ListOfShape LV2;
311 if (!TopExp::CommonVertex( E1, E2, CV ))
313 BRepLib::BuildCurve3d(E1);
314 BRepLib::BuildCurve3d(E2);
316 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
317 TolSum = Max( TolSum, 1.e-5 );
319 TColgp_SequenceOfPnt ResPoints;
320 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
322 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
326 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
327 TopoDS_Iterator iter( EI[ideg] );
330 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
331 DegPoint = BRep_Tool::Pnt(vdeg);
335 BRepAdaptor_Curve CEdeg( EI[ideg], F );
336 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
339 BRepAdaptor_Surface BAsurf(F);
340 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
341 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
342 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
343 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
344 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
345 for (i = 1; i <= Inter2d.NbPoints(); i++)
352 gp_Pnt2d P2d = Inter2d.Point(i).Value();
353 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
355 ResPoints.Append( P3d );
356 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
357 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
360 for (i = 1; i <= ResPoints.Length(); i++)
362 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
363 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
364 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
367 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
372 gp_Pnt P = ResPoints(i); //ponc1.Value();
373 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
374 aNewVertex.Orientation(TopAbs_INTERNAL);
375 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
376 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
377 gp_Pnt P1 = CE1.Value(aT1);
378 gp_Pnt P2 = CE2.Value(aT2);
379 Standard_Real dist1, dist2, dist3;
380 dist1 = P1.Distance(P);
381 dist2 = P2.Distance(P);
382 dist3 = P1.Distance(P2);
383 dist1 = Max( dist1, dist2 );
384 dist1 = Max( dist1, dist3 );
385 B.UpdateVertex( aNewVertex, dist1 );
388 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
390 cout << "out of limit"<<endl;
391 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
393 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
395 cout << "out of limit"<<endl;
396 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
398 Standard_Real MilTol2 = 1000*Tol*Tol;
399 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
401 cout << "Inter2d : Solution rejected "<<endl;
402 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
403 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
404 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
405 cout<<"MaxDist = "<<dist1<<endl;
408 //define the orientation of a new vertex
409 TopAbs_Orientation OO1 = TopAbs_REVERSED;
410 TopAbs_Orientation OO2 = TopAbs_REVERSED;
413 BRepAdaptor_Curve2d PCE1( E1, F );
414 BRepAdaptor_Curve2d PCE2( E2, F );
416 gp_Vec2d V1, V2, V1or, V2or;
417 PCE1.D1( aT1, P2d1, V1 );
418 PCE2.D1( aT2, P2d2, V2 );
419 V1or = V1; V2or = V2;
420 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
421 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
422 Standard_Real CrossProd = V2or ^ V1;
424 if (Abs(CrossProd) <= gp::Resolution())
425 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
428 OO1 = TopAbs_FORWARD;
429 CrossProd = V1or ^ V2;
431 OO2 = TopAbs_FORWARD;
433 LV1.Append( aNewVertex.Oriented(OO1) );
434 LV2.Append( aNewVertex.Oriented(OO2) );
438 //----------------------------------
440 //---------------------------------
442 Standard_Real TolConf = Tol;
443 TopoDS_Vertex V1[2],V2[2];
444 TopExp::Vertices(E1,V1[0],V1[1]);
445 TopExp::Vertices(E2,V2[0],V2[1]);
448 for (j = 0; j < 2; j++) {
449 if (V1[j].IsNull()) continue;
450 for (Standard_Integer k = 0; k < 2; k++) {
451 if (V2[k].IsNull()) continue;
452 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
453 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
454 Standard_Real Dist = P1.Distance(P2);
455 if (Dist < TolConf) {
456 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
457 U1 = (j == 0) ? f[1] : l[1];
458 U2 = (k == 0) ? f[2] : l[2];
459 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
460 // Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
461 Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
463 if (!V1[j].IsSame(V2[k])) {
464 Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
466 aTol = Max(aTol, aTol2);
469 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
470 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
471 // B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
472 // B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
473 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
475 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
477 // Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
478 LV1.Prepend(V.Oriented(V1[j].Orientation()));
479 LV2.Prepend(V.Oriented(V2[k].Orientation()));
484 Standard_Boolean AffichPurge = Standard_False;
486 if ( !LV1.IsEmpty()) {
487 //----------------------------------
488 // Remove all vertices.
489 // There can be doubles
490 //----------------------------------
491 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
493 Standard_Boolean Purge = Standard_True;
497 Purge = Standard_False;
498 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
499 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
501 it2LV1.Initialize(LV1);
503 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
504 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
505 // Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
506 // if (P1.IsEqual(P2,10*Tol)) {
509 aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
510 BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
511 if (P1.IsEqual(P2,aTol)) {
512 // Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
515 if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
516 Purge = Standard_True;
526 //---------------------------------
527 // Vertex storage in DS.
528 //---------------------------------
529 // Modified by skv - Tue Jan 13 15:14:30 2004 Begin
530 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
532 TolStore = Max(TolStore, 10.*Tol);
534 Store (E1,E2,LV1,LV2,AsDes,TolStore);
535 // Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
536 // Store (E1,E2,LV1,LV2,AsDes,Tol);
537 // Modified by skv - Tue Jan 13 15:14:30 2004 End
540 //=======================================================================
541 //function : EdgeInter
543 //=======================================================================
545 static void RefEdgeInter(const TopoDS_Face& F,
546 const TopoDS_Edge& E1,
547 const TopoDS_Edge& E2,
548 const Handle(BRepAlgo_AsDes)& AsDes,
550 Standard_Boolean WithOri,
556 char* name = new char[100];
557 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
559 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
567 Standard_Real f[3],l[3];
568 Standard_Real TolDub = 1.e-7;
571 //BRep_Tool::Range(E1, f[1], l[1]);
572 //BRep_Tool::Range(E2, f[2], l[2]);
574 BRepAdaptor_Curve CE1(E1,F);
575 BRepAdaptor_Curve CE2(E2,F);
577 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
578 TopTools_ListOfShape LV1;
579 TopTools_ListOfShape LV2;
582 BRepLib::BuildCurve3d(E1);
583 BRepLib::BuildCurve3d(E2);
585 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
586 TolSum = Max( TolSum, 1.e-5 );
588 TColgp_SequenceOfPnt ResPoints;
589 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
591 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
595 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
596 TopoDS_Iterator iter( EI[ideg] );
599 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
600 DegPoint = BRep_Tool::Pnt(vdeg);
604 BRepAdaptor_Curve CEdeg( EI[ideg], F );
605 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
608 BRepAdaptor_Surface BAsurf(F);
609 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
610 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
611 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
612 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
613 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
614 for (i = 1; i <= Inter2d.NbPoints(); i++)
621 gp_Pnt2d P2d = Inter2d.Point(i).Value();
622 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
624 ResPoints.Append( P3d );
625 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
626 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
629 for (i = 1; i <= ResPoints.Length(); i++)
631 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
632 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
633 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
636 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
641 gp_Pnt P = ResPoints(i); //ponc1.Value();
642 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
643 aNewVertex.Orientation(TopAbs_INTERNAL);
644 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
645 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
646 gp_Pnt P1 = CE1.Value(aT1);
647 gp_Pnt P2 = CE2.Value(aT2);
648 Standard_Real dist1, dist2, dist3;
649 dist1 = P1.Distance(P);
650 dist2 = P2.Distance(P);
651 dist3 = P1.Distance(P2);
652 dist1 = Max( dist1, dist2 );
653 dist1 = Max( dist1, dist3 );
654 B.UpdateVertex( aNewVertex, dist1 );
657 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
659 cout << "out of limit"<<endl;
660 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
662 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
664 cout << "out of limit"<<endl;
665 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
667 Standard_Real MilTol2 = 1000*Tol*Tol;
668 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
670 cout << "Inter2d : Solution rejected"<<endl;
671 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
672 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
673 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
674 cout<<"MaxDist = "<<dist1<<endl;
677 //define the orientation of a new vertex
678 TopAbs_Orientation OO1 = TopAbs_REVERSED;
679 TopAbs_Orientation OO2 = TopAbs_REVERSED;
682 BRepAdaptor_Curve2d PCE1( E1, F );
683 BRepAdaptor_Curve2d PCE2( E2, F );
685 gp_Vec2d V1, V2, V1or, V2or;
686 PCE1.D1( aT1, P2d1, V1 );
687 PCE2.D1( aT2, P2d2, V2 );
688 V1or = V1; V2or = V2;
689 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
690 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
691 Standard_Real CrossProd = V2or ^ V1;
693 if (Abs(CrossProd) <= gp::Resolution())
694 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
697 OO1 = TopAbs_FORWARD;
698 CrossProd = V1or ^ V2;
700 OO2 = TopAbs_FORWARD;
702 LV1.Append( aNewVertex.Oriented(OO1) );
703 LV2.Append( aNewVertex.Oriented(OO2) );
706 //----------------------------------
708 //---------------------------------
710 Standard_Real TolConf = Tol;
711 TopoDS_Vertex V1[2],V2[2];
712 TopExp::Vertices(E1,V1[0],V1[1]);
713 TopExp::Vertices(E2,V2[0],V2[1]);
716 for (j = 0; j < 2; j++) {
717 if (V1[j].IsNull()) continue;
718 for (Standard_Integer k = 0; k < 2; k++) {
719 if (V2[k].IsNull()) continue;
720 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
721 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
722 Standard_Real Dist = P1.Distance(P2);
723 if (Dist < TolConf) {
724 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
725 U1 = (j == 0) ? f[1] : l[1];
726 U2 = (k == 0) ? f[2] : l[2];
727 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
728 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
729 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
730 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
732 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
734 LV1.Prepend(V.Oriented(V1[j].Orientation()));
735 LV2.Prepend(V.Oriented(V2[k].Orientation()));
740 Standard_Boolean AffichPurge = Standard_False;
742 if ( !LV1.IsEmpty()) {
743 //----------------------------------
744 // Remove all vertices.
745 // there can be doubles
746 //----------------------------------
747 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
749 Standard_Boolean Purge = Standard_True;
753 Purge = Standard_False;
754 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
755 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
757 it2LV1.Initialize(LV1);
759 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
760 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
761 if (P1.IsEqual(P2,10*Tol)) {
764 if (AffichPurge) cout <<"Doubles removed in EdgeInter."<<endl;
765 Purge = Standard_True;
775 //---------------------------------
776 // Vertex storage in SD.
777 //---------------------------------
778 ////-----------------------------------------------------
779 if(LV1.Extent() > 1) {
780 //cout << "IFV - RefEdgeInter: remove vertex" << endl;
781 Standard_Real dmin = RealLast();
783 for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
784 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
785 Standard_Real d = P.SquareDistance(Pref);
788 Vmin = TopoDS::Vertex(it1LV1.Value());
791 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
792 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
793 if(!Vmin.IsSame(it1LV1.Value())) {
796 if(!it1LV1.More()) break;
801 ////-----------------------------------------------------
803 // Modified by skv - Tue Jan 13 15:14:30 2004 Begin
804 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
806 TolStore = Max(TolStore, 10.*Tol);
808 Store (E1,E2,LV1,LV2,AsDes,TolStore);
809 // Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
810 // Store (E1,E2,LV1,LV2,AsDes,Tol);
811 // Modified by skv - Tue Jan 13 15:14:30 2004 End
816 //======================================================================
817 //function : EvaluateMaxSegment
818 //purpose : return MaxSegment to pass in approximation
819 //======================================================================
821 static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurveOnSurface)
823 Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface();
824 Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
826 Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
828 if (aSurf->GetType() == GeomAbs_BSplineSurface) {
829 Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
830 aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
832 if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
833 aNbC2dKnots = aCurv2d->NbKnots();
835 Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ;
840 //=======================================================================
841 //function : ExtendPCurve
843 //=======================================================================
845 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
846 const Standard_Real anEf,
847 const Standard_Real anEl,
848 const Standard_Real a2Offset,
849 Handle(Geom2d_Curve)& NewPCurve)
852 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
853 NewPCurve = (*((Handle(Geom2d_TrimmedCurve)*)&NewPCurve))->BasisCurve();
855 Standard_Real FirstPar = NewPCurve->FirstParameter();
856 Standard_Real LastPar = NewPCurve->LastParameter();
858 if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
859 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
861 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
863 Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
864 if (aBezier->NbPoles() == 2)
866 TColgp_Array1OfPnt2d thePoles(1,2);
867 aBezier->Poles(thePoles);
868 gp_Vec2d aVec(thePoles(1), thePoles(2));
869 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
870 return Standard_True;
873 else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
875 Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
876 if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
878 TColgp_Array1OfPnt2d thePoles(1,2);
879 aBSpline->Poles(thePoles);
880 gp_Vec2d aVec(thePoles(1), thePoles(2));
881 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
882 return Standard_True;
887 FirstPar = aPCurve->FirstParameter();
888 LastPar = aPCurve->LastParameter();
889 Handle(Geom2d_TrimmedCurve) aTrCurve =
890 new Geom2d_TrimmedCurve(aPCurve, FirstPar, LastPar);
892 // The curve is not prolonged on begin or end.
893 // Trying to prolong it adding a segment to its bound.
898 Handle(Geom2d_Line) aLin;
899 Handle(Geom2d_TrimmedCurve) aSegment;
900 Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
901 Standard_Real aTol = Precision::Confusion();
902 Standard_Real aDelta = Max(a2Offset, 1.);
904 if (FirstPar > anEf - a2Offset) {
905 aPCurve->D1(FirstPar, aPBnd, aVBnd);
906 aDBnd.SetXY(aVBnd.XY());
907 aPBeg = aPBnd.Translated(gp_Vec2d(-aDelta*aDBnd.XY()));
908 aLin = new Geom2d_Line(aPBeg, aDBnd);
909 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
911 if (!aCompCurve.Add(aSegment, aTol))
912 return Standard_False;
915 if (LastPar < anEl + a2Offset) {
916 aPCurve->D1(LastPar, aPBeg, aVBnd);
917 aDBnd.SetXY(aVBnd.XY());
918 aLin = new Geom2d_Line(aPBeg, aDBnd);
919 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
921 if (!aCompCurve.Add(aSegment, aTol))
922 return Standard_False;
925 NewPCurve = aCompCurve.BSplineCurve();
926 return Standard_True;
929 //=======================================================================
930 //function : ExtentEdge
932 //=======================================================================
934 // Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
935 //static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE)
936 static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
938 //BRepLib::BuildCurve3d(E);
940 TopoDS_Shape aLocalShape = E.EmptyCopied();
943 Standard_Real a2Offset = 2.*Abs(theOffset);
945 Standard_Integer i, j;
947 BRep_Tool::Range(E, anEf, anEl);
948 NE = TopoDS::Edge(aLocalShape);
949 // NE = TopoDS::Edge(E.EmptyCopied());
950 // Enough for analytic edges, for general case reconstruct the
951 // geometry of the edge recalculating the intersection of surfaces.
953 //BRepLib::BuildCurve3d(E);
955 Standard_Integer NbPCurves = 0;
956 Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
957 Handle(Geom2d_Curve) MinPC;
958 Handle(Geom_Surface) MinSurf;
959 TopLoc_Location MinLoc;
961 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
962 for (; itr.More(); itr.Next())
964 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
965 Standard_Real FirstPar, LastPar;
966 if (CurveRep->IsCurveOnSurface())
969 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
970 FirstPar = theCurve->FirstParameter();
971 LastPar = theCurve->LastParameter();
973 if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
974 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
976 Handle(Geom2d_Curve) NewPCurve;
977 if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
979 CurveRep->PCurve(NewPCurve);
980 FirstPar = NewPCurve->FirstParameter();
981 LastPar = NewPCurve->LastParameter();
982 if (CurveRep->IsCurveOnClosedSurface())
984 Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
985 if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
986 CurveRep->PCurve2(NewPCurve);
990 else if (theCurve->IsPeriodic())
992 Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
994 FirstPar = anEf - delta;
995 LastPar = anEl + delta;
997 else if (theCurve->IsClosed())
998 LastPar -= 0.05*(LastPar - FirstPar);
1000 //check FirstPar and LastPar: the pcurve should be in its surface
1001 theCurve = CurveRep->PCurve();
1002 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1003 Standard_Real Umin, Umax, Vmin, Vmax;
1004 theSurf->Bounds(Umin, Umax, Vmin, Vmax);
1005 TColGeom2d_SequenceOfCurve BoundLines;
1006 if (!Precision::IsInfinite(Vmin))
1008 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
1009 gp_Dir2d( 1., 0. ));
1010 BoundLines.Append(aLine);
1012 if (!Precision::IsInfinite(Umin))
1014 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
1015 gp_Dir2d( 0., 1. ));
1016 BoundLines.Append(aLine);
1018 if (!Precision::IsInfinite(Vmax))
1020 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
1021 gp_Dir2d( 1., 0. ));
1022 BoundLines.Append(aLine);
1024 if (!Precision::IsInfinite(Umax))
1026 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
1027 gp_Dir2d( 0., 1. ));
1028 BoundLines.Append(aLine);
1031 TColStd_SequenceOfReal params;
1032 Geom2dInt_GInter IntCC;
1033 Geom2dAdaptor_Curve GAcurve(theCurve);
1034 for (i = 1; i <= BoundLines.Length(); i++)
1036 Geom2dAdaptor_Curve GAline( BoundLines(i) );
1037 IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
1040 for (j = 1; j <= IntCC.NbPoints(); j++)
1042 const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
1043 gp_Pnt2d aPoint = ip.Value();
1044 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1045 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1046 params.Append( ip.ParamOnFirst() );
1048 for (j = 1; j <= IntCC.NbSegments(); j++)
1050 const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
1051 if (is.HasFirstPoint())
1053 const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
1054 gp_Pnt2d aPoint = ip.Value();
1055 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1056 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1057 params.Append( ip.ParamOnFirst() );
1059 if (is.HasLastPoint())
1061 const IntRes2d_IntersectionPoint& ip = is.LastPoint();
1062 gp_Pnt2d aPoint = ip.Value();
1063 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1064 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1065 params.Append( ip.ParamOnFirst() );
1070 if (!params.IsEmpty())
1072 if (params.Length() == 1)
1074 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
1075 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
1076 PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
1078 if (LastPar > params(1))
1079 LastPar = params(1);
1081 else if (FirstPar < params(1))
1082 FirstPar = params(1);
1086 Standard_Real fpar = RealLast(), lpar = RealFirst();
1087 for (i = 1; i <= params.Length(); i++)
1089 if (params(i) < fpar)
1091 if (params(i) > lpar)
1094 if (FirstPar < fpar)
1100 //// end of check ////
1101 (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
1102 //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
1103 //gp_Pnt2d Plast = theCurve->Value(LastPar);
1104 //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
1106 //update FirstParOnPC and LastParOnPC
1107 if (FirstPar > FirstParOnPC)
1109 FirstParOnPC = FirstPar;
1112 MinLoc = CurveRep->Location();
1114 if (LastPar < LastParOnPC)
1116 LastParOnPC = LastPar;
1119 MinLoc = CurveRep->Location();
1125 Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
1128 MinLoc = E.Location() * MinLoc;
1131 if (MinPC->IsClosed())
1136 else if (C3d->IsPeriodic())
1138 Standard_Real delta = (C3d->Period() - (l - f))*0.5;
1143 else if (C3d->IsClosed())
1149 GeomAPI_ProjectPointOnCurve Projector;
1150 if (!Precision::IsInfinite(FirstParOnPC))
1152 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
1153 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
1154 P1.Transform(MinLoc.Transformation());
1155 Projector.Init( P1, C3d );
1156 if (Projector.NbPoints() > 0)
1157 f = Projector.LowerDistanceParameter();
1160 cout<<"ProjectPointOnCurve not done"<<endl;
1163 if (!Precision::IsInfinite(LastParOnPC))
1165 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
1166 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
1167 P2.Transform(MinLoc.Transformation());
1168 Projector.Init( P2, C3d );
1169 if (Projector.NbPoints() > 0)
1170 l = Projector.LowerDistanceParameter();
1173 cout<<"ProjectPointOnCurve not done"<<endl;
1177 BB.Range( NE, f, l );
1178 if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
1179 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1181 else if (!BRep_Tool::Degenerated(E)) //no 3d curve
1183 MinSurf = Handle(Geom_Surface)::DownCast
1184 (MinSurf->Transformed(MinLoc.Transformation()));
1185 Standard_Real max_deviation = 0.;
1186 if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
1188 if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1190 Standard_Boolean IsLine = Standard_False;
1191 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1192 IsLine = Standard_True;
1193 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
1194 MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
1196 Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
1197 gp_Dir2d LineDir = theLine->Direction();
1198 if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
1199 IsLine = Standard_True;
1203 gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
1204 gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
1205 gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
1206 gp_Vec aVec(P1, P2);
1207 C3d = new Geom_Line( P1, aVec );
1213 Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
1214 GeomAdaptor_Surface GAsurf( MinSurf );
1215 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
1216 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
1217 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
1218 Standard_Real /*max_deviation,*/ average_deviation;
1219 GeomAbs_Shape Continuity = GeomAbs_C1;
1220 Standard_Integer MaxDegree = 14;
1221 Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
1222 GeomLib::BuildCurve3d(Precision::Confusion(),
1223 ConS, FirstParOnPC, LastParOnPC,
1224 C3d, max_deviation, average_deviation,
1225 Continuity, MaxDegree, MaxSegment);
1227 BB.UpdateEdge( NE, C3d, max_deviation );
1228 //BB.Range( NE, FirstParOnPC, LastParOnPC );
1229 Standard_Boolean ProjectionSuccess = Standard_True;
1231 //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1232 for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
1236 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
1237 Standard_Real FirstPar, LastPar;
1238 if (CurveRep->IsCurveOnSurface())
1240 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
1241 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1242 TopLoc_Location theLoc = CurveRep->Location();
1243 if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
1245 FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
1246 LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
1247 if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
1248 Abs(LastPar - LastParOnPC) > Precision::PConfusion())
1250 theLoc = E.Location() * theLoc;
1251 theSurf = Handle(Geom_Surface)::DownCast
1252 (theSurf->Transformed(theLoc.Transformation()));
1254 if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
1255 theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
1257 gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
1258 if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
1259 theDir.IsParallel(gp::DY2d(), Precision::Angular()))
1261 Standard_Real U1, U2, V1, V2;
1262 theSurf->Bounds(U1, U2, V1, V2);
1263 gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
1264 if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
1265 Abs(Origin.X()-U2) <= Precision::Confusion() ||
1266 Abs(Origin.Y()-V1) <= Precision::Confusion() ||
1267 Abs(Origin.Y()-V2) <= Precision::Confusion())
1269 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1275 Handle(Geom2d_Curve) ProjPCurve =
1276 GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
1277 if (ProjPCurve.IsNull())
1278 ProjectionSuccess = Standard_False;
1280 CurveRep->PCurve( ProjPCurve );
1284 if (ProjectionSuccess)
1285 BB.Range( NE, FirstParOnPC, LastParOnPC );
1288 BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
1289 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1295 Standard_Real FirstPar = C3d->FirstParameter();
1296 Standard_Real LastPar = C3d->LastParameter();
1298 if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
1299 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
1301 Handle(Geom_TrimmedCurve) aTrCurve =
1302 new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
1304 // The curve is not prolonged on begin or end.
1305 // Trying to prolong it adding a segment to its bound.
1310 Handle(Geom_Line) aLin;
1311 Handle(Geom_TrimmedCurve) aSegment;
1312 GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
1313 Standard_Real aTol = Precision::Confusion();
1314 Standard_Real aDelta = Max(a2Offset, 1.);
1316 if (FirstPar > anEf - a2Offset) {
1317 C3d->D1(FirstPar, aPBnd, aVBnd);
1318 aDBnd.SetXYZ(aVBnd.XYZ());
1319 aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
1320 aLin = new Geom_Line(aPBeg, aDBnd);
1321 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1323 if (!aCompCurve.Add(aSegment, aTol))
1327 if (LastPar < anEl + a2Offset) {
1328 C3d->D1(LastPar, aPBeg, aVBnd);
1329 aDBnd.SetXYZ(aVBnd.XYZ());
1330 aLin = new Geom_Line(aPBeg, aDBnd);
1331 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1333 if (!aCompCurve.Add(aSegment, aTol))
1337 C3d = aCompCurve.BSplineCurve();
1338 FirstPar = C3d->FirstParameter();
1339 LastPar = C3d->LastParameter();
1340 BB.UpdateEdge(NE, C3d, Precision::Confusion());
1342 else if (C3d->IsPeriodic())
1344 Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
1346 FirstPar = anEf - delta;
1347 LastPar = anEl + delta;
1349 else if (C3d->IsClosed())
1350 LastPar -= 0.05*(LastPar - FirstPar);
1352 BB.Range( NE, FirstPar, LastPar );
1355 // Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
1358 //=======================================================================
1359 //function : UpdateVertex
1361 //=======================================================================
1363 static Standard_Boolean UpdateVertex(TopoDS_Vertex V,
1366 Standard_Real TolConf)
1368 BRepAdaptor_Curve OC(OE);
1369 BRepAdaptor_Curve NC(NE);
1370 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
1371 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
1372 Standard_Real U = 0.;
1373 Standard_Real ParTol = Precision::PConfusion();
1374 gp_Pnt P = BRep_Tool::Pnt(V);
1375 Standard_Boolean OK = Standard_False;
1377 if (P.Distance(OC.Value(Of)) < TolConf) {
1378 if (Of >= Nf + ParTol && Of <= Nl + ParTol && P.Distance(NC.Value(Of)) < TolConf) {
1383 if (P.Distance(OC.Value(Ol)) < TolConf) {
1384 if (Ol >= Nf + ParTol && Ol <= Nl + ParTol && P.Distance(NC.Value(Ol)) < TolConf) {
1391 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
1392 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
1393 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
1394 aLocalShape = V.Oriented(TopAbs_INTERNAL);
1395 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
1396 U,NE,BRep_Tool::Tolerance(NE));
1397 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
1398 // U,NE,BRep_Tool::Tolerance(NE));
1403 //=======================================================================
1404 //function : Compute
1406 //=======================================================================
1408 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
1409 const TopoDS_Face& F,
1410 const TopTools_IndexedMapOfShape& NewEdges,
1411 const Standard_Real Tol)
1418 //Do not intersect the edges of face
1419 TopTools_MapOfShape EdgesOfFace;
1420 TopExp_Explorer Explo( F, TopAbs_EDGE );
1421 for (; Explo.More(); Explo.Next())
1422 EdgesOfFace.Add( Explo.Current() );
1424 //-----------------------------------------------------------
1425 // calculate intersections2d on faces touched by
1427 //---------------------------------------------------------
1428 TopTools_ListIteratorOfListOfShape it1LE ;
1429 TopTools_ListIteratorOfListOfShape it2LE ;
1431 //-----------------------------------------------
1432 // Intersection of edges 2*2.
1433 //-----------------------------------------------
1434 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
1435 TopoDS_Vertex V1,V2;
1436 Standard_Integer j, i = 1;
1438 for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
1439 const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
1441 it2LE.Initialize(LE);
1443 while (j < i && it2LE.More()) {
1444 const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
1445 //--------------------------------------------------------------
1446 // Intersections of New edges obtained by intersection
1447 // between them and with edges of restrictions
1448 //------------------------------------------------------
1449 if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
1450 (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
1451 TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
1452 EdgeInter(TopoDS::Face(aLocalShape),E1,E2,AsDes,Tol,Standard_True);
1453 // EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
1462 //=======================================================================
1463 //function : ConnexIntByInt
1465 //=======================================================================
1467 // Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
1468 // Add another parameter: offset value.
1469 void BRepOffset_Inter2d::ConnexIntByInt
1470 (const TopoDS_Face& FI,
1471 BRepOffset_Offset& OFI,
1472 TopTools_DataMapOfShapeShape& MES,
1473 const TopTools_DataMapOfShapeShape& Build,
1474 const Handle(BRepAlgo_AsDes)& AsDes,
1475 const Standard_Real Offset,
1476 const Standard_Real Tol)
1477 // Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
1480 TopTools_DataMapOfShapeListOfShape MVE;
1481 BRepOffset_Tool::MapVertexEdges(FI,MVE);
1483 //---------------------
1484 // Extension of edges.
1485 //---------------------
1487 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
1488 for ( ; it.More(); it.Next()) {
1489 const TopTools_ListOfShape& L = it.Value();
1490 Standard_Boolean YaBuild = 0;
1491 TopTools_ListIteratorOfListOfShape itL(L);
1492 for (; itL.More(); itL.Next()) {
1493 YaBuild = Build.IsBound(itL.Value());
1497 for (itL.Initialize(L); itL.More(); itL.Next()) {
1498 const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
1499 TopoDS_Shape aLocalShape = OFI.Generated(EI);
1500 const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
1501 // const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
1502 if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
1503 // Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin
1504 // ExtentEdge(OE,NE);
1505 ExtentEdge(OE,NE, Offset);
1506 // Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End
1513 TopoDS_Face FIO = TopoDS::Face(OFI.Face());
1514 if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
1516 TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1517 for (; exp.More(); exp.Next()) {
1518 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
1519 BRepTools_WireExplorer wexp;
1520 Standard_Boolean end = Standard_False ;
1521 TopoDS_Edge FirstE,CurE,NextE;
1523 TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1524 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1525 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
1526 // wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
1527 // TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
1528 CurE = FirstE = wexp.Current();
1532 NextE = wexp.Current();
1535 NextE = FirstE; end = Standard_True;
1537 if (CurE.IsSame(NextE)) continue;
1540 TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
1541 gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1544 TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1545 TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1546 aLocalShape = OFI.Generated(NextE);
1547 TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1548 // TopoDS_Edge CEO = TopoDS::Edge(OFI.Generated(CurE));
1549 // TopoDS_Edge NEO = TopoDS::Edge(OFI.Generated(NextE));
1550 //------------------------------------------
1551 // Inter processing of images of CurE NextE.
1552 //------------------------------------------
1553 TopTools_ListOfShape LV1,LV2;
1554 Standard_Boolean DoInter = 1;
1555 TopoDS_Shape NE1,NE2;
1557 if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
1561 else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
1565 else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
1573 //------------------------------------
1574 // NE1,NE2 can be a compound of Edges.
1575 //------------------------------------
1576 TopExp_Explorer Exp1,Exp2;
1577 for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1578 for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
1579 RefEdgeInter(FIO,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
1580 AsDes,Tol,Standard_True/*Standard_False*/, Pref);
1585 if (MES.IsBound(CEO)) {
1586 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1587 UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
1588 AsDes->Add (MES(CEO),V);
1590 else if (MES.IsBound(NEO)) {
1591 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1592 UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
1593 AsDes->Add (MES(NEO),V);