1 // Created on: 1995-04-24
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <BRepFill_TrimEdgeTool.ixx>
24 #include <BRep_Tool.hxx>
25 #include <Bisector_BisecAna.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_TrimmedCurve.hxx>
28 #include <Geom2d_CartesianPoint.hxx>
29 #include <Geom_Curve.hxx>
30 #include <GeomProjLib.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
33 #include <Geom2dInt_GInter.hxx>
35 #include <TopLoc_Location.hxx>
37 #include <Precision.hxx>
38 #include <IntRes2d_IntersectionPoint.hxx>
39 #include <IntRes2d_IntersectionSegment.hxx>
41 #include <StdFail_NotDone.hxx>
44 #include <DrawTrSurf.hxx>
46 static Standard_Boolean Affich = Standard_False;
50 //=======================================================================
51 //function : SimpleExpression
53 //=======================================================================
55 static void SimpleExpression (const Bisector_Bisec& B,
56 Handle(Geom2d_Curve)& Bis)
60 Handle(Standard_Type) BT = Bis->DynamicType();
61 if (BT == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
62 Handle(Geom2d_TrimmedCurve) TrBis
63 = Handle(Geom2d_TrimmedCurve)::DownCast(Bis);
64 Handle(Geom2d_Curve) BasBis = TrBis->BasisCurve();
65 BT = BasBis->DynamicType();
66 if (BT == STANDARD_TYPE(Bisector_BisecAna)) {
67 Bis = Handle(Bisector_BisecAna)::DownCast(BasBis)->Geom2dCurve();
68 Bis = new Geom2d_TrimmedCurve (Bis,
69 TrBis->FirstParameter(),
70 TrBis->LastParameter());
76 //=======================================================================
77 //function : BRepFill_TrimEdgeTool
79 //=======================================================================
81 BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool()
86 //=======================================================================
87 //function : BRepFill_TrimEdgeTool
89 //=======================================================================
91 BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool
92 (const Bisector_Bisec& Bisec,
93 const Handle(Geom2d_Geometry)& S1,
94 const Handle(Geom2d_Geometry)& S2,
95 const Standard_Real Offset) :
99 isPoint1 = (S1->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint));
100 isPoint2 = (S2->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint));
102 // return geometries of shapes.
103 // Standard_Real f,l;
105 myP1 = Handle(Geom2d_Point)::DownCast(S1)->Pnt2d();
108 myC1 = Handle(Geom2d_Curve)::DownCast(S1);
112 char* myC1name = "myC1";
113 DrawTrSurf::Set(myC1name,myC1);
114 // DrawTrSurf::Set("myC1",myC1);
119 myP2 = Handle(Geom2d_Point)::DownCast(S2)->Pnt2d();
122 myC2 = Handle(Geom2d_Curve)::DownCast(S2);
125 char* myC2name = "myC2";
126 DrawTrSurf::Set(myC2name,myC2);
127 // DrawTrSurf::Set("myC2",myC2);
131 // return the simple expression of the bissectrice
132 Handle(Geom2d_Curve) Bis;
133 SimpleExpression(myBisec, Bis);
134 myBis = Geom2dAdaptor_Curve(Bis);
137 char* myBisname = "myBis";
138 DrawTrSurf::Set(myBisname,Bis);
144 //=======================================================================
146 //purpose : Order the sequence of points by increasing x.
147 //=======================================================================
149 static void Bubble(TColgp_SequenceOfPnt& Seq)
151 Standard_Boolean Invert = Standard_True;
152 Standard_Integer NbPoints = Seq.Length();
154 Invert = Standard_False;
155 for ( Standard_Integer i = 1; i < NbPoints; i++) {
156 gp_Pnt P1 = Seq.Value(i);
157 gp_Pnt P2 = Seq.Value(i+1);
160 Invert = Standard_True;
167 //=======================================================================
168 //function : EvalParameters
170 //=======================================================================
172 static void EvalParameters(const Geom2dAdaptor_Curve& Bis,
173 const Geom2dAdaptor_Curve& AC,
174 TColgp_SequenceOfPnt& Params)
176 Geom2dInt_GInter Intersector;
177 Standard_Real Tol = Precision::Confusion();
178 // Standard_Real TolC = 1.e-9;
180 Geom2dAdaptor_Curve CBis(Bis);
181 Geom2dAdaptor_Curve CAC (AC);
183 //Intersector = Geom2dInt_GInter(CBis, CAC, TolC, Tol);
184 Intersector = Geom2dInt_GInter(CAC, CBis, Tol, Tol);
186 Standard_Integer NbPoints, NbSegments;
187 Standard_Real U1, U2;
190 if ( !Intersector.IsDone()) {
191 StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
194 NbPoints = Intersector.NbPoints();
197 for ( Standard_Integer i = 1; i <= NbPoints; i++) {
198 U1 = Intersector.Point(i).ParamOnSecond();
199 U2 = Intersector.Point(i).ParamOnFirst();
200 P = gp_Pnt(U1,U2,0.);
206 NbSegments = Intersector.NbSegments();
208 if (NbSegments > 0) {
209 IntRes2d_IntersectionSegment Seg;
210 for ( Standard_Integer i = 1; i <= NbSegments; i++) {
211 Seg = Intersector.Segment(i);
212 U1 = Seg.FirstPoint().ParamOnSecond();
213 Standard_Real Ulast = Seg.LastPoint().ParamOnSecond();
214 if ( Abs(U1 - CBis.FirstParameter()) <= Tol &&
215 Abs(Ulast - CBis.LastParameter()) <= Tol ) {
216 P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.);
218 P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.);
222 U1 += Seg.LastPoint().ParamOnSecond();
224 U2 = Seg.FirstPoint().ParamOnFirst();
225 U2 += Seg.LastPoint().ParamOnFirst();
227 P = gp_Pnt(U1,U2,0.);
233 // Order the sequence by growing parameter on the bissectrice.
237 static void EvalParametersBis(const Geom2dAdaptor_Curve& Bis,
238 const Geom2dAdaptor_Curve& AC,
239 TColgp_SequenceOfPnt& Params,
240 const Standard_Real Tol)
242 Geom2dInt_GInter Intersector;
243 Standard_Real TolC = Tol;
245 Geom2dAdaptor_Curve CBis(Bis);
246 Geom2dAdaptor_Curve CAC (AC);
248 Intersector = Geom2dInt_GInter(CAC, CBis, TolC, Tol);
250 Standard_Integer NbPoints, NbSegments;
251 Standard_Real U1, U2;
254 if ( !Intersector.IsDone()) {
255 StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
258 NbPoints = Intersector.NbPoints();
261 for ( Standard_Integer i = 1; i <= NbPoints; i++) {
262 U1 = Intersector.Point(i).ParamOnSecond();
263 U2 = Intersector.Point(i).ParamOnFirst();
264 P = gp_Pnt(U1,U2,0.);
270 NbSegments = Intersector.NbSegments();
272 if (NbSegments > 0) {
273 IntRes2d_IntersectionSegment Seg;
274 for ( Standard_Integer i = 1; i <= NbSegments; i++) {
275 Seg = Intersector.Segment(i);
276 U1 = Seg.FirstPoint().ParamOnSecond();
277 Standard_Real Ulast = Seg.LastPoint().ParamOnSecond();
278 if ( Abs(U1 - CBis.FirstParameter()) <= Tol &&
279 Abs(Ulast - CBis.LastParameter()) <= Tol ) {
280 P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.);
282 P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.);
286 U1 += Seg.LastPoint().ParamOnSecond();
288 U2 = Seg.FirstPoint().ParamOnFirst();
289 U2 += Seg.LastPoint().ParamOnFirst();
291 P = gp_Pnt(U1,U2,0.);
297 // Order the sequence by parameter growing on the bissectrice.
302 //=======================================================================
303 //function : IntersectWith
305 //=======================================================================
307 void BRepFill_TrimEdgeTool::IntersectWith(const TopoDS_Edge& Edge1,
308 const TopoDS_Edge& Edge2,
309 TColgp_SequenceOfPnt& Params)
313 // return curves associated to edges.
316 Handle(Geom_Surface) Surf;
318 Handle(Geom2d_Curve) C1;
319 BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l);
320 Geom2dAdaptor_Curve AC1(C1,f,l);
322 Handle(Geom2d_Curve) C2;
323 BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f,l);
324 Geom2dAdaptor_Curve AC2(C2,f,l);
328 f = AC1.FirstParameter();
329 l = AC1.LastParameter();
330 char* CURVE1name = "CURVE1";
331 DrawTrSurf::Set(CURVE1name, new Geom2d_TrimmedCurve(C1,f,l));
332 f = AC2.FirstParameter();
333 l = AC2.LastParameter();
334 char* CURVE2name = "CURVE2";
335 DrawTrSurf::Set(CURVE2name, new Geom2d_TrimmedCurve(C2,f,l));
336 f = myBis.FirstParameter();
337 l = myBis.LastParameter();
338 char* bisname = "BIS";
339 DrawTrSurf::Set(bisname, new Geom2d_TrimmedCurve(myBis.Curve(),f,l));
340 char* Edge1name = "E1";
341 DBRep::Set(Edge1name, Edge1);
342 char* Edge2name = "E2";
343 DBRep::Set(Edge2name, Edge2);
348 // Calculate intersection
349 TColgp_SequenceOfPnt Points2;
352 EvalParameters (myBis,AC1,Params);
353 EvalParameters (myBis,AC2,Points2);
356 Standard_Integer SeanceDeRattrapage=0;
357 Standard_Real TolInit= 1.e-9;
358 Standard_Integer nn = 7;
360 if((AC1.GetType() != GeomAbs_Circle && AC1.GetType() != GeomAbs_Line) ||
361 (AC2.GetType() != GeomAbs_Circle && AC2.GetType() != GeomAbs_Line)) {
367 while ( SeanceDeRattrapage < nn // TolInit <= 0.01
368 && ( Points2.Length() != Params.Length() ||
369 (Points2.Length() == 0 && Params.Length() == 0) ) ) {
372 cout << "BRepFill_TrimEdgeTool: incoherent intersection. Try with a greater tolerance" << endl;
380 EvalParametersBis(myBis,AC1,Params,TolInit);
381 EvalParametersBis(myBis,AC2,Points2,TolInit);
382 SeanceDeRattrapage++;
386 if(SeanceDeRattrapage != 0) cout << "SeanceDeRattrapage = " << SeanceDeRattrapage << endl;
387 if(SeanceDeRattrapage == nn) {
388 cout << "BRepFill_TrimEdgeTool: incoherent intersection" << endl;
393 if(Params.Length() == 0 && Points2.Length() == 1) {
395 //cout << "Params.Length() == 0 && Points2.Length() == 1" << endl;
397 Standard_Real tBis = Points2(1).X();
398 gp_Pnt2d PBis = myBis.Value(tBis);
400 Standard_Real t = AC1.FirstParameter();
401 gp_Pnt2d PC = AC1.Value(t);
402 dmin = PC.SquareDistance(PBis);
403 gp_Pnt P(tBis, t, 0.);
406 t = AC1.LastParameter();
408 if(dmin > PC.SquareDistance(PBis)) {
410 Params.SetValue(1,P);
413 else if(Params.Length() == 1 && Points2.Length() == 0) {
415 //cout << "Params.Length() == 1 && Points2.Length() == 0" << endl;
417 Standard_Real tBis = Params(1).X();
418 gp_Pnt2d PBis = myBis.Value(tBis);
420 Standard_Real t = AC2.FirstParameter();
421 gp_Pnt2d PC = AC2.Value(t);
422 dmin = PC.SquareDistance(PBis);
423 gp_Pnt P(tBis, t, 0.);
426 t = AC2.LastParameter();
428 if(dmin > PC.SquareDistance(PBis)) {
430 Points2.SetValue(1,P);
434 // small manipulation to remove incorrect intersections:
435 // return only common intersections (same parameter
436 // on the bissectrice.).
437 // The tolerance can be eventually changed.
440 Standard_Real Tol = 4 * 100 * Precision::PConfusion();
441 Standard_Integer i = 1;
442 Standard_Integer NbPoints = Params.Length();
444 if(NbPoints == 1 && Points2.Length() == 1) {
445 //cout << "NbPoints == 1 && Points2.Length() == 1" << endl;
446 for ( i = 1; i <= NbPoints; i++) {
448 PSeq.SetZ((Points2.Value(i)).Y());
449 Params.SetValue(i,PSeq);
455 while ( i <= Min( Params.Length(), Points2.Length())) {
458 Standard_Real P1xP2x=Abs( P1.X() - P2.X());
460 if ( P1xP2x > Tol ) {
462 cout << "BRepFill_TrimEdgeTool: no same parameter on the bissectrice" << endl;
466 cout << "BRepFill_TrimEdgeTool: Continue somehow" << endl;
471 if ( P1.X() < P2.X()) Params.Remove(i);
472 else Points2.Remove(i);
478 if ( Params.Length() > Points2.Length()) {
479 Params.Remove(Points2.Length()+1, Params.Length());
481 else if ( Params.Length() < Points2.Length()) {
482 Points2.Remove(Params.Length()+1, Points2.Length());
485 NbPoints = Params.Length();
486 for ( i = 1; i <= NbPoints; i++) {
488 PSeq.SetZ((Points2.Value(i)).Y());
489 Params.SetValue(i,PSeq);
493 //=======================================================================
494 //function : AddOrConfuse
495 //purpose : the first or the last point of the bissectrice is on the
496 // parallel if it was not found in the intersections,
497 // it is projected on parallel lines and added in the parameters
498 //=======================================================================
500 void BRepFill_TrimEdgeTool::AddOrConfuse(const Standard_Boolean Start,
501 const TopoDS_Edge& Edge1,
502 const TopoDS_Edge& Edge2,
503 TColgp_SequenceOfPnt& Params)
506 Standard_Boolean ToProj = Standard_True;
508 Standard_Real Tol = 10*Precision::Confusion();
510 // return curves associated to edges.
513 Handle(Geom_Surface) Surf;
515 Handle(Geom2d_Curve) C1;
516 BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l);
517 Geom2dAdaptor_Curve AC1(C1,f,l);
520 if (Start) PBis = myBis.Value(myBis.FirstParameter());
521 else PBis = myBis.Value(myBis.LastParameter ());
523 // Test if the end of the bissectrice is in the set of intersection points.
524 if (!Params.IsEmpty()) {
526 if (Start) P = AC1.Value(Params.First().Y());
527 else P = AC1.Value(Params.Last ().Y());
528 ToProj = !PBis.IsEqual(P,Tol);
533 cout << " project extremity bissectrice on parallel."<<endl;
536 // Project point on parallels and add in Params
539 Handle(Geom2d_Curve) C2;
540 BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f2,l2);
542 Geom2dAPI_ProjectPointOnCurve Projector1(PBis,C1,f,l);
543 Geom2dAPI_ProjectPointOnCurve Projector2(PBis,C2,f2,l2);
545 if (Projector1.NbPoints() == 0) {
547 cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
551 if (!Projector1.NearestPoint().IsEqual(PBis,Tol)) {
553 cout <<"Incorrect solution in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
557 if (Projector2.NbPoints() == 0) {
559 cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
563 if (!Projector2.NearestPoint().IsEqual(PBis,Tol)) {
565 cout <<" Mauvaisesolution dans BRepFill_TrimEdgeTool::AddOrConfuse"<<endl;
570 Projector1.LowerDistanceParameter(),
571 Projector2.LowerDistanceParameter());
573 PInt.SetX (myBis.FirstParameter());
574 Params.Prepend(PInt);
577 PInt.SetX (myBis.LastParameter());
583 //=======================================================================
584 //function : IsInside
586 //=======================================================================
588 Standard_Boolean BRepFill_TrimEdgeTool::IsInside(const gp_Pnt2d& P) const
590 // Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 Begin
591 // Standard_Real Dist;
592 Standard_Real Dist = RealLast();
593 // Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 End
595 Dist = P.Distance(myP1);
597 Dist = P.Distance(myP2);
599 Geom2dAPI_ProjectPointOnCurve Projector(P,myC1);
600 if (Projector.NbPoints() > 0) {
601 Dist = Projector.LowerDistance();
603 // Modified by Sergey KHROMOV - Fri Sep 27 11:43:43 2002 Begin
605 // gp_Pnt2d PF = myC1->Value(myC1->FirstParameter());
606 // gp_Pnt2d PL = myC1->Value(myC1->LastParameter());
607 // Dist = Min (P.Distance(PF),P.Distance(PL));
610 // Check of distances between P and first and last point of the first curve
611 // should be performed in any case, despite of the results of projection.
612 gp_Pnt2d PF = myC1->Value(myC1->FirstParameter());
613 gp_Pnt2d PL = myC1->Value(myC1->LastParameter());
614 Standard_Real aDistMin = Min (P.Distance(PF),P.Distance(PL));
618 // Modified by Sergey KHROMOV - Fri Sep 27 11:43:44 2002 End
621 // return (Dist < Abs(myOffset);
622 // return (Dist < Abs(myOffset) + Precision::Confusion());
623 return (Dist < Abs(myOffset) - Precision::Confusion());