1 // Created on: 1996-07-12
2 // Created by: Stagiaire Mary FABIEN
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 <BRepTools_NurbsConvertModification.ixx>
25 #include <BRepTools.hxx>
26 #include <Standard_NoSuchObject.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <Geom2d_TrimmedCurve.hxx>
29 #include <Geom_RectangularTrimmedSurface.hxx>
30 #include <Geom_BSplineSurface.hxx>
31 #include <Geom_BSplineCurve.hxx>
32 #include <Geom_BezierSurface.hxx>
33 #include <Geom_BezierCurve.hxx>
34 #include <Geom2d_BSplineCurve.hxx>
35 #include <GeomConvert.hxx>
36 #include <Geom2dConvert.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_Line.hxx>
39 #include <Geom2dAdaptor_Curve.hxx>
40 #include <GeomAdaptor_Curve.hxx>
41 #include <GeomAdaptor_Surface.hxx>
42 #include <Geom2dAdaptor_HCurve.hxx>
43 #include <Geom2dAdaptor_HCurve.hxx>
44 #include <GeomAdaptor_HCurve.hxx>
45 #include <GeomAdaptor_HSurface.hxx>
47 #include <BSplCLib.hxx>
48 #include <Approx_SameParameter.hxx>
49 #include <BRep_Tool.hxx>
50 #include <Extrema_LocateExtPC.hxx>
51 #include <OSD_Chronometer.hxx>
52 #include <gp_GTrsf2d.hxx>
53 #include <gp_TrsfForm.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TColStd_ListIteratorOfListOfTransient.hxx>
58 #include <ProjLib_ComputeApprox.hxx>
59 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
61 #include <BSplCLib.hxx>
62 #include <Geom_Circle.hxx>
63 #include <Geom_Ellipse.hxx>
64 #include <Geom_CylindricalSurface.hxx>
66 #include <TColStd_Array1OfReal.hxx>
67 #include <BRep_TEdge.hxx>
68 #include <BRep_GCurve.hxx>
69 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
71 static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
72 const Standard_Real newU1,
73 const Standard_Real newU2)
75 TColStd_Array1OfReal knots(1,aSurface->NbUKnots()) ;
76 aSurface->UKnots(knots) ;
77 BSplCLib::Reparametrize(newU1,
80 aSurface->SetUKnots(knots) ;
82 static void GeomLib_ChangeVBounds(Handle(Geom_BSplineSurface)& aSurface,
83 const Standard_Real newV1,
84 const Standard_Real newV2)
86 TColStd_Array1OfReal knots(1,aSurface->NbVKnots()) ;
87 aSurface->VKnots(knots) ;
88 BSplCLib::Reparametrize(newV1,
91 aSurface->SetVKnots(knots) ;
94 //=======================================================================
95 //function : BRepTools_NurbsConvertModification
97 //=======================================================================
99 BRepTools_NurbsConvertModification::BRepTools_NurbsConvertModification()
105 //=======================================================================
106 //function : NewSurface
108 //=======================================================================
110 Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
111 (const TopoDS_Face& F,
112 Handle(Geom_Surface)& S,
115 Standard_Boolean& RevWires,
116 Standard_Boolean& RevFace)
118 Standard_Real U1, U2, curvU1, curvU2, surfU1, surfU2, UTol;
119 Standard_Real V1, V2, curvV1, curvV2, surfV1, surfV2, VTol;
120 RevWires = Standard_False;
121 RevFace = Standard_False;
122 Handle(Geom_Surface) SS = BRep_Tool::Surface(F,L);
123 Handle(Standard_Type) TheTypeSS = SS->DynamicType();
124 if ((TheTypeSS == STANDARD_TYPE(Geom_BSplineSurface)) ||
125 (TheTypeSS == STANDARD_TYPE(Geom_BezierSurface))) {
126 return Standard_False;
129 BRepTools::UVBounds(F,curvU1,curvU2,curvV1,curvV2);
130 Tol = BRep_Tool::Tolerance(F);
131 Standard_Real TolPar = 0.1*Tol;
132 Standard_Boolean IsUp = S->IsUPeriodic(), IsVp = S->IsVPeriodic();
134 U1 = curvU1; U2 = curvU2;
135 V1 = curvV1; V2 = curvV2;
136 SS->Bounds(surfU1,surfU2,surfV1,surfV2);
138 if (Abs(U1 - surfU1) <= TolPar)
140 if (Abs(U2 - surfU2) <= TolPar)
142 if (Abs(V1 - surfV1) <= TolPar)
144 if (Abs(V2 - surfV2) <= TolPar)
148 U1 = Max(surfU1,curvU1);
149 U2 = Min(surfU2,curvU2);
152 V1 = Max(surfV1,curvV1);
153 V2 = Min(surfV2,curvV2);
159 Standard_Real Up = S->UPeriod();
165 Standard_Real Vp = S->VPeriod();
172 Standard_Real dU = Abs(U2 - U1), dV = Abs(V2 - V1);
173 Standard_Real Up = S->UPeriod(), Vp = S->VPeriod();
174 if(Abs(dU - Up) <= TolPar && U2 <= Up) {
175 if(Abs(dV - Vp) <= TolPar && V2 <= Vp) { }
177 SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
181 if(Abs(dV - Vp) <= TolPar && V2 <= Vp)
182 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
184 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
189 Standard_Real dU = Abs(U2 - U1);
190 Standard_Real Up = S->UPeriod();
191 if(Abs(dU - Up) <= TolPar && U2 <= Up)
192 SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
194 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
198 Standard_Real dV = Abs(V2 - V1);
199 Standard_Real Vp = S->VPeriod();
200 if(Abs(dV - Vp) <= TolPar && V2 <= Vp)
201 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
203 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
207 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
211 if (Abs(surfU1-U1) > Tol || Abs(surfU2-U2) > Tol ||
212 Abs(surfV1-V1) > Tol || Abs(surfV2-V2) > Tol)
213 SS = new Geom_RectangularTrimmedSurface(S, U1, U2, V1, V2);
214 SS->Bounds(surfU1,surfU2,surfV1,surfV2);
216 S = GeomConvert::SurfaceToBSplineSurface(SS);
217 Handle(Geom_BSplineSurface) BS = Handle(Geom_BSplineSurface)::DownCast(S) ;
218 BS->Resolution(Tol, UTol, VTol) ;
221 // on recadre les bornes de S sinon les anciennes PCurves sont aux fraises
224 if (Abs(curvU1-surfU1) > UTol && !BS->IsUPeriodic()) {
225 GeomLib_ChangeUBounds(BS, U1,U2) ;
227 if (Abs(curvV1-surfV1) > VTol && !BS->IsVPeriodic()) {
228 GeomLib_ChangeVBounds(BS, V1, V2) ;
231 return Standard_True;
234 static Standard_Boolean IsConvert(const TopoDS_Edge& E)
236 Standard_Boolean isConvert = Standard_False;
237 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
238 // iterate on pcurves
239 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
240 for ( ; itcr.More() && !isConvert; itcr.Next() ) {
241 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
242 if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
243 Handle(Geom_Surface) aSurface = GC->Surface();
244 Handle(Geom2d_Curve) aCurve2d = GC->PCurve();
245 isConvert =((!aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) &&
246 !aSurface->IsKind(STANDARD_TYPE(Geom_BezierSurface))) ||
247 (!aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) &&
248 !aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))));
255 //=======================================================================
256 //function : NewCurve
258 //=======================================================================
260 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve
261 (const TopoDS_Edge& E,
262 Handle(Geom_Curve)& C,
267 Tol = BRep_Tool::Tolerance(E);
268 if(BRep_Tool::Degenerated(E)) {
271 return Standard_True;
275 Handle(Geom_Curve) Caux = BRep_Tool::Curve(E, L, f, l);
277 if ( Caux.IsNull()) {
279 return Standard_False;
281 Handle(Standard_Type) TheType = Caux->DynamicType();
282 if ((TheType == STANDARD_TYPE(Geom_BSplineCurve)) ||
283 (TheType == STANDARD_TYPE(Geom_BezierCurve))) {
285 C = Handle(Geom_Curve)::DownCast(Caux->Copy());
286 return Standard_True;
288 return Standard_False;
293 Standard_Real TolPar = Tol *.1;
295 if(C->IsPeriodic()) {
296 Standard_Real p = C->Period();
297 Standard_Real d = Abs(l - f);
298 if(Abs(d - p) <= TolPar && l <= p) {}
300 C = new Geom_TrimmedCurve(C, f, l);
303 C = new Geom_TrimmedCurve(C, f, l);
305 //modif WOK++ portage hp (fbi du 14/03/97)
307 // gp_Trsf trsf = L.Transformation();
309 // C = GeomConvert::CurveToBSplineCurve(C,Convert_QuasiAngular);
311 C = GeomConvert::CurveToBSplineCurve(C);
313 Standard_Real fnew = C->FirstParameter(), lnew = C->LastParameter(), UTol;
315 Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(C) ;
317 if(!BC->IsPeriodic()) {
318 BC->Resolution(Tol, UTol) ;
319 if(Abs(f - fnew) > UTol || Abs(l - lnew) > UTol) {
320 TColStd_Array1OfReal knots(1,BC->NbKnots()) ;
322 BSplCLib::Reparametrize(f, l, knots) ;
323 BC->SetKnots(knots) ;
327 if(!myMap.Contains(Caux)) {
330 return Standard_True ;
333 //=======================================================================
334 //function : NewPoint
336 //=======================================================================
338 Standard_Boolean BRepTools_NurbsConvertModification::NewPoint
339 //(const TopoDS_Vertex& V,
340 (const TopoDS_Vertex& ,
343 // Standard_Real& Tol)
346 return Standard_False;
350 //=======================================================================
351 //function : NewCurve2d
353 //=======================================================================
355 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
356 (const TopoDS_Edge& E,
357 const TopoDS_Face& F,
358 const TopoDS_Edge& newE,
359 const TopoDS_Face& newF,
360 Handle(Geom2d_Curve)& Curve2d,
364 Tol = BRep_Tool::Tolerance(E);
365 Standard_Real f2d,l2d;
366 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
367 Standard_Real f3d,l3d;
369 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
370 Standard_Boolean isConvert2d = ((!C3d.IsNull() && !C3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) &&
371 !C3d->IsKind(STANDARD_TYPE(Geom_BezierCurve))) ||
374 if(BRep_Tool::Degenerated(E)) {
376 if(!C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
378 Handle(Geom2d_TrimmedCurve) aTrimC = new Geom2d_TrimmedCurve(C2d,f2d,l2d);
381 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
382 return Standard_True;
384 if(!BRepTools::IsReallyClosed(E,F)) {
385 Handle(Standard_Type) TheTypeC2d = C2d->DynamicType();
387 if(TheTypeC2d == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
388 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C2d);
389 C2d = TC->BasisCurve();
392 Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter();
394 if(!C2d->IsPeriodic()) {
395 if(fc - f2d > Precision::PConfusion()) f2d = fc;
396 if(l2d - lc > Precision::PConfusion()) l2d = lc;
399 C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
401 Geom2dAdaptor_Curve G2dAC(C2d, f2d, l2d);
402 Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
405 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
407 C3d = BRep_Tool::Curve(newE, f3d, l3d);
410 C3d = BRep_Tool::Curve(E,f3d,l3d);
412 GeomAdaptor_Curve G3dAC(C3d, f3d, l3d);
413 Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
415 Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
416 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
417 Handle(Standard_Type) myT = S->DynamicType();
418 if(myT != STANDARD_TYPE(Geom_Plane)) {
420 Handle(Standard_Type) st = C2d->DynamicType();
421 if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
422 (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
424 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
425 return Standard_True;
427 return Standard_False;
431 S = BRep_Tool::Surface(newF);
434 S->Bounds(Uinf, Usup, Vinf, Vsup);
435 //Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
436 u = (Usup - Uinf)*0.1;
437 v = (Vsup - Vinf)*0.1;
438 if(S->IsUPeriodic()) {
439 Standard_Real uperiod = S->UPeriod();
440 if(uperiod < (Usup+2*u-Uinf)) {
441 if(uperiod <= (Usup-Uinf)) {
445 u = (uperiod-(Usup-Uinf))*0.5;
449 if(S->IsVPeriodic()) {
450 Standard_Real vperiod = S->VPeriod();
451 if(vperiod < (Vsup+2*v-Vinf)) {
452 if(vperiod <= (Vsup-Vinf)) {
456 v = (vperiod-(Vsup-Vinf))*0.5;
462 S = BRep_Tool::Surface(F);// Si S est un plan, pas de changement de parametrisation
463 GeomAdaptor_Surface GAS(S);
464 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
465 ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
466 if(ProjOnCurve.BSpline().IsNull()) {
467 Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
468 return Standard_True;
470 Curve2d = ProjOnCurve.BSpline();
471 return Standard_True;
473 GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
475 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
477 ProjLib_ComputeApproxOnPolarSurface ProjOnCurve(G2dAHC,G3dAHC,GAHS,Tol);
479 if(ProjOnCurve.IsDone()) {
480 Curve2d = ProjOnCurve.BSpline();
482 return Standard_True;
485 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
486 return Standard_True;
490 TopTools_ListIteratorOfListOfShape itled;
491 TColStd_ListIteratorOfListOfTransient itlcu;
493 for (itled.Initialize(myled), itlcu.Initialize(mylcu);
494 itled.More(); // itlcu.More()
495 itled.Next(),itlcu.Next())
497 if (itled.Value().IsSame(E)) {
502 if (!itled.More()) { // on stocke l`edge et la curve2d
503 Handle(Geom2d_Curve) C2dBis;
504 Standard_Real f3d,l3d,f2dBis,l2dBis;
505 C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
506 Geom2dAdaptor_Curve G2dAC(C2d, f2d, l2d);
507 Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
508 TopoDS_Edge ERevers = E;
510 // TopoDS_Edge ERevers = TopoDS::Edge(E.Reversed());
511 C2dBis = BRep_Tool::CurveOnSurface(ERevers,F,f2dBis,l2dBis);
512 Handle(Standard_Type) TheTypeC2dBis = C2dBis->DynamicType();
513 C2dBis = new Geom2d_TrimmedCurve(C2dBis,f2dBis, l2dBis);
514 Geom2dAdaptor_Curve G2dACBis(C2dBis, f2dBis, l2dBis);
515 Handle(Geom2dAdaptor_HCurve) G2dAHCBis = new Geom2dAdaptor_HCurve(G2dACBis);
518 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, f3d,l3d);
521 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
522 return Standard_True;
525 return Standard_False;
528 C3d = BRep_Tool::Curve(newE, f3d,l3d);
530 GeomAdaptor_Curve G3dAC(C3d, f3d, l3d);
531 Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
533 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
534 Handle(Standard_Type) myT = S->DynamicType();
536 mylcu.Append(C2dBis);
537 Handle(Standard_Type) st = C2d->DynamicType();
538 if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
539 (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
541 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
542 return Standard_True;
544 return Standard_False;
548 S = BRep_Tool::Surface(newF);// S est une BSplineSurface : pas besoin de la trimmed
550 Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
551 S->Bounds(Uinf, Usup, Vinf, Vsup);
552 //Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
553 u = (Usup - Uinf)*0.1;
554 v = (Vsup - Vinf)*0.1;
555 if(S->IsUPeriodic()) {
556 Standard_Real uperiod = S->UPeriod();
557 if(uperiod < (Usup+2*u-Uinf))
558 if(uperiod <= (Usup-Uinf))
561 u = (uperiod-(Usup-Uinf))*0.5;
563 if(S->IsVPeriodic()) {
564 Standard_Real vperiod = S->VPeriod();
565 if(vperiod < (Vsup+2*v-Vinf))
566 if(vperiod <= (Vsup-Vinf))
569 v = (vperiod-(Vsup-Vinf))*0.5;
571 GeomAdaptor_Surface GAS(S, Uinf-u,Usup+u,Vinf-v,Vsup+v);
572 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
575 ProjLib_ComputeApproxOnPolarSurface
576 ProjOnCurve(G2dAHC,G2dAHCBis,G3dAHC,GAHS,Tol);
578 if(ProjOnCurve.IsDone()) {
579 Curve2d = ProjOnCurve.BSpline();
580 mylcu.Append(ProjOnCurve.Curve2d());
581 return Standard_True;
584 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
585 mylcu.Append(C2dBis);
586 return Standard_True;
589 else { // on est au 2ieme tour
590 C2d = Handle(Geom2d_Curve)::DownCast(itlcu.Value());
591 Handle(Standard_Type) st = C2d->DynamicType();
592 if (!(st == STANDARD_TYPE(Geom2d_BSplineCurve)) &&
593 !(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
594 return Standard_False;
596 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
597 return Standard_True;
602 //=======================================================================
603 //function : NewParameter
605 //=======================================================================
607 Standard_Boolean BRepTools_NurbsConvertModification::NewParameter
608 (const TopoDS_Vertex& V,
609 const TopoDS_Edge& E,
613 if(BRep_Tool::Degenerated(E))
614 return Standard_False;
615 Standard_Real f, l, param = BRep_Tool::Parameter(V,E);
618 Handle(Geom_Curve) gc = BRep_Tool::Curve(E, L, f, l);
619 if(!myMap.Contains(gc))
620 return Standard_False;
622 Handle(Geom_BSplineCurve) gcc =
623 Handle(Geom_BSplineCurve)::DownCast(myMap.FindFromKey(gc));
625 gcc = Handle(Geom_BSplineCurve)::DownCast(gcc->Transformed(L.Transformation()));
627 GeomAdaptor_Curve ac(gcc);
628 gp_Pnt pnt = BRep_Tool::Pnt(V);
630 Extrema_LocateExtPC proj(pnt, ac, param, f, l, Tol);
632 Standard_Real Dist2Min = proj.SquareDistance();
633 if (Dist2Min < Tol*Tol) {
634 // Standard_Real U_final_point,V_final_point;
635 P = proj.Point().Parameter();
636 return Standard_True;
639 return Standard_False;
642 //=======================================================================
643 //function : Continuity
645 //=======================================================================
647 GeomAbs_Shape BRepTools_NurbsConvertModification::Continuity
648 (const TopoDS_Edge& E,
649 const TopoDS_Face& F1,
650 const TopoDS_Face& F2,
655 return BRep_Tool::Continuity(E,F1,F2);