1 // Created on: 1996-04-23
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1996-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 <BRepFeat.ixx>
25 //#include <BRepAlgo_Cut.hxx>
27 #include <BRepBuilderAPI.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <TopExp_Explorer.hxx>
30 #include <TopTools_MapOfShape.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRep_Builder.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_TrimmedCurve.hxx>
35 #include <Geom2d_TrimmedCurve.hxx>
36 #include <Extrema_ExtPC.hxx>
37 #include <GeomAdaptor_Curve.hxx>
38 #include <BRepLProp.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Face.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Shell.hxx>
44 #include <TopoDS_Solid.hxx>
45 #include <Precision.hxx>
46 #include <GCPnts_QuasiUniformDeflection.hxx>
47 #include <BRepTopAdaptor_FClass2d.hxx>
48 #include <Geom2dAdaptor_Curve.hxx>
49 #include <GeomProjLib.hxx>
50 #include <gp_Vec2d.hxx>
51 #include <BRepTools.hxx>
52 #include <Geom_Surface.hxx>
53 #include <Bnd_Box.hxx>
54 #include <BRepBndLib.hxx>
55 #include <BRepLib_MakeFace.hxx>
56 #include <Geom_RectangularTrimmedSurface.hxx>
57 #include <Geom_Plane.hxx>
58 #include <Geom_CylindricalSurface.hxx>
59 #include <Geom_ConicalSurface.hxx>
60 #include <LocOpe_CSIntersector.hxx>
61 #include <LocOpe_PntFace.hxx>
62 #include <LocOpe_BuildShape.hxx>
64 #include <TColGeom_SequenceOfCurve.hxx>
69 #define NECHANTBARYC 11
71 //=======================================================================
72 //function : SampleEdges
74 //=======================================================================
76 void BRepFeat::SampleEdges(const TopoDS_Shape& theShape,
77 TColgp_SequenceOfPnt& theSeq)
79 LocOpe::SampleEdges(theShape,theSeq);
84 //=======================================================================
85 //function : Barycenter
86 //purpose : Calcul du barycentre des edges d'un shape
87 //=======================================================================
89 void BRepFeat::Barycenter(const TopoDS_Shape& S,
92 TopTools_MapOfShape theMap;
93 TopExp_Explorer exp(S,TopAbs_EDGE);
96 Standard_Real f,l,prm;
98 Standard_Integer i, nbp= 0;
100 for (; exp.More(); exp.Next()) {
101 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
102 if (!theMap.Add(edg)) {
105 if (!BRep_Tool::Degenerated(edg)) {
106 C = BRep_Tool::Curve(edg,Loc,f,l);
107 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
108 for (i=1;i<NECHANTBARYC; i++) {
109 prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
110 Bar += C->Value(prm).XYZ();
116 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
117 if (theMap.Add(exp.Current())) {
118 Bar += (BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))).XYZ();
123 Bar.Divide((Standard_Real)nbp);
128 //=======================================================================
129 //function : ParametricBarycenter
130 //purpose : Calcul du barycentre "parametrique" shape sur une courbe
131 //=======================================================================
133 Standard_Real BRepFeat::ParametricBarycenter(const TopoDS_Shape& S,
134 const Handle(Geom_Curve)& CC)
136 TopTools_MapOfShape theMap;
137 TopExp_Explorer exp(S,TopAbs_EDGE);
139 Handle(Geom_Curve) C;
140 Standard_Real f,l,prm;
141 Standard_Integer i, nbp= 0;
142 GeomAdaptor_Curve TheCurve(CC);
144 extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter());
145 Standard_Real parbar = 0;
147 for (; exp.More(); exp.Next()) {
148 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
149 if (!theMap.Add(edg)) {
152 if (!BRep_Tool::Degenerated(edg)) {
153 C = BRep_Tool::Curve(edg,Loc,f,l);
154 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
155 for (i=1;i<NECHANTBARYC; i++) {
156 prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
157 gp_Pnt pone = C->Value(prm);
158 // On projette sur CC
160 if (extpc.IsDone() && extpc.NbExt() >= 1) {
161 Standard_Real Dist2Min = extpc.SquareDistance(1);
162 Standard_Integer kmin = 1;
163 for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
164 Standard_Real Dist2 = extpc.SquareDistance(k);
165 if (Dist2 < Dist2Min) {
171 Standard_Real prmp = extpc.Point(kmin).Parameter();
178 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
179 if (theMap.Add(exp.Current())) {
180 gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
181 // On projette sur CC
183 if (extpc.IsDone() && extpc.NbExt() >= 1) {
184 Standard_Real Dist2Min = extpc.SquareDistance(1);
185 Standard_Integer kmin = 1;
186 for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
187 Standard_Real Dist2 = extpc.SquareDistance(k);
188 if (Dist2 < Dist2Min) {
198 parbar /=((Standard_Real)nbp);
203 //=======================================================================
204 //function : ParametricBarycenter
205 //purpose : Calcul du barycentre "parametrique" shape sur une courbe
206 //=======================================================================
208 void BRepFeat::ParametricMinMax(const TopoDS_Shape& S,
209 const Handle(Geom_Curve)& CC,
210 Standard_Real& prmin,
211 Standard_Real& prmax,
212 Standard_Real& prbmin,
213 Standard_Real& prbmax,
214 Standard_Boolean& flag,
215 const Standard_Boolean Ori)
217 LocOpe_CSIntersector ASI(S);
218 TColGeom_SequenceOfCurve scur;
221 if(ASI.IsDone() && ASI.NbPoints(1) >=1) {
223 prmin = Min(ASI.Point(1,1).Parameter(),
224 ASI.Point(1, ASI.NbPoints(1)).Parameter());
225 prmax = Max(ASI.Point(1,1).Parameter(),
226 ASI.Point(1, ASI.NbPoints(1)).Parameter());
229 TopAbs_Orientation Ori = ASI.Point(1,1).Orientation();
230 if (Ori == TopAbs_FORWARD) {
231 prmin = ASI.Point(1,1).Parameter();
232 prmax = ASI.Point(1, ASI.NbPoints(1)).Parameter();
235 prmax = ASI.Point(1,1).Parameter();
236 prmin = ASI.Point(1, ASI.NbPoints(1)).Parameter();
239 flag = Standard_True;
244 flag = Standard_False;
247 TopTools_MapOfShape theMap;
248 TopExp_Explorer exp(S,TopAbs_EDGE);
250 Handle(Geom_Curve) C;
251 Standard_Real f,l,prm;
252 // Standard_Integer i, nbp= 0;
254 GeomAdaptor_Curve TheCurve(CC);
256 extpc.Initialize(TheCurve,CC->FirstParameter(),CC->LastParameter());
258 prbmax = RealFirst();
259 for (; exp.More(); exp.Next()) {
260 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
261 if (!theMap.Add(edg)) {
264 if (!BRep_Tool::Degenerated(edg)) {
265 C = BRep_Tool::Curve(edg,Loc,f,l);
266 C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
267 for (i=1;i<NECHANTBARYC; i++) {
268 prm = ((NECHANTBARYC-i)*f + i*l)/NECHANTBARYC;
269 gp_Pnt pone = C->Value(prm);
270 // On projette sur CC
272 if (extpc.IsDone() && extpc.NbExt() >= 1) {
273 Standard_Real Dist2Min = extpc.SquareDistance(1);
274 Standard_Integer kmin = 1;
275 for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
276 Standard_Real Dist2 = extpc.SquareDistance(k);
277 if (Dist2 < Dist2Min) {
282 Standard_Real prmp = extpc.Point(kmin).Parameter();
283 if (prmp <= prbmin) {
286 if (prmp >= prbmax) {
294 for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
295 if (theMap.Add(exp.Current())) {
296 gp_Pnt pone = BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()));
297 // On projette sur CC
299 if (extpc.IsDone() && extpc.NbExt() >= 1) {
300 Standard_Real Dist2Min = extpc.SquareDistance(1);
301 Standard_Integer kmin = 1;
302 for (Standard_Integer k=2; k<=extpc.NbExt(); k++) {
303 Standard_Real Dist2 = extpc.SquareDistance(k);
304 if (Dist2 < Dist2Min) {
309 Standard_Real prmp = extpc.Point(kmin).Parameter();
310 if (prmp <= prbmin) {
313 if (prmp >= prbmax) {
324 //=======================================================================
327 //=======================================================================
329 static Standard_Boolean IsIn (BRepTopAdaptor_FClass2d& FC,
330 Geom2dAdaptor_Curve AC)
332 Standard_Real Def = 100*Precision::Confusion();
333 GCPnts_QuasiUniformDeflection QU(AC,Def);
335 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
336 gp_Pnt2d P = AC.Value(QU.Parameter(i));
337 if (FC.Perform(P, Standard_False) == TopAbs_OUT) {
338 return Standard_False;
341 return Standard_True;
345 //=======================================================================
346 //function : PutInBoundsU
347 //purpose : Recadre la courbe 2d dans les bounds de la face
348 //=======================================================================
353 static void PutInBoundsU (Standard_Real umin,
356 Standard_Real period,
359 Handle(Geom2d_Curve)& C2d)
361 gp_Pnt2d Pf = C2d->Value(f);
362 gp_Pnt2d Pl = C2d->Value(l);
363 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
364 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
365 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
366 Standard_Real du = 0.;
367 if (minC< umin - eps) {
368 du = (int((umin - minC)/period) + 1)*period;
370 if (minC > umax + eps) {
371 du = -(int((minC - umax)/period) + 1)*period;
376 minC += du; maxC += du;
378 // Ajuste au mieux la courbe dans le domaine.
379 if (maxC > umax +100*eps) {
380 Standard_Real d1 = maxC - umax;
381 Standard_Real d2 = umin - minC + period;
382 if (d2 < d1) du =-period;
391 //=======================================================================
392 //function : PutInBoundsU
393 //purpose : Recadre la courbe 2d dans les bounds de la face
394 //=======================================================================
399 static void PutInBoundsV (Standard_Real vmin,
402 Standard_Real period,
405 Handle(Geom2d_Curve)& C2d)
407 gp_Pnt2d Pf = C2d->Value(f);
408 gp_Pnt2d Pl = C2d->Value(l);
409 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
410 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
411 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
412 Standard_Real dv = 0.;
413 if (minC< vmin - eps) {
414 dv = (int((vmin - minC)/period) + 1)*period;
416 if (minC > vmax + eps) {
417 dv = -(int((minC - vmax)/period) + 1)*period;
422 minC += dv; maxC += dv;
424 // Ajuste au mieux la courbe dans le domaine.
425 if (maxC > vmax +100*eps) {
426 Standard_Real d1 = maxC - vmax;
427 Standard_Real d2 = vmin - minC + period;
428 if (d2 < d1) dv =-period;
437 //=======================================================================
438 //function : IsInside
440 //=======================================================================
443 Standard_Boolean BRepFeat::IsInside(const TopoDS_Face& F1,
444 const TopoDS_Face& F2)
447 exp.Init(F1, TopAbs_EDGE);
449 Standard_Real umin,umax,vmin,vmax, uperiod=0, vperiod=0;
450 Standard_Integer flagu = 0, flagv = 0;
451 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
452 Handle (Geom_Surface) S = BRep_Tool::Surface(F2);
453 // Standard_Real periodu, periodv;
454 BRepTools::UVBounds(F2,umin,umax,vmin,vmax);
456 if (S->IsUPeriodic()) {
458 uperiod = S->UPeriod();
461 if (S->IsVPeriodic()) {
463 vperiod = S->VPeriod();
465 TopoDS_Shape aLocalShape = F2.Oriented(TopAbs_FORWARD);
466 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalShape),Precision::Confusion());
467 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(F2.Oriented(TopAbs_FORWARD)),
468 // Precision::Confusion());
469 for(; exp.More(); exp.Next()) {
471 Handle(Geom_Curve) C0 = BRep_Tool::Curve(TopoDS::Edge(exp.Current()),f1,l1);
472 Handle(Geom2d_Curve) C = GeomProjLib::Curve2d(C0,f1,l1,S);
473 TopoDS_Edge E = TopoDS::Edge(exp.Current());
474 if(flagu == 1 || flagv == 1) {
475 Standard_Real eps = BRep_Tool::Tolerance(E);
476 BRep_Tool::Range(E,f1,l1);
477 if(flagu == 1) PutInBoundsU(umin, umax, eps, uperiod, f1, l1, C);
478 if(flagv == 1) PutInBoundsV(vmin, vmax, eps, vperiod, f1, l1, C);
480 Geom2dAdaptor_Curve AC(C,f1,l1);
482 return Standard_False;
485 return Standard_True;
490 //=======================================================================
491 //function : FaceUntil
493 //=======================================================================
496 void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase,
500 BRepBndLib::Add(Sbase,B);
501 Standard_Real c[6], bnd;
502 B.Get(c[0],c[2],c[4],c[1],c[3],c[5]);
504 for(Standard_Integer i = 1 ; i < 6; i++) {
505 if(c[i] > bnd) bnd = c[i];
510 Handle(Geom_Surface) s = BRep_Tool::Surface(FUntil);
511 Handle(Standard_Type) styp = s->DynamicType();
512 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
513 s = Handle(Geom_RectangularTrimmedSurface)::DownCast(s)->BasisSurface();
514 styp = s->DynamicType();
516 Handle(Geom_RectangularTrimmedSurface) str;
517 if (styp == STANDARD_TYPE(Geom_Plane)) {
518 str = new Geom_RectangularTrimmedSurface
519 (s, bnd, -bnd, bnd, -bnd, Standard_True, Standard_True);
521 else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) {
522 str = new Geom_RectangularTrimmedSurface
523 (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True);
525 else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) {
526 str = new Geom_RectangularTrimmedSurface
527 (s, 0., 2.*M_PI, bnd, -bnd, Standard_True, Standard_True);
534 FUntil = BRepLib_MakeFace(str, Precision::Confusion());
539 //=======================================================================
542 //=======================================================================
544 TopoDS_Solid BRepFeat::Tool(const TopoDS_Shape& SRef,
545 const TopoDS_Face& Fac,
546 const TopAbs_Orientation Orf)
548 TopTools_ListOfShape lfaces;
549 // for (TopExp_Explorer exp(SRef,TopAbs_FACE); exp.More(); exp.Next()) {
550 TopExp_Explorer exp(SRef,TopAbs_FACE) ;
551 for ( ; exp.More(); exp.Next()) {
552 if (exp.Current().ShapeType() == TopAbs_FACE) {
553 lfaces.Append(exp.Current());
557 LocOpe_BuildShape bs(lfaces);
558 const TopoDS_Shape& Res = bs.Shape();
560 if (Res.ShapeType() == TopAbs_SHELL) {
562 Sh = TopoDS::Shell(Res);
564 else if (Res.ShapeType() == TopAbs_SOLID) {
565 exp.Init(Res,TopAbs_SHELL);
566 Sh = TopoDS::Shell(exp.Current());
579 Sh.Orientation(TopAbs_FORWARD);
581 TopAbs_Orientation orient = TopAbs_FORWARD;
583 for (exp.Init(Sh,TopAbs_FACE); exp.More(); exp.Next()) {
584 if (exp.Current().IsSame(Fac)) {
585 orient = exp.Current().Orientation();
590 Standard_Boolean reverse = Standard_False;
591 if ((orient == Fac.Orientation() && Orf == TopAbs_REVERSED) ||
592 (orient != Fac.Orientation() && Orf == TopAbs_FORWARD)) {
593 reverse = Standard_True;
608 //=======================================================================
610 //purpose : Print the error Description of a StatusError on a stream.
611 //=======================================================================
613 Standard_OStream& BRepFeat::Print(const BRepFeat_StatusError se,
620 case BRepFeat_BadDirect :
621 s << "Directions must be opposite";
623 case BRepFeat_BadIntersect :
624 s << "Intersection failure";
626 case BRepFeat_EmptyBaryCurve :
627 s << "Empty BaryCurve";
629 case BRepFeat_EmptyCutResult :
630 s << "Failure in Cut : Empty resulting shape";
632 case BRepFeat_FalseSide :
633 s << "Verify plane and wire orientation";
635 case BRepFeat_IncDirection :
636 s << "Incoherent Direction for shapes From and Until";
638 case BRepFeat_IncSlidFace :
639 s << "Sliding face not in Base shape";
641 case BRepFeat_IncParameter :
642 s << "Incoherent Parameter : shape Until before shape From";
644 case BRepFeat_IncTypes :
645 s << "Invalid option for faces From and Until : 1 Support and 1 not";
647 case BRepFeat_IntervalOverlap :
648 s << "Shapes From and Until overlap";
650 case BRepFeat_InvFirstShape :
651 s << "Invalid First shape : more than 1 face";
653 case BRepFeat_InvOption :
654 s << "Invalid option";
656 case BRepFeat_InvShape :
657 s << "Invalid shape";
659 case BRepFeat_LocOpeNotDone :
660 s << "Local Operation not done";
662 case BRepFeat_LocOpeInvNotDone :
663 s << "Local Operation : intersection line conflict";
665 case BRepFeat_NoExtFace :
666 s << "No Extreme faces";
668 case BRepFeat_NoFaceProf :
669 s << "No Face Profile";
671 case BRepFeat_NoGluer :
672 s << "Gluer Failure";
674 case BRepFeat_NoIntersectF :
675 s << "No intersection between Feature and shape From";
677 case BRepFeat_NoIntersectU :
678 s << "No intersection between Feature and shape Until";
680 case BRepFeat_NoParts :
681 s << "No parts of tool kept";
683 case BRepFeat_NoProjPt :
684 s << "No projection points";
686 case BRepFeat_NotInitialized :
687 s << "Fields not initialized";
689 case BRepFeat_NotYetImplemented :
690 s << "Not yet implemented";
692 case BRepFeat_NullRealTool :
693 s << "Real Tool : Null DPrism";
695 case BRepFeat_NullToolF :
696 s << "Null Tool : Invalid type for shape Form";
698 case BRepFeat_NullToolU :
699 s << "Null Tool : Invalid type for shape Until";