1 // File: BRepOffset_Inter2d.cxx
2 // Created: Tue Sep 3 16:37:35 1996
3 // Author: Yves FRICAUD
4 // <yfr@claquox.paris1.matra-dtv.fr>
6 // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455
10 #include <BRepOffset_Inter2d.ixx>
11 #include <BRepAlgo_AsDes.hxx>
12 #include <BRepOffset_Offset.hxx>
13 #include <BRepOffset_Tool.hxx>
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepLib_MakeVertex.hxx>
18 #include <BRepAdaptor_Curve.hxx>
19 #include <BRepAdaptor_Surface.hxx>
20 #include <BRepTools_WireExplorer.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <TopoDS_Iterator.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
33 #include <BRep_TEdge.hxx>
34 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
35 #include <BRep_CurveRepresentation.hxx>
36 #include <BRep_GCurve.hxx>
43 extern Standard_Integer AffichInt2d;
45 Standard_IMPORT Standard_Boolean AffichInt2d;
47 static Standard_Integer NbF2d = 0;
48 static Standard_Integer NbE2d = 0;
49 static Standard_Integer NbNewVertices = 0;
52 #include <Geom_Line.hxx>
53 #include <Geom_TrimmedCurve.hxx>
54 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
55 #include <Precision.hxx>
56 #include <Geom2d_TrimmedCurve.hxx>
57 #include <Geom2d_BezierCurve.hxx>
58 #include <Geom2d_BSplineCurve.hxx>
59 #include <Geom2d_Line.hxx>
60 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
62 #include <BRepLib.hxx>
63 #include <BRepAdaptor_Curve2d.hxx>
64 #include <Adaptor3d_HSurface.hxx>
65 #include <Adaptor3d_CurveOnSurface.hxx>
66 #include <Geom_BSplineSurface.hxx>
67 #include <Geom_CylindricalSurface.hxx>
68 #include <Geom_ConicalSurface.hxx>
69 #include <Adaptor2d_HCurve2d.hxx>
70 #include <TColGeom2d_SequenceOfCurve.hxx>
71 #include <Geom2dInt_GInter.hxx>
72 #include <IntRes2d_IntersectionPoint.hxx>
73 #include <IntRes2d_IntersectionSegment.hxx>
74 #include <GeomAPI_ProjectPointOnCurve.hxx>
75 #include <GeomAdaptor_Surface.hxx>
76 #include <Geom2dAdaptor_HCurve.hxx>
77 #include <GeomAdaptor_HSurface.hxx>
78 #include <GeomLib.hxx>
79 #include <GeomProjLib.hxx>
80 #include <TColgp_SequenceOfPnt.hxx>
81 #include <TColgp_Array1OfPnt2d.hxx>
82 #include <Bnd_Box.hxx>
83 #include <BndLib_Add3dCurve.hxx>
84 #include <BRepTools.hxx>
87 //=======================================================================
88 //function : CommonVertex
90 //=======================================================================
92 static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1,
95 TopoDS_Vertex V1[2],V2[2],V;
96 // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin
97 // TopExp::Vertices(E1,V1[0],V1[1]);
98 // TopExp::Vertices(E2,V2[0],V2[1]);
100 TopExp::Vertices(E1,V1[0],V1[1], Standard_True);
101 TopExp::Vertices(E2,V2[0],V2[1], Standard_True);
102 // The first edge is the current one, the second edge is the next one.
103 // We check last vertex of the first edge first.
104 // if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
105 // if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
106 if (V1[1].IsSame(V2[0]) || V1[1].IsSame(V2[1])) return V1[1];
107 if (V1[0].IsSame(V2[0]) || V1[0].IsSame(V2[1])) return V1[0];
108 // Modified by skv - Wed Dec 24 18:08:40 2003 OCC4455 End
112 //=======================================================================
115 //=======================================================================
117 static void Store (const TopoDS_Edge& E1,
118 const TopoDS_Edge& E2,
119 TopTools_ListOfShape& LV1,
120 TopTools_ListOfShape& LV2,
121 Handle(BRepAlgo_AsDes) AsDes,
124 //-------------------------------------------------------------
125 // Test si les points d intersection correspondent a des vertex
126 // existants.Sinon ajout dans les descendants des edges.
127 // Remarque a ce stade seulement les vertex d intersection sont
128 // dans les descendants.
129 //-------------------------------------------------------------
130 const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1);
131 const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2);
132 TopTools_ListOfShape NewVOnE1;
133 TopTools_ListOfShape NewVOnE2;
136 TopTools_ListIteratorOfListOfShape it, itLV1, itLV2;
138 TopAbs_Orientation O1,O2;
140 Standard_Boolean OnE1,OnE2;
142 for (itLV1.Initialize(LV1),itLV2.Initialize(LV2);
144 itLV1.Next() ,itLV2.Next()) {
146 TopoDS_Vertex V = TopoDS::Vertex(itLV1.Value());
148 U1 = BRep_Tool::Parameter(V,E1);
149 U2 = BRep_Tool::Parameter(V,E2);
150 O1 = V.Orientation();
151 O2 = itLV2.Value().Orientation();
152 P = BRep_Tool::Pnt(V);
153 OnE1 = OnE2 = Standard_False;
155 if (!VOnE1.IsEmpty()) {
156 //-----------------------------------------------------------------
157 // Recherche si le point d intersection correspond a un vertex de E1.
158 //-----------------------------------------------------------------
159 for (it.Initialize(VOnE1); it.More(); it.Next()) {
160 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
161 if (P.IsEqual(P1,Tol)) {
162 V = TopoDS::Vertex(it.Value());
164 OnE1 = Standard_True;
169 if (!VOnE2.IsEmpty()) {
171 //-----------------------------------------------------------------
172 // Recherche si le vertex trouve sur E1 n est pas deja sur E2.
173 //-----------------------------------------------------------------
174 for (it.Initialize(VOnE2); it.More(); it.Next()) {
175 if (it.Value().IsSame(V)) {
176 OnE2 = Standard_True;
182 for (it.Initialize(VOnE2); it.More(); it.Next()) {
183 //-----------------------------------------------------------------
184 // Recherche si le point d intersection correspond a un vertex de E2.
185 //-----------------------------------------------------------------
186 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
187 if (P.IsEqual(P2,Tol)) {
188 V = TopoDS::Vertex(it.Value());
190 OnE2 = Standard_True;
196 if (!V1.IsSame(V2)) {
197 //---------------------------------------------------------------
198 // Les deux vertex sont en fait les memes.
199 // on va remplacer V2 par V1.
200 // mis a jour des parametres des vertex sur les edges.
201 //---------------------------------------------------------------
204 const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
206 for (it.Initialize(EdgeWithV2); it.More(); it.Next()) {
207 EWE2 = TopoDS::Edge(it.Value());
208 TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL);
209 UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
211 // BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2);
212 aLocalShape = V1.Oriented(TopAbs_INTERNAL);
213 B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
214 // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
217 AsDes->Replace(V2,V1);
222 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
223 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
224 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
227 NewVOnE1.Append(V.Oriented(O1));
231 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
232 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
233 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
236 NewVOnE2.Append(V.Oriented(O2));
241 if (!OnE1 && !OnE2) {
243 char* name = new char[100];
244 sprintf(name,"VV_%d",NbNewVertices++);
250 if (!NewVOnE1.IsEmpty()) AsDes->Add(E1,NewVOnE1);
251 if (!NewVOnE2.IsEmpty()) AsDes->Add(E2,NewVOnE2);
255 //=======================================================================
256 //function : EdgeInter
258 //=======================================================================
260 static void EdgeInter(const TopoDS_Face& F,
261 const TopoDS_Edge& E1,
262 const TopoDS_Edge& E2,
263 const Handle(BRepAlgo_AsDes)& AsDes,
265 Standard_Boolean WithOri)
270 char* name = new char[100];
271 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
273 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
281 Standard_Real f[3],l[3];
282 Standard_Real MilTol2 = 1000*Tol*Tol;
283 Standard_Real TolDub = 1.e-7; // Faire un calcul plus malin !!! NYI
286 BRep_Tool::Range(E1, f[1], l[1]);
287 BRep_Tool::Range(E2, f[2], l[2]);
289 BRepAdaptor_Curve CE1(E1,F);
290 BRepAdaptor_Curve CE2(E2,F);
292 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
293 TopTools_ListOfShape LV1;
294 TopTools_ListOfShape LV2;
298 if (!TopExp::CommonVertex( E1, E2, CV ))
300 BRepLib::BuildCurve3d(E1);
301 BRepLib::BuildCurve3d(E2);
303 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
304 TolSum = Max( TolSum, 1.e-5 );
306 TColgp_SequenceOfPnt ResPoints;
307 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
309 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
313 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
314 TopoDS_Iterator iter( EI[ideg] );
317 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
318 DegPoint = BRep_Tool::Pnt(vdeg);
322 BRepAdaptor_Curve CEdeg( EI[ideg], F );
323 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
326 BRepAdaptor_Surface BAsurf(F);
327 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
328 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
329 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
330 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
331 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
332 for (i = 1; i <= Inter2d.NbPoints(); i++)
339 gp_Pnt2d P2d = Inter2d.Point(i).Value();
340 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
342 ResPoints.Append( P3d );
343 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
344 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
347 for (i = 1; i <= ResPoints.Length(); i++)
349 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
350 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
351 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
354 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
359 gp_Pnt P = ResPoints(i); //ponc1.Value();
360 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
361 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
362 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
363 gp_Pnt P1 = CE1.Value(aT1);
364 gp_Pnt P2 = CE2.Value(aT2);
365 Standard_Real dist1, dist2, dist3;
366 dist1 = P1.Distance(P);
367 dist2 = P2.Distance(P);
368 dist3 = P1.Distance(P2);
369 dist1 = Max( dist1, dist2 );
370 dist1 = Max( dist1, dist3 );
371 B.UpdateVertex( aNewVertex, dist1 );
374 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
376 cout << "hors borne"<<endl;
377 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
379 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
381 cout << "hors borne"<<endl;
382 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
384 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
386 cout << "Inter2d : Solution rejete "<<endl;
387 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
388 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
389 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
390 cout<<"MaxDist = "<<dist1<<endl;
393 //define the orientation of a new vertex
394 TopAbs_Orientation OO1 = TopAbs_REVERSED;
395 TopAbs_Orientation OO2 = TopAbs_REVERSED;
398 BRepAdaptor_Curve2d PCE1( E1, F );
399 BRepAdaptor_Curve2d PCE2( E2, F );
401 gp_Vec2d V1, V2, V1or, V2or;
402 PCE1.D1( aT1, P2d1, V1 );
403 PCE2.D1( aT2, P2d2, V2 );
404 V1or = V1; V2or = V2;
405 if (E1.Orientation() == TopAbs_REVERSED) V1or.Reverse();
406 if (E2.Orientation() == TopAbs_REVERSED) V2or.Reverse();
407 Standard_Real CrossProd = V2or ^ V1;
409 if (Abs(CrossProd) <= gp::Resolution())
410 cout<<endl<<"CrossProd = "<<CrossProd<<endl;
413 OO1 = TopAbs_FORWARD;
414 CrossProd = V1or ^ V2;
416 OO2 = TopAbs_FORWARD;
418 LV1.Append( aNewVertex.Oriented(OO1) );
419 LV2.Append( aNewVertex.Oriented(OO2) );
423 //----------------------------------
425 //---------------------------------
427 Standard_Real TolConf = Tol;
428 TopoDS_Vertex V1[2],V2[2];
429 TopExp::Vertices(E1,V1[0],V1[1]);
430 TopExp::Vertices(E2,V2[0],V2[1]);
433 for (j = 0; j < 2; j++) {
434 if (V1[j].IsNull()) continue;
435 for (Standard_Integer k = 0; k < 2; k++) {
436 if (V2[k].IsNull()) continue;
437 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
438 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
439 Standard_Real Dist = P1.Distance(P2);
440 if (Dist < TolConf) {
441 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
442 U1 = (j == 0) ? f[1] : l[1];
443 U2 = (k == 0) ? f[2] : l[2];
444 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
445 // Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 Begin
446 Standard_Real aTol = BRep_Tool::Tolerance(V1[j]);
448 if (!V1[j].IsSame(V2[k])) {
449 Standard_Real aTol2 = BRep_Tool::Tolerance(V2[k]);
451 aTol = Max(aTol, aTol2);
454 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,aTol);
455 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,aTol);
456 // B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
457 // B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
458 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
460 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
462 // Modified by skv - Thu Jan 22 18:16:01 2004 OCC4455 End
463 LV1.Prepend(V.Oriented(V1[j].Orientation()));
464 LV2.Prepend(V.Oriented(V2[k].Orientation()));
469 Standard_Boolean AffichPurge = Standard_False;
471 if ( !LV1.IsEmpty()) {
472 //----------------------------------
473 // Purge de l ensemble des vertex.
474 // il peut y avoir des doublons
475 //----------------------------------
476 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
478 Standard_Boolean Purge = Standard_True;
482 Purge = Standard_False;
483 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
484 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
486 it2LV1.Initialize(LV1);
488 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
489 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
490 // Modified by skv - Thu Jan 22 18:19:04 2004 OCC4455 Begin
491 // if (P1.IsEqual(P2,10*Tol)) {
494 aTol = Max(BRep_Tool::Tolerance(TopoDS::Vertex(it1LV1.Value())),
495 BRep_Tool::Tolerance(TopoDS::Vertex(it2LV1.Value())));
496 if (P1.IsEqual(P2,aTol)) {
497 // Modified by skv - Thu Jan 22 18:19:05 2004 OCC4455 End
500 if (AffichPurge) cout <<"Doublons purges dans EdgeInter."<<endl;
501 Purge = Standard_True;
511 //---------------------------------
512 // Stockage vertex en SD.
513 //---------------------------------
514 // Modified by skv - Tue Jan 13 15:14:30 2004 Begin
515 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
517 TolStore = Max(TolStore, 10.*Tol);
519 Store (E1,E2,LV1,LV2,AsDes,TolStore);
520 // Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
521 // Store (E1,E2,LV1,LV2,AsDes,Tol);
522 // Modified by skv - Tue Jan 13 15:14:30 2004 End
525 //=======================================================================
526 //function : EdgeInter
528 //=======================================================================
530 static void RefEdgeInter(const TopoDS_Face& F,
531 const TopoDS_Edge& E1,
532 const TopoDS_Edge& E2,
533 const Handle(BRepAlgo_AsDes)& AsDes,
535 Standard_Boolean WithOri,
541 char* name = new char[100];
542 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
544 sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
552 Standard_Real f[3],l[3];
553 Standard_Real MilTol2 = 1000*Tol*Tol;
554 Standard_Real TolDub = 1.e-7; // Faire un calcul plus malin !!! NYI
557 //BRep_Tool::Range(E1, f[1], l[1]);
558 //BRep_Tool::Range(E2, f[2], l[2]);
560 BRepAdaptor_Curve CE1(E1,F);
561 BRepAdaptor_Curve CE2(E2,F);
563 TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2;
564 TopTools_ListOfShape LV1;
565 TopTools_ListOfShape LV2;
568 BRepLib::BuildCurve3d(E1);
569 BRepLib::BuildCurve3d(E2);
571 Standard_Real TolSum = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
572 TolSum = Max( TolSum, 1.e-5 );
574 TColgp_SequenceOfPnt ResPoints;
575 TColStd_SequenceOfReal ResParamsOnE1, ResParamsOnE2;
577 Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2);
581 Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2;
582 TopoDS_Iterator iter( EI[ideg] );
585 const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value());
586 DegPoint = BRep_Tool::Pnt(vdeg);
590 BRepAdaptor_Curve CEdeg( EI[ideg], F );
591 DegPoint = CEdeg.Value( CEdeg.FirstParameter() );
594 BRepAdaptor_Surface BAsurf(F);
595 Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]);
596 Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]);
597 Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]);
598 Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]);
599 Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub );
600 for (i = 1; i <= Inter2d.NbPoints(); i++)
607 gp_Pnt2d P2d = Inter2d.Point(i).Value();
608 P3d = BAsurf.Value( P2d.X(), P2d.Y() );
610 ResPoints.Append( P3d );
611 ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() );
612 ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() );
615 for (i = 1; i <= ResPoints.Length(); i++)
617 Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter();
618 Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter();
619 if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2))
622 cout << "Inter2d : Solution rejected due to infinite parameter"<<endl;
627 gp_Pnt P = ResPoints(i); //ponc1.Value();
628 TopoDS_Vertex aNewVertex = BRepLib_MakeVertex(P);
629 B.UpdateVertex( aNewVertex, aT1, E1, Tol );
630 B.UpdateVertex( aNewVertex, aT2, E2, Tol );
631 gp_Pnt P1 = CE1.Value(aT1);
632 gp_Pnt P2 = CE2.Value(aT2);
633 Standard_Real dist1, dist2, dist3;
634 dist1 = P1.Distance(P);
635 dist2 = P2.Distance(P);
636 dist3 = P1.Distance(P2);
637 dist1 = Max( dist1, dist2 );
638 dist1 = Max( dist1, dist3 );
639 B.UpdateVertex( aNewVertex, dist1 );
642 if (aT1 < f[1]-Tol || aT1 > l[1]+Tol)
644 cout << "hors borne"<<endl;
645 cout<<"aT1 = "<<aT1<<", f[1] = "<<f[1]<<", l[1] = "<<l[1]<<endl;
647 if (aT2 < f[2]-Tol || aT2 > l[2]+Tol)
649 cout << "hors borne"<<endl;
650 cout<<"aT2 = "<<aT2<<", f[2] = "<<f[2]<<", l[2] = "<<l[2]<<endl;
652 if (P1.SquareDistance(P) > MilTol2 || P2.SquareDistance(P) > MilTol2 || P1.Distance(P2) > 2.*Tol)
654 cout << "Inter2d : Solution rejete "<<endl;
655 cout<<"P = "<<P.X()<<" "<<P.Y()<<" "<<P.Z()<<endl;
656 cout<<"P1 = "<<P1.X()<<" "<<P1.Y()<<" "<<P1.Z()<<endl;
657 cout<<"P2 = "<<P2.X()<<" "<<P2.Y()<<" "<<P2.Z()<<endl;
658 cout<<"MaxDist = "<<dist1<<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 cout<<endl<<"CrossProd = "<<CrossProd<<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 gp_Pnt P1 = BRep_Tool::Pnt(V1[j]);
705 gp_Pnt P2 = BRep_Tool::Pnt(V2[k]);
706 Standard_Real Dist = P1.Distance(P2);
707 if (Dist < TolConf) {
708 TopoDS_Vertex V = BRepLib_MakeVertex(P1);
709 U1 = (j == 0) ? f[1] : l[1];
710 U2 = (k == 0) ? f[2] : l[2];
711 TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL);
712 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol);
713 B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol);
714 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
716 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
718 LV1.Prepend(V.Oriented(V1[j].Orientation()));
719 LV2.Prepend(V.Oriented(V2[k].Orientation()));
724 Standard_Boolean AffichPurge = Standard_False;
726 if ( !LV1.IsEmpty()) {
727 //----------------------------------
728 // Purge de l ensemble des vertex.
729 // il peut y avoir des doublons
730 //----------------------------------
731 TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1;
733 Standard_Boolean Purge = Standard_True;
737 Purge = Standard_False;
738 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
739 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
741 it2LV1.Initialize(LV1);
743 P1 = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
744 P2 = BRep_Tool::Pnt(TopoDS::Vertex(it2LV1.Value()));
745 if (P1.IsEqual(P2,10*Tol)) {
748 if (AffichPurge) cout <<"Doublons purges dans EdgeInter."<<endl;
749 Purge = Standard_True;
759 //---------------------------------
760 // Stockage vertex en SD.
761 //---------------------------------
762 ////-----------------------------------------------------
763 if(LV1.Extent() > 1) {
764 //cout << "IFV - RefEdgeInter: remove vertex" << endl;
765 Standard_Real dmin = RealLast();
767 for (it1LV1.Initialize(LV1); it1LV1.More(); it1LV1.Next()) {
768 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(it1LV1.Value()));
769 Standard_Real d = P.SquareDistance(Pref);
772 Vmin = TopoDS::Vertex(it1LV1.Value());
775 for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2);
776 it1LV1.More(); it1LV1.Next(),it1LV2.Next()) {
777 if(!Vmin.IsSame(it1LV1.Value())) {
780 if(!it1LV1.More()) break;
785 ////-----------------------------------------------------
787 // Modified by skv - Tue Jan 13 15:14:30 2004 Begin
788 Standard_Real TolStore = BRep_Tool::Tolerance(E1) + BRep_Tool::Tolerance(E2);
790 TolStore = Max(TolStore, 10.*Tol);
792 Store (E1,E2,LV1,LV2,AsDes,TolStore);
793 // Store (E1,E2,LV1,LV2,AsDes,10.*Tol);
794 // Store (E1,E2,LV1,LV2,AsDes,Tol);
795 // Modified by skv - Tue Jan 13 15:14:30 2004 End
800 //======================================================================
801 //function : EvaluateMaxSegment
802 //purpose : return MaxSegment to pass in approximation
803 //======================================================================
805 static Standard_Integer evaluateMaxSegment(const Adaptor3d_CurveOnSurface& aCurveOnSurface)
807 Handle(Adaptor3d_HSurface) aSurf = aCurveOnSurface.GetSurface();
808 Handle(Adaptor2d_HCurve2d) aCurv2d = aCurveOnSurface.GetCurve();
810 Standard_Real aNbSKnots = 0, aNbC2dKnots = 0;
812 if (aSurf->GetType() == GeomAbs_BSplineSurface) {
813 Handle(Geom_BSplineSurface) aBSpline = aSurf->BSpline();
814 aNbSKnots = Max(aBSpline->NbUKnots(), aBSpline->NbVKnots());
816 if (aCurv2d->GetType() == GeomAbs_BSplineCurve) {
817 aNbC2dKnots = aCurv2d->NbKnots();
819 Standard_Integer aReturn = (Standard_Integer) ( 30 + Max(aNbSKnots, aNbC2dKnots) ) ;
824 //=======================================================================
825 //function : ExtendPCurve
827 //=======================================================================
829 static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve,
830 const Standard_Real anEf,
831 const Standard_Real anEl,
832 const Standard_Real a2Offset,
833 Handle(Geom2d_Curve)& NewPCurve)
836 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
837 NewPCurve = (*((Handle(Geom2d_TrimmedCurve)*)&NewPCurve))->BasisCurve();
839 Standard_Real FirstPar = NewPCurve->FirstParameter();
840 Standard_Real LastPar = NewPCurve->LastParameter();
842 if (NewPCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
843 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
845 if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve)))
847 Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve);
848 if (aBezier->NbPoles() == 2)
850 TColgp_Array1OfPnt2d thePoles(1,2);
851 aBezier->Poles(thePoles);
852 gp_Vec2d aVec(thePoles(1), thePoles(2));
853 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
854 return Standard_True;
857 else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve)))
859 Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve);
860 if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2)
862 TColgp_Array1OfPnt2d thePoles(1,2);
863 aBSpline->Poles(thePoles);
864 gp_Vec2d aVec(thePoles(1), thePoles(2));
865 NewPCurve = new Geom2d_Line(thePoles(1), aVec);
866 return Standard_True;
871 FirstPar = aPCurve->FirstParameter();
872 LastPar = aPCurve->LastParameter();
873 Handle(Geom2d_TrimmedCurve) aTrCurve =
874 new Geom2d_TrimmedCurve(aPCurve, FirstPar, LastPar);
876 // The curve is not prolonged on begin or end.
877 // Trying to prolong it adding a segment to its bound.
882 Handle(Geom2d_Line) aLin;
883 Handle(Geom2d_TrimmedCurve) aSegment;
884 Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
885 Standard_Real aTol = Precision::Confusion();
886 Standard_Real aDelta = Max(a2Offset, 1.);
888 if (FirstPar > anEf - a2Offset) {
889 aPCurve->D1(FirstPar, aPBnd, aVBnd);
890 aDBnd.SetXY(aVBnd.XY());
891 aPBeg = aPBnd.Translated(gp_Vec2d(-aDelta*aDBnd.XY()));
892 aLin = new Geom2d_Line(aPBeg, aDBnd);
893 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
895 if (!aCompCurve.Add(aSegment, aTol))
896 return Standard_False;
899 if (LastPar < anEl + a2Offset) {
900 aPCurve->D1(LastPar, aPBeg, aVBnd);
901 aDBnd.SetXY(aVBnd.XY());
902 aLin = new Geom2d_Line(aPBeg, aDBnd);
903 aSegment = new Geom2d_TrimmedCurve(aLin, 0, aDelta);
905 if (!aCompCurve.Add(aSegment, aTol))
906 return Standard_False;
909 NewPCurve = aCompCurve.BSplineCurve();
910 return Standard_True;
913 //=======================================================================
914 //function : ExtentEdge
916 //=======================================================================
918 // Modified by skv - Fri Dec 26 17:00:55 2003 OCC4455 Begin
919 //static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE)
920 static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real theOffset)
922 //BRepLib::BuildCurve3d(E);
924 TopoDS_Shape aLocalShape = E.EmptyCopied();
927 Standard_Real a2Offset = 2.*Abs(theOffset);
929 Standard_Integer i, j;
931 BRep_Tool::Range(E, anEf, anEl);
932 NE = TopoDS::Edge(aLocalShape);
933 // NE = TopoDS::Edge(E.EmptyCopied());
934 // Suffit pour les edges analytiques, pour le cas general reconstruire la
935 // la geometrie de l edge en recalculant l intersection des surfaces.
937 //BRepLib::BuildCurve3d(E);
939 Standard_Integer NbPCurves = 0;
940 Standard_Real FirstParOnPC = RealFirst(), LastParOnPC = RealLast();
941 Handle(Geom2d_Curve) MinPC;
942 Handle(Geom_Surface) MinSurf;
943 TopLoc_Location MinLoc;
945 BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves() );
946 for (; itr.More(); itr.Next())
948 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
949 Standard_Real FirstPar, LastPar;
950 if (CurveRep->IsCurveOnSurface())
953 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
954 FirstPar = theCurve->FirstParameter();
955 LastPar = theCurve->LastParameter();
957 if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) &&
958 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
960 Handle(Geom2d_Curve) NewPCurve;
961 if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve))
963 CurveRep->PCurve(NewPCurve);
964 FirstPar = NewPCurve->FirstParameter();
965 LastPar = NewPCurve->LastParameter();
966 if (CurveRep->IsCurveOnClosedSurface())
968 Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2();
969 if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve))
970 CurveRep->PCurve2(NewPCurve);
974 else if (theCurve->IsPeriodic())
976 Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5;
978 FirstPar = anEf - delta;
979 LastPar = anEl + delta;
981 else if (theCurve->IsClosed())
982 LastPar -= 0.05*(LastPar - FirstPar);
984 //check FirstPar and LastPar: the pcurve should be in its surface
985 theCurve = CurveRep->PCurve();
986 Handle(Geom_Surface) theSurf = CurveRep->Surface();
987 Standard_Real Umin, Umax, Vmin, Vmax;
988 theSurf->Bounds(Umin, Umax, Vmin, Vmax);
989 TColGeom2d_SequenceOfCurve BoundLines;
990 if (!Precision::IsInfinite(Vmin))
992 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ),
994 BoundLines.Append(aLine);
996 if (!Precision::IsInfinite(Umin))
998 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ),
1000 BoundLines.Append(aLine);
1002 if (!Precision::IsInfinite(Vmax))
1004 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ),
1005 gp_Dir2d( 1., 0. ));
1006 BoundLines.Append(aLine);
1008 if (!Precision::IsInfinite(Umax))
1010 Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ),
1011 gp_Dir2d( 0., 1. ));
1012 BoundLines.Append(aLine);
1015 TColStd_SequenceOfReal params;
1016 Geom2dInt_GInter IntCC;
1017 Geom2dAdaptor_Curve GAcurve(theCurve);
1018 for (i = 1; i <= BoundLines.Length(); i++)
1020 Geom2dAdaptor_Curve GAline( BoundLines(i) );
1021 IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion());
1024 for (j = 1; j <= IntCC.NbPoints(); j++)
1026 const IntRes2d_IntersectionPoint& ip = IntCC.Point(j);
1027 gp_Pnt2d aPoint = ip.Value();
1028 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1029 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1030 params.Append( ip.ParamOnFirst() );
1032 for (j = 1; j <= IntCC.NbSegments(); j++)
1034 const IntRes2d_IntersectionSegment& is = IntCC.Segment(j);
1035 if (is.HasFirstPoint())
1037 const IntRes2d_IntersectionPoint& ip = is.FirstPoint();
1038 gp_Pnt2d aPoint = ip.Value();
1039 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1040 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1041 params.Append( ip.ParamOnFirst() );
1043 if (is.HasLastPoint())
1045 const IntRes2d_IntersectionPoint& ip = is.LastPoint();
1046 gp_Pnt2d aPoint = ip.Value();
1047 if (aPoint.X() >= Umin && aPoint.X() <= Umax &&
1048 aPoint.Y() >= Vmin && aPoint.Y() <= Vmax)
1049 params.Append( ip.ParamOnFirst() );
1054 if (!params.IsEmpty())
1056 if (params.Length() == 1)
1058 gp_Pnt2d PntFirst = theCurve->Value(FirstPar);
1059 if (PntFirst.X() >= Umin && PntFirst.X() <= Umax &&
1060 PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax)
1062 if (LastPar > params(1))
1063 LastPar = params(1);
1065 else if (FirstPar < params(1))
1066 FirstPar = params(1);
1070 Standard_Real fpar = RealLast(), lpar = RealFirst();
1071 for (i = 1; i <= params.Length(); i++)
1073 if (params(i) < fpar)
1075 if (params(i) > lpar)
1078 if (FirstPar < fpar)
1084 //// end of check ////
1085 (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar );
1086 //gp_Pnt2d Pfirst = theCurve->Value(FirstPar);
1087 //gp_Pnt2d Plast = theCurve->Value(LastPar);
1088 //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast );
1090 //update FirstParOnPC and LastParOnPC
1091 if (FirstPar > FirstParOnPC)
1093 FirstParOnPC = FirstPar;
1096 MinLoc = CurveRep->Location();
1098 if (LastPar < LastParOnPC)
1100 LastParOnPC = LastPar;
1103 MinLoc = CurveRep->Location();
1109 Handle(Geom_Curve) C3d = BRep_Tool::Curve( NE, f, l );
1112 MinLoc = E.Location() * MinLoc;
1115 Standard_Real FirstPar = C3d->FirstParameter();
1116 Standard_Real LastPar = C3d->LastParameter();
1117 if (MinPC->IsClosed())
1122 else if (C3d->IsPeriodic())
1124 Standard_Real delta = (C3d->Period() - (l - f))*0.5;
1129 else if (C3d->IsClosed())
1135 GeomAPI_ProjectPointOnCurve Projector;
1136 if (!Precision::IsInfinite(FirstParOnPC))
1138 gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC);
1139 gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() );
1140 P1.Transform(MinLoc.Transformation());
1141 Projector.Init( P1, C3d );
1142 if (Projector.NbPoints() > 0)
1143 f = Projector.LowerDistanceParameter();
1146 cout<<"ProjectPointOnCurve not done"<<endl;
1149 if (!Precision::IsInfinite(LastParOnPC))
1151 gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC);
1152 gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() );
1153 P2.Transform(MinLoc.Transformation());
1154 Projector.Init( P2, C3d );
1155 if (Projector.NbPoints() > 0)
1156 l = Projector.LowerDistanceParameter();
1159 cout<<"ProjectPointOnCurve not done"<<endl;
1163 BB.Range( NE, f, l );
1164 if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
1165 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1169 MinSurf = Handle(Geom_Surface)::DownCast
1170 (MinSurf->Transformed(MinLoc.Transformation()));
1171 Standard_Real max_deviation = 0.;
1172 if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC))
1174 if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1176 Standard_Boolean IsLine = Standard_False;
1177 if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1178 IsLine = Standard_True;
1179 else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) ||
1180 MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface)))
1182 Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC);
1183 gp_Dir2d LineDir = theLine->Direction();
1184 if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() ))
1185 IsLine = Standard_True;
1189 gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.);
1190 gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y());
1191 gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y());
1192 gp_Vec aVec(P1, P2);
1193 C3d = new Geom_Line( P1, aVec );
1199 Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC );
1200 GeomAdaptor_Surface GAsurf( MinSurf );
1201 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d );
1202 Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
1203 Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
1204 Standard_Real /*max_deviation,*/ average_deviation;
1205 GeomAbs_Shape Continuity = GeomAbs_C1;
1206 Standard_Integer MaxDegree = 14;
1207 Standard_Integer MaxSegment = evaluateMaxSegment(ConS);
1208 GeomLib::BuildCurve3d(Precision::Confusion(),
1209 ConS, FirstParOnPC, LastParOnPC,
1210 C3d, max_deviation, average_deviation,
1211 Continuity, MaxDegree, MaxSegment);
1213 BB.UpdateEdge( NE, C3d, max_deviation );
1214 //BB.Range( NE, FirstParOnPC, LastParOnPC );
1215 Standard_Boolean ProjectionSuccess = Standard_True;
1217 //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1218 for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves());
1222 Handle( BRep_CurveRepresentation ) CurveRep = itr.Value();
1223 Standard_Real FirstPar, LastPar;
1224 if (CurveRep->IsCurveOnSurface())
1226 Handle(Geom2d_Curve) theCurve = CurveRep->PCurve();
1227 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1228 TopLoc_Location theLoc = CurveRep->Location();
1229 if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc)
1231 FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First();
1232 LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last();
1233 if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() ||
1234 Abs(LastPar - LastParOnPC) > Precision::PConfusion())
1236 theLoc = E.Location() * theLoc;
1237 theSurf = Handle(Geom_Surface)::DownCast
1238 (theSurf->Transformed(theLoc.Transformation()));
1240 if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) &&
1241 theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface)))
1243 gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction();
1244 if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) ||
1245 theDir.IsParallel(gp::DY2d(), Precision::Angular()))
1247 Standard_Real U1, U2, V1, V2;
1248 theSurf->Bounds(U1, U2, V1, V2);
1249 gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location();
1250 if (Abs(Origin.X()-U1) <= Precision::Confusion() ||
1251 Abs(Origin.X()-U2) <= Precision::Confusion() ||
1252 Abs(Origin.Y()-V1) <= Precision::Confusion() ||
1253 Abs(Origin.Y()-V2) <= Precision::Confusion())
1255 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1261 Handle(Geom2d_Curve) ProjPCurve =
1262 GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf );
1263 if (ProjPCurve.IsNull())
1264 ProjectionSuccess = Standard_False;
1266 CurveRep->PCurve( ProjPCurve );
1270 if (ProjectionSuccess)
1271 BB.Range( NE, FirstParOnPC, LastParOnPC );
1274 BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True );
1275 BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True );
1281 Standard_Real FirstPar = C3d->FirstParameter();
1282 Standard_Real LastPar = C3d->LastParameter();
1284 if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) &&
1285 (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset))
1287 Handle(Geom_TrimmedCurve) aTrCurve =
1288 new Geom_TrimmedCurve(C3d, FirstPar, LastPar);
1290 // The curve is not prolonged on begin or end.
1291 // Trying to prolong it adding a segment to its bound.
1296 Handle(Geom_Line) aLin;
1297 Handle(Geom_TrimmedCurve) aSegment;
1298 GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1);
1299 Standard_Real aTol = Precision::Confusion();
1300 Standard_Real aDelta = Max(a2Offset, 1.);
1302 if (FirstPar > anEf - a2Offset) {
1303 C3d->D1(FirstPar, aPBnd, aVBnd);
1304 aDBnd.SetXYZ(aVBnd.XYZ());
1305 aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ()));
1306 aLin = new Geom_Line(aPBeg, aDBnd);
1307 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1309 if (!aCompCurve.Add(aSegment, aTol))
1313 if (LastPar < anEl + a2Offset) {
1314 C3d->D1(LastPar, aPBeg, aVBnd);
1315 aDBnd.SetXYZ(aVBnd.XYZ());
1316 aLin = new Geom_Line(aPBeg, aDBnd);
1317 aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta);
1319 if (!aCompCurve.Add(aSegment, aTol))
1323 C3d = aCompCurve.BSplineCurve();
1324 FirstPar = C3d->FirstParameter();
1325 LastPar = C3d->LastParameter();
1326 BB.UpdateEdge(NE, C3d, Precision::Confusion());
1328 else if (C3d->IsPeriodic())
1330 Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5;
1332 FirstPar = anEf - delta;
1333 LastPar = anEl + delta;
1335 else if (C3d->IsClosed())
1336 LastPar -= 0.05*(LastPar - FirstPar);
1338 BB.Range( NE, FirstPar, LastPar );
1341 // Modified by skv - Fri Dec 26 17:00:57 2003 OCC4455 End
1344 //=======================================================================
1345 //function : UpdateVertex
1347 //=======================================================================
1349 static Standard_Boolean UpdateVertex(TopoDS_Vertex V,
1352 Standard_Real TolConf)
1354 BRepAdaptor_Curve OC(OE);
1355 BRepAdaptor_Curve NC(NE);
1356 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
1357 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
1359 Standard_Real U = 0.;
1363 Standard_Real ParTol = Precision::PConfusion();
1364 gp_Pnt P = BRep_Tool::Pnt(V);
1365 Standard_Boolean OK = Standard_False;
1367 if (P.Distance(OC.Value(Of)) < TolConf) {
1368 if (Of >= Nf + ParTol && Of <= Nl + ParTol && P.Distance(NC.Value(Of)) < TolConf) {
1373 if (P.Distance(OC.Value(Ol)) < TolConf) {
1374 if (Ol >= Nf + ParTol && Ol <= Nl + ParTol && P.Distance(NC.Value(Ol)) < TolConf) {
1381 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
1382 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
1383 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
1384 aLocalShape = V.Oriented(TopAbs_INTERNAL);
1385 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
1386 U,NE,BRep_Tool::Tolerance(NE));
1387 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
1388 // U,NE,BRep_Tool::Tolerance(NE));
1393 //=======================================================================
1394 //function : Compute
1396 //=======================================================================
1398 void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes,
1399 const TopoDS_Face& F,
1400 const TopTools_MapOfShape& NewEdges,
1401 const Standard_Real Tol)
1408 //Do not intersect the edges of face
1409 TopTools_MapOfShape EdgesOfFace;
1410 TopExp_Explorer Explo( F, TopAbs_EDGE );
1411 for (; Explo.More(); Explo.Next())
1412 EdgesOfFace.Add( Explo.Current() );
1414 //-----------------------------------------------------------
1415 // calcul des intersections2d sur les faces touchees par les
1417 //---------------------------------------------------------
1418 TopTools_ListIteratorOfListOfShape it1LE ;
1419 TopTools_ListIteratorOfListOfShape it2LE ;
1421 //-----------------------------------------------
1422 // Intersection des edges 2 a 2.
1423 //-----------------------------------------------
1424 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
1425 TopoDS_Vertex V1,V2;
1426 Standard_Integer j, i = 1;
1428 for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) {
1429 const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value());
1431 it2LE.Initialize(LE);
1433 while (j < i && it2LE.More()) {
1434 const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value());
1435 //--------------------------------------------------------------
1436 // Intersectionns des Nouvelles edges obtenues par intersection
1437 // entre elles et avec les edges de restictions
1438 //------------------------------------------------------
1439 if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) &&
1440 (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) {
1441 TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD);
1442 EdgeInter(TopoDS::Face(aLocalShape),E1,E2,AsDes,Tol,Standard_True);
1443 // EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True);
1452 //=======================================================================
1453 //function : ConnexIntByInt
1455 //=======================================================================
1457 // Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin
1458 // Add another parameter: offset value.
1459 void BRepOffset_Inter2d::ConnexIntByInt
1460 (const TopoDS_Face& FI,
1461 BRepOffset_Offset& OFI,
1462 TopTools_DataMapOfShapeShape& MES,
1463 const TopTools_DataMapOfShapeShape& Build,
1464 const Handle(BRepAlgo_AsDes)& AsDes,
1465 const Standard_Real Offset,
1466 const Standard_Real Tol)
1467 // Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End
1470 TopTools_DataMapOfShapeListOfShape MVE;
1471 BRepOffset_Tool::MapVertexEdges(FI,MVE);
1473 //---------------------
1474 // Extension des edges.
1475 //---------------------
1477 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(MVE);
1478 for ( ; it.More(); it.Next()) {
1479 const TopTools_ListOfShape& L = it.Value();
1480 Standard_Boolean YaBuild = 0;
1481 TopTools_ListIteratorOfListOfShape itL(L);
1482 for (; itL.More(); itL.Next()) {
1483 YaBuild = Build.IsBound(itL.Value());
1487 for (itL.Initialize(L); itL.More(); itL.Next()) {
1488 const TopoDS_Edge& EI = TopoDS::Edge(itL.Value());
1489 TopoDS_Shape aLocalShape = OFI.Generated(EI);
1490 const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape);
1491 // const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI));
1492 if (!MES.IsBound(OE) && !Build.IsBound(EI)) {
1493 // Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin
1494 // ExtentEdge(OE,NE);
1495 ExtentEdge(OE,NE, Offset);
1496 // Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End
1503 TopoDS_Face FIO = TopoDS::Face(OFI.Face());
1504 if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO));
1506 TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
1507 for (; exp.More(); exp.Next()) {
1508 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
1509 BRepTools_WireExplorer wexp;
1510 Standard_Boolean end = Standard_False ;
1511 TopoDS_Edge FirstE,CurE,NextE;
1513 TopoDS_Shape aLocalWire = W .Oriented(TopAbs_FORWARD);
1514 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
1515 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
1516 // wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)),
1517 // TopoDS::Face(FI.Oriented(TopAbs_FORWARD)));
1518 CurE = FirstE = wexp.Current();
1522 NextE = wexp.Current();
1525 NextE = FirstE; end = Standard_True;
1527 if (CurE.IsSame(NextE)) continue;
1530 TopoDS_Vertex Vref = CommonVertex(CurE, NextE);
1531 gp_Pnt Pref = BRep_Tool::Pnt(Vref);
1534 TopoDS_Shape aLocalShape = OFI.Generated(CurE);
1535 TopoDS_Edge CEO = TopoDS::Edge(aLocalShape);
1536 aLocalShape = OFI.Generated(NextE);
1537 TopoDS_Edge NEO = TopoDS::Edge(aLocalShape);
1538 // TopoDS_Edge CEO = TopoDS::Edge(OFI.Generated(CurE));
1539 // TopoDS_Edge NEO = TopoDS::Edge(OFI.Generated(NextE));
1540 //------------------------------------------
1541 //traitement Inter des images de CurE NextE.
1542 //------------------------------------------
1543 TopTools_ListOfShape LV1,LV2;
1544 Standard_Boolean DoInter = 1;
1545 TopoDS_Shape NE1,NE2;
1547 if (Build.IsBound(CurE) && Build.IsBound(NextE)) {
1551 else if (Build.IsBound(CurE) && MES.IsBound(NEO)) {
1555 else if (Build.IsBound(NextE) && MES.IsBound(CEO)) {
1563 //------------------------------------
1564 // NE1,NE2 can be a compound of Edges.
1565 //------------------------------------
1566 TopExp_Explorer Exp1,Exp2;
1567 for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) {
1568 for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) {
1569 RefEdgeInter(FIO,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()),
1570 AsDes,Tol,Standard_True/*Standard_False*/, Pref);
1575 if (MES.IsBound(CEO)) {
1576 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1577 UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol);
1578 AsDes->Add (MES(CEO),V);
1580 else if (MES.IsBound(NEO)) {
1581 TopoDS_Vertex V = CommonVertex(CEO,NEO);
1582 UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol);
1583 AsDes->Add (MES(NEO),V);