0023024: Update headers of OCCT files
[occt.git] / src / BRepFill / BRepFill_TrimSurfaceTool.cxx
CommitLineData
b311480e 1// Created on: 1994-10-21
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
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.
10//
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.
13//
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.
20
7fd59977 21
22
23#include <stdio.h>
24
25#include <BRepFill_TrimSurfaceTool.ixx>
26
27#include <Precision.hxx>
28
29#include <Adaptor3d_SurfaceOfRevolution.hxx>
30#include <AppParCurves_MultiCurve.hxx>
31#include <BRepFill_ComputeCLine.hxx>
32#include <BRepFill_MultiLine.hxx>
33#include <BRepIntCurveSurface_Inter.hxx>
34#include <BRepFill_ApproxSeewing.hxx>
35#include <BRep_Tool.hxx>
36#include <ElCLib.hxx>
37#include <BSplCLib.hxx>
38#include <PLib.hxx>
39#include <gp.hxx>
40#include <gp_Sphere.hxx>
41#include <gp_Cone.hxx>
42#include <gp_Torus.hxx>
43#include <gp_Cylinder.hxx>
44#include <Geom2dInt_GInter.hxx>
45#include <Geom2dAPI_ProjectPointOnCurve.hxx>
46#include <Geom2dAdaptor_Curve.hxx>
47#include <Geom2d_BSplineCurve.hxx>
48#include <Geom2d_TrimmedCurve.hxx>
49#include <GeomAdaptor_Surface.hxx>
50#include <GeomAdaptor_HCurve.hxx>
51#include <Geom_Plane.hxx>
52#include <Geom_SurfaceOfRevolution.hxx>
53#include <Geom_BSplineCurve.hxx>
54#include <Geom_TrimmedCurve.hxx>
55#include <GeomProjLib.hxx>
56#include <IntRes2d_IntersectionPoint.hxx>
57#include <IntRes2d_IntersectionSegment.hxx>
58#include <Precision.hxx>
59#include <StdFail_NotDone.hxx>
60#include <Standard_NotImplemented.hxx>
61#include <TColgp_Array1OfPnt.hxx>
62#include <TColStd_Array1OfReal.hxx>
63#include <TColStd_Array1OfInteger.hxx>
64#include <TopAbs_State.hxx>
65#include <TopExp.hxx>
66#include <TopoDS.hxx>
67#include <TopoDS_Vertex.hxx>
68
69#ifdef DRAW
70#include <DrawTrSurf.hxx>
71#include <DBRep.hxx>
72#endif
73#ifdef DEB
74static Standard_Boolean Affich = Standard_False;
75static Standard_Integer NBCALL = 1;
76#endif
77
78//=======================================================================
79//function : BRepFill_TrimSurfaceTool
0d969553
Y
80//purpose : Initialisation with two neighbor faces
81// Edge1 and Edge2 are parallel edges corresponding
82// to minimum iso on F1 and F2 respectively.
83// ie Edge1 is Umin or VMin on F1.
84// Inv1 and Inv2 show if Edge1 and Edge2 are
85// returned parallel.
7fd59977 86//=======================================================================
87
88BRepFill_TrimSurfaceTool::BRepFill_TrimSurfaceTool
89(const Handle(Geom2d_Curve)& Bis,
90 const TopoDS_Face& Face1,
91 const TopoDS_Face& Face2,
92 const TopoDS_Edge& Edge1,
93 const TopoDS_Edge& Edge2,
94 const Standard_Boolean Inv1,
95 const Standard_Boolean Inv2 ) :
96myFace1(Face1),
97myFace2(Face2),
98myEdge1(Edge1),
99myEdge2(Edge2),
100myInv1(Inv1),
101myInv2(Inv2),
102myBis (Bis)
103{
104#ifdef DEB
105 if ( Affich) {
106 cout << " ---------->TrimSurfaceTool : NBCALL = " << NBCALL << endl;
107
108#ifdef DRAW
109 char name[256];
110
111 sprintf(name,"FACE1_%d",NBCALL);
112 DBRep::Set(name,myFace1);
113
114 sprintf(name,"FACE2_%d",NBCALL);
115 DBRep::Set(name,myFace2);
116
117 sprintf(name,"EDGE1_%d",NBCALL);
118 DBRep::Set(name,myEdge1);
119
120 sprintf(name,"EDGE2_%d",NBCALL);
121 DBRep::Set(name,myEdge2);
122
123 sprintf(name,"BISSEC_%d",NBCALL);
124 DrawTrSurf::Set(name,myBis);
125#endif
126 NBCALL++;
127 }
128#endif
129}
130
131
132//=======================================================================
133//function : Bubble
0d969553 134//purpose : Order the sequence of points by increasing x.
7fd59977 135//=======================================================================
136
137static void Bubble(TColgp_SequenceOfPnt& Seq)
138{
139 Standard_Boolean Invert = Standard_True;
140 Standard_Integer NbPoints = Seq.Length();
141 while (Invert) {
142 Invert = Standard_False;
143 for ( Standard_Integer i = 1; i < NbPoints; i++) {
144 gp_Pnt P1 = Seq.Value(i);
145 gp_Pnt P2 = Seq.Value(i+1);
146 if (P2.X()<P1.X()) {
147 Seq.Exchange(i,i+1);
148 Invert = Standard_True;
149 }
150 }
151 }
152}
153
154
155//=======================================================================
156//function : EvalPhase
157//purpose :
158//=======================================================================
159
160static Standard_Real EvalPhase(const TopoDS_Edge& Edge,
161 const TopoDS_Face& Face,
162 const GeomAdaptor_Surface& GAS,
163 const gp_Ax3& Axis)
164{
165 gp_Pnt2d PE1,PE2,PF1,PF2;
166 Standard_Real VDeg;
167#ifndef DEB
168 Standard_Real V = 0.;
169#else
170 Standard_Real V;
171#endif
172 BRep_Tool::UVPoints(Edge,Face,PE1,PE2);
173 VDeg = PE1.Y();
174 TopExp_Explorer Exp(Face,TopAbs_EDGE);
175 for (; Exp.More(); Exp.Next()) {
176 if ( !TopoDS::Edge(Exp.Current()).IsSame(Edge)) {
177 BRep_Tool::UVPoints(TopoDS::Edge(Exp.Current()),Face,PF1,PF2);
178 V = ( Abs(PF1.Y() - VDeg) > Abs(PF2.Y() - VDeg)) ? PF1.Y() : PF2.Y();
179 break;
180 }
181 }
182 gp_Pnt P = GAS.Value(0., V);
183
184 if ( gp_Vec(Axis.Location(), P).Dot(Axis.XDirection()) < 0.)
c6541a0c 185 return M_PI;
7fd59977 186 else
187 return 0.;
188}
189
190
191//=======================================================================
192//function : EvalParameters
193//purpose :
194//=======================================================================
195
196static void EvalParameters(const TopoDS_Edge& Edge,
197 const TopoDS_Face& Face,
198 const Handle(Geom2d_Curve)& Bis ,
199 TColgp_SequenceOfPnt& Seq )
200{
201 Standard_Boolean Degener = BRep_Tool::Degenerated(Edge);
0d969553 202 // return curves 3d associated to edges.
7fd59977 203 TopLoc_Location L;
204 Standard_Real f,l;
205
206 Handle(Geom_TrimmedCurve) CT;
207 Handle(Geom_Plane) Plane = new Geom_Plane(0,0,1,0);
208
209 Geom2dInt_GInter Intersector;
210
211 Standard_Integer NbPoints, NbSegments;
212 Standard_Real U1, U2;
213 gp_Pnt P;//,PSeq;
214
215// Standard_Real Tol = Precision::Intersection();
216 // modified by NIZHNY-EAP Wed Dec 22 15:00:51 1999 ___BEGIN___
217 Standard_Real Tol = 1.e-6; // BRepFill_Precision();
218 Standard_Real TolC = 0.;
219
220 if ( !Degener) {
221 Handle(Geom_Curve) C = BRep_Tool::Curve(Edge,L,f,l);
222 CT = new Geom_TrimmedCurve(C,f,l);
223 CT->Transform(L.Transformation());
0d969553 224 // projection of 3d curves in the plane xOy
7fd59977 225 Handle(Geom2d_Curve) C2d = GeomProjLib::Curve2d(CT,Plane);
226
227 Geom2dAdaptor_Curve AC(C2d);
228 Geom2dAdaptor_Curve ABis(Bis);
229
230 Intersector = Geom2dInt_GInter(ABis, AC, TolC, Tol);
231
232 if ( !Intersector.IsDone()) {
233 StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
234 }
235
236 NbPoints = Intersector.NbPoints();
237
238 if (NbPoints < 1) {
239 // try to elongate curves and enlarge tolerance
240
241 // don't do it rightaway from the beginning in order not to get
242 // extra solutions those would cause *Exception*: incoherent intersection
243
244 GeomAbs_CurveType CType = AC.GetType(), BisType = ABis.GetType();
245 Standard_Boolean canElongateC = !(CType == GeomAbs_BezierCurve ||
246 CType == GeomAbs_BSplineCurve ||
247 CType == GeomAbs_OtherCurve);
248 Standard_Boolean canElongateBis = !(BisType == GeomAbs_BezierCurve ||
249 BisType == GeomAbs_BSplineCurve ||
250 BisType == GeomAbs_OtherCurve);
251
252 Handle(Geom2d_TrimmedCurve) TBis = Handle(Geom2d_TrimmedCurve)::DownCast(Bis);
253 Handle(Geom2d_TrimmedCurve) TC2d = Handle(Geom2d_TrimmedCurve)::DownCast(C2d);
254
255 if (canElongateC) {
256 TC2d->SetTrim(TC2d->FirstParameter() - Tol, TC2d->LastParameter() + Tol);
257 AC.Load(TC2d);
258 }
259 if (canElongateBis) {
260 TBis->SetTrim(TBis->FirstParameter() - Tol, TBis->LastParameter() + Tol);
261 ABis.Load(TBis);
262 }
263 Intersector = Geom2dInt_GInter(ABis, AC, TolC, Tol*10);
264
265 if ( !Intersector.IsDone()) {
266 StdFail_NotDone::Raise("BRepFill_TrimSurfaceTool::IntersectWith");
267 }
268
269 NbPoints = Intersector.NbPoints();
270 }
271 // modified by NIZHNY-EAP Wed Dec 22 15:00:56 1999 ___END___
272 if (NbPoints > 0) {
273
274 for ( Standard_Integer i = 1; i <= NbPoints; i++) {
275 U1 = Intersector.Point(i).ParamOnFirst();
276 U2 = Intersector.Point(i).ParamOnSecond();
277 P = gp_Pnt(U1,U2,0.);
278 Seq.Append(P);
279 }
280 }
281
282 NbSegments = Intersector.NbSegments();
283
284 if (NbSegments > 0) {
285#ifdef DEB
286 cout << " IntersectWith : " << NbSegments
0d969553 287 << " Segments of intersection" << endl;
7fd59977 288#endif
289 IntRes2d_IntersectionSegment Seg;
290 for ( Standard_Integer i = 1; i <= NbSegments; i++) {
291 Seg = Intersector.Segment(i);
292 U1 = Seg.FirstPoint().ParamOnFirst();
293 U1 += Seg.LastPoint().ParamOnFirst();
294 U1 /= 2.;
295 U2 = Seg.FirstPoint().ParamOnSecond();
296 U2 += Seg.LastPoint().ParamOnSecond();
297 U2 /= 2.;
298 P = gp_Pnt(U1,U2,0.);
299 Seq.Append(P);
300 }
301 }
0d969553 302 // Order the sequence by increasing parameter on the bissectrice.
7fd59977 303 Bubble( Seq);
304
305// modified by NIZHNY-EAP Fri Dec 24 18:47:24 1999 ___BEGIN___
306 // Remove double points
307 gp_Pnt P1, P2;
308 for ( Standard_Integer i = 1; i < NbPoints; i++) {
309 P1 = Seq.Value(i);
310 P2 = Seq.Value(i+1);
311 if ( P2.X()-P1.X() < Tol ) {
312// cout<<"REMOVE "<<P1.X()<<endl;
313 Seq.Remove(i--);
314 NbPoints--;
315 }
316 }
317// modified by NIZHNY-EAP Fri Dec 24 18:47:28 1999 ___END___
318 }
319 else {
0d969553
Y
320 // the edge is degenerated : the point and it is found if it is
321 // on the bissectrice.
7fd59977 322
323 gp_Pnt P3d = BRep_Tool::Pnt( TopExp::FirstVertex(Edge));
324 gp_Pnt2d P2d( P3d.X(), P3d.Y());
325
326 Standard_Real UBis = Bis->FirstParameter();
327 gp_Pnt2d PBis = Bis->Value( UBis);
328
329// modified by NIZHNY-EAP Wed Jan 12 11:41:30 2000 ___BEGIN___
330 // inside gp_Pnt2d::Distance
331 // Infinite * Infinite => Exception: DefaultNumericError
332 // Case encounered: UBis < Precision::Infinite()
333 // but PBis.X() > Precision::Infinite()
334 if (Precision::IsPositiveInfinite(Abs(PBis.X())) ||
335 Precision::IsPositiveInfinite(Abs(PBis.Y())) ||
336 PBis.Distance(P2d) > Tol) {
337// modified by NIZHNY-EAP Wed Jan 12 11:41:40 2000 ___END___
338 UBis = Bis->LastParameter();
339 if (UBis >= Precision::Infinite()) return;
340 PBis = Bis->Value( UBis);
341 if ( PBis.Distance(P2d) > Tol) return;
342 }
343
0d969553 344 // evaluate parameter intersection.
7fd59977 345 Handle(Geom_Surface) GS = BRep_Tool::Surface(Face);
346 GeomAdaptor_Surface GAS(GS);
347
348 gp_Ax3 Axis;
349 Standard_Real Phase = 0.;
350
351 switch ( GAS.GetType()) {
352
353 case GeomAbs_Sphere:
354 Axis = GAS.Sphere().Position(); break;
355 case GeomAbs_Cone: {
356 //----------------------------------------------------------
0d969553 357 // if myFace1 is not at the same side of the apex as the point
c6541a0c 358 // of parameter 0 0 on the cone => phase = M_PI.
7fd59977 359 //----------------------------------------------------------
360 Axis = GAS.Cone().Position();
361 Phase = EvalPhase(Edge,Face,GAS,Axis);
362 break;
363 }
364 case GeomAbs_Torus:
365 Axis = GAS.Torus().Position(); break;
366 case GeomAbs_Cylinder:
367 Axis = GAS.Cylinder().Position(); break;
368 case GeomAbs_SurfaceOfRevolution: {
369 //----------------------------------------------------------
0d969553 370 // if myFace1 is not at the same side of the apex as the point
c6541a0c 371 // of parameter 0 0 on the cone => phase = M_PI.
7fd59977 372 //----------------------------------------------------------
373 Handle(Geom_SurfaceOfRevolution) GSRev =
374 Handle(Geom_SurfaceOfRevolution)::DownCast(GS);
375 Handle(GeomAdaptor_HCurve) HC =
376 new GeomAdaptor_HCurve(GSRev->BasisCurve());
377 Adaptor3d_SurfaceOfRevolution ASRev(HC,GAS.AxeOfRevolution());
378 Axis = ASRev.Axis();
379 Phase = EvalPhase(Edge,Face,GAS,Axis);
380 break;
381 }
382 default:
383 Standard_NotImplemented::Raise(" BRepFill_TrimSurfaceTool");
384 }
385
386 gp_Vec2d D12d = Bis->DN(UBis,1);
387 gp_Vec D1( D12d.X(), D12d.Y(), 0.);
388
389 Standard_Real U = Axis.XDirection().
390 AngleWithRef(D1,Axis.XDirection()^Axis.YDirection());
391 U += Phase;
c6541a0c 392 if ( U < 0.) U += 2*M_PI;
7fd59977 393
394 P = gp_Pnt(Bis->FirstParameter(), U, 0.);
395 Seq.Append(P);
396 }
397}
398
399
400//=======================================================================
401//function : IntersectWith
402//purpose :
403//=======================================================================
404
405void BRepFill_TrimSurfaceTool::IntersectWith
406(const TopoDS_Edge& EdgeOnF1,
407 const TopoDS_Edge& EdgeOnF2,
408 TColgp_SequenceOfPnt& Points )
409const
410{
411 Points.Clear();
412 TColgp_SequenceOfPnt Points2;
413
414 EvalParameters(EdgeOnF1, myFace1, myBis, Points);
415 EvalParameters(EdgeOnF2, myFace2, myBis, Points2);
416
417 StdFail_NotDone_Raise_if
418 ( Points.Length() != Points2.Length(),
419 "BRepFill_TrimSurfaceTool::IntersectWith: incoherent intersection");
420
421 gp_Pnt PSeq;
422 Standard_Integer NbPoints = Points.Length();
423 for ( Standard_Integer i = 1; i <= NbPoints; i++) {
424 PSeq = Points(i);
425 PSeq.SetZ((Points2.Value(i)).Y());
426 Points.SetValue(i,PSeq);
427// cout<<"BisPar "<<PSeq.X()<<endl;
428 }
429}
430
431
432//=======================================================================
433//function : IsOnFace
434//purpose :
435//=======================================================================
436
437Standard_Boolean BRepFill_TrimSurfaceTool::IsOnFace
438(const gp_Pnt2d& Point) const
439{
440 gp_Pnt P( Point.X(), Point.Y(), 0.);
441 gp_Lin Line( P, gp::DZ());
442
443 BRepIntCurveSurface_Inter Inter;
444
445 // eval if is on face 1
446// modified by NIZHNY-EAP Fri Jan 21 09:49:09 2000 ___BEGIN___
447 Inter.Init(myFace1, Line, 1e-6);//Precision::PConfusion());
448 if (Inter.More()) return Standard_True;
449
450 // eval if is on face 2
451 Inter.Init(myFace2, Line, 1e-6);//Precision::PConfusion());
452 return Inter.More();
453// modified by NIZHNY-EAP Fri Jan 21 09:49:14 2000 ___END___
454}
455
456
457//=======================================================================
458//function : ProjOn
459//purpose :
460//=======================================================================
461
462Standard_Real BRepFill_TrimSurfaceTool::ProjOn(const gp_Pnt2d& Point,
463 const TopoDS_Edge& Edge) const
464{
465 TopLoc_Location L;
466 Standard_Real f,l;
467
468
469
470 Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge,L,f,l);
471 Handle(Geom_TrimmedCurve) CT = new Geom_TrimmedCurve(C1,f,l);
472 CT->Transform(L.Transformation());
473
0d969553 474 // projection of curves 3d in the plane xOy
7fd59977 475 Handle(Geom_Plane) Plane = new Geom_Plane(0,0,1,0);
476 Handle(Geom2d_Curve) C2d = GeomProjLib::Curve2d(CT,Plane);
477
0d969553 478 // evaluate the projection of the point on the curve.
7fd59977 479 Geom2dAPI_ProjectPointOnCurve Projector(Point, C2d);
480#ifdef DEB
481 Standard_Real Dist =
482#endif
483 Projector.LowerDistance();
484#ifdef DEB
485 if ( Dist > Precision::Confusion() ) {
486 cout << " *** WARNING TrimSurfaceTool: *** " << endl;
0d969553 487 cout << " --> the point is not on the edge" <<endl;
7fd59977 488 cout << " distance = " << Dist << endl;
489 }
490#endif
491
492 Standard_Real U = Projector.LowerDistanceParameter();
493 return U;
494}
495
496
497//=======================================================================
498//function : Project
499//purpose :
500//=======================================================================
501
502void BRepFill_TrimSurfaceTool::Project
503(const Standard_Real U1,
504 const Standard_Real U2,
505 Handle(Geom_Curve)& Curve,
506 Handle(Geom2d_Curve)& PCurve1,
507 Handle(Geom2d_Curve)& PCurve2,
508 GeomAbs_Shape& Cont) const
509{
510 Standard_Integer Deg1, Deg2;
511 Deg1 = Deg2 = 8;
512
513 Handle(Geom2d_TrimmedCurve) CT =
514 new Geom2d_TrimmedCurve(myBis,U1,U2);
515 BRepFill_MultiLine ML(myFace1,myFace2,
516 myEdge1,myEdge2,myInv1,myInv2,CT);
517
518 Cont = ML.Continuity();
519
520 if ( ML.IsParticularCase()) {
521 ML.Curves(Curve,PCurve1,PCurve2);
522 }
523 else {
524 BRepFill_ApproxSeewing AppSeew(ML);
525
526 Curve = AppSeew.Curve();
527 PCurve1 = AppSeew.CurveOnF1();
528 PCurve2 = AppSeew.CurveOnF2();
529 }
530}