1 // File: BRepTools_NurbsConvertModification.cxx
2 // Created: Fri Jul 12 10:16:32 1996
3 // Author: Stagiaire Mary FABIEN
4 // <fbi@animax.paris1.matra-dtv.fr>
7 #include <BRepTools_NurbsConvertModification.ixx>
9 #include <BRepTools.hxx>
10 #include <Standard_NoSuchObject.hxx>
11 #include <Geom_TrimmedCurve.hxx>
12 #include <Geom2d_TrimmedCurve.hxx>
13 #include <Geom_RectangularTrimmedSurface.hxx>
14 #include <Geom_BSplineSurface.hxx>
15 #include <Geom_BSplineCurve.hxx>
16 #include <Geom_BezierSurface.hxx>
17 #include <Geom_BezierCurve.hxx>
18 #include <Geom2d_BSplineCurve.hxx>
19 #include <GeomConvert.hxx>
20 #include <Geom2dConvert.hxx>
21 #include <Geom_Plane.hxx>
22 #include <Geom_Line.hxx>
23 #include <Geom2dAdaptor_Curve.hxx>
24 #include <GeomAdaptor_Curve.hxx>
25 #include <GeomAdaptor_Surface.hxx>
26 #include <Geom2dAdaptor_HCurve.hxx>
27 #include <Geom2dAdaptor_HCurve.hxx>
28 #include <GeomAdaptor_HCurve.hxx>
29 #include <GeomAdaptor_HSurface.hxx>
31 #include <BSplCLib.hxx>
32 #include <Approx_SameParameter.hxx>
33 #include <BRep_Tool.hxx>
34 #include <Extrema_LocateExtPC.hxx>
35 #include <OSD_Chronometer.hxx>
36 #include <gp_GTrsf2d.hxx>
37 #include <gp_TrsfForm.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TColStd_ListIteratorOfListOfTransient.hxx>
42 #include <ProjLib_ComputeApprox.hxx>
43 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
45 #include <BSplCLib.hxx>
46 #include <Geom_Circle.hxx>
47 #include <Geom_Ellipse.hxx>
48 #include <Geom_CylindricalSurface.hxx>
50 #include <TColStd_Array1OfReal.hxx>
51 #include <BRep_TEdge.hxx>
52 #include <BRep_GCurve.hxx>
53 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
55 static void GeomLib_ChangeUBounds(Handle(Geom_BSplineSurface)& aSurface,
56 const Standard_Real newU1,
57 const Standard_Real newU2)
59 TColStd_Array1OfReal knots(1,aSurface->NbUKnots()) ;
60 aSurface->UKnots(knots) ;
61 BSplCLib::Reparametrize(newU1,
64 aSurface->SetUKnots(knots) ;
66 static void GeomLib_ChangeVBounds(Handle(Geom_BSplineSurface)& aSurface,
67 const Standard_Real newV1,
68 const Standard_Real newV2)
70 TColStd_Array1OfReal knots(1,aSurface->NbVKnots()) ;
71 aSurface->VKnots(knots) ;
72 BSplCLib::Reparametrize(newV1,
75 aSurface->SetVKnots(knots) ;
78 //=======================================================================
79 //function : BRepTools_NurbsConvertModification
81 //=======================================================================
83 BRepTools_NurbsConvertModification::BRepTools_NurbsConvertModification()
89 //=======================================================================
90 //function : NewSurface
92 //=======================================================================
94 Standard_Boolean BRepTools_NurbsConvertModification::NewSurface
95 (const TopoDS_Face& F,
96 Handle(Geom_Surface)& S,
99 Standard_Boolean& RevWires,
100 Standard_Boolean& RevFace)
102 Standard_Real U1, U2, curvU1, curvU2, surfU1, surfU2, UTol;
103 Standard_Real V1, V2, curvV1, curvV2, surfV1, surfV2, VTol;
104 RevWires = Standard_False;
105 RevFace = Standard_False;
106 Handle(Geom_Surface) SS = BRep_Tool::Surface(F,L);
107 Handle(Standard_Type) TheTypeSS = SS->DynamicType();
108 if ((TheTypeSS == STANDARD_TYPE(Geom_BSplineSurface)) ||
109 (TheTypeSS == STANDARD_TYPE(Geom_BezierSurface))) {
110 return Standard_False;
113 BRepTools::UVBounds(F,curvU1,curvU2,curvV1,curvV2);
114 Tol = BRep_Tool::Tolerance(F);
115 Standard_Real TolPar = 0.1*Tol;
116 Standard_Boolean IsUp = S->IsUPeriodic(), IsVp = S->IsVPeriodic();
118 U1 = curvU1; U2 = curvU2;
119 V1 = curvV1; V2 = curvV2;
120 SS->Bounds(surfU1,surfU2,surfV1,surfV2);
122 U1 = Max(surfU1,curvU1);
123 U2 = Min(surfU2,curvU2);
126 V1 = Max(surfV1,curvV1);
127 V2 = Min(surfV2,curvV2);
131 Standard_Real dU = Abs(U2 - U1), dV = Abs(V2 - V1);
132 Standard_Real Up = S->UPeriod(), Vp = S->VPeriod();
133 if(Abs(dU - Up) <= TolPar && U2 <= Up) {
134 if(Abs(dV - Vp) <= TolPar && V2 <= Vp) { }
136 SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
140 if(Abs(dV - Vp) <= TolPar && V2 <= Vp)
141 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
143 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
148 Standard_Real dU = Abs(U2 - U1);
149 Standard_Real Up = S->UPeriod();
150 if(Abs(dU - Up) <= TolPar && U2 <= Up)
151 SS = new Geom_RectangularTrimmedSurface(S, V1+1e-9, V2-1e-9, Standard_False);
153 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
157 Standard_Real dV = Abs(V2 - V1);
158 Standard_Real Vp = S->VPeriod();
159 if(Abs(dV - Vp) <= TolPar && V2 <= Vp)
160 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, Standard_True);
162 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
166 SS = new Geom_RectangularTrimmedSurface(S, U1+1e-9, U2-1e-9, V1+1e-9, V2-1e-9);
169 SS->Bounds(surfU1,surfU2,surfV1,surfV2) ;
171 S = GeomConvert::SurfaceToBSplineSurface(SS);
172 Handle(Geom_BSplineSurface) BS = Handle(Geom_BSplineSurface)::DownCast(S) ;
173 BS->Resolution(Tol, UTol, VTol) ;
176 // on recadre les bornes de S sinon les anciennes PCurves sont aux fraises
179 if (Abs(curvU1-surfU1) > UTol && !BS->IsUPeriodic()) {
180 GeomLib_ChangeUBounds(BS, U1,U2) ;
182 if (Abs(curvV1-surfV1) > VTol && !BS->IsVPeriodic()) {
183 GeomLib_ChangeVBounds(BS, V1, V2) ;
186 return Standard_True;
189 static Standard_Boolean IsConvert(const TopoDS_Edge& E)
191 Standard_Boolean isConvert = Standard_False;
192 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
193 // iterate on pcurves
194 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
195 for ( ; itcr.More() && !isConvert; itcr.Next() ) {
196 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
197 if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
198 Handle(Geom_Surface) aSurface = GC->Surface();
199 Handle(Geom2d_Curve) aCurve2d = GC->PCurve();
200 isConvert =((!aSurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface)) &&
201 !aSurface->IsKind(STANDARD_TYPE(Geom_BezierSurface))) ||
202 (!aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) &&
203 !aCurve2d->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))));
210 //=======================================================================
211 //function : NewCurve
213 //=======================================================================
215 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve
216 (const TopoDS_Edge& E,
217 Handle(Geom_Curve)& C,
222 Tol = BRep_Tool::Tolerance(E);
223 if(BRep_Tool::Degenerated(E)) {
226 return Standard_True;
230 Handle(Geom_Curve) Caux = BRep_Tool::Curve(E, L, f, l);
232 if ( Caux.IsNull()) {
234 return Standard_False;
236 Handle(Standard_Type) TheType = Caux->DynamicType();
237 if ((TheType == STANDARD_TYPE(Geom_BSplineCurve)) ||
238 (TheType == STANDARD_TYPE(Geom_BezierCurve))) {
240 C = Handle(Geom_Curve)::DownCast(Caux->Copy());
241 return Standard_True;
243 return Standard_False;
248 Standard_Real TolPar = Tol *.1;
250 if(C->IsPeriodic()) {
251 Standard_Real p = C->Period();
252 Standard_Real d = Abs(l - f);
253 if(Abs(d - p) <= TolPar && l <= p) {}
255 C = new Geom_TrimmedCurve(C, f, l);
258 C = new Geom_TrimmedCurve(C, f, l);
260 //modif WOK++ portage hp (fbi du 14/03/97)
262 // gp_Trsf trsf = L.Transformation();
264 // C = GeomConvert::CurveToBSplineCurve(C,Convert_QuasiAngular);
266 C = GeomConvert::CurveToBSplineCurve(C);
268 Standard_Real fnew = C->FirstParameter(), lnew = C->LastParameter(), UTol;
270 Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(C) ;
272 if(!BC->IsPeriodic()) {
273 BC->Resolution(Tol, UTol) ;
274 if(Abs(f - fnew) > UTol || Abs(l - lnew) > UTol) {
275 TColStd_Array1OfReal knots(1,BC->NbKnots()) ;
277 BSplCLib::Reparametrize(f, l, knots) ;
278 BC->SetKnots(knots) ;
282 if(!myMap.Contains(Caux)) {
285 return Standard_True ;
288 //=======================================================================
289 //function : NewPoint
291 //=======================================================================
293 Standard_Boolean BRepTools_NurbsConvertModification::NewPoint
294 //(const TopoDS_Vertex& V,
295 (const TopoDS_Vertex& ,
298 // Standard_Real& Tol)
301 return Standard_False;
305 //=======================================================================
306 //function : NewCurve2d
308 //=======================================================================
310 Standard_Boolean BRepTools_NurbsConvertModification::NewCurve2d
311 (const TopoDS_Edge& E,
312 const TopoDS_Face& F,
313 const TopoDS_Edge& newE,
314 const TopoDS_Face& newF,
315 Handle(Geom2d_Curve)& Curve2d,
319 Tol = BRep_Tool::Tolerance(E);
320 Standard_Real f2d,l2d;
321 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f2d,l2d);
322 Standard_Real f3d,l3d;
324 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
325 Standard_Boolean isConvert2d = ((!C3d.IsNull() && !C3d->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) &&
326 !C3d->IsKind(STANDARD_TYPE(Geom_BezierCurve))) ||
329 if(BRep_Tool::Degenerated(E)) {
331 if(!C2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
333 Handle(Geom2d_TrimmedCurve) aTrimC = new Geom2d_TrimmedCurve(C2d,f2d,l2d);
336 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
337 return Standard_True;
339 if(!BRepTools::IsReallyClosed(E,F)) {
340 Handle(Standard_Type) TheTypeC2d = C2d->DynamicType();
342 if(TheTypeC2d == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
343 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C2d);
344 C2d = TC->BasisCurve();
347 Standard_Real fc = C2d->FirstParameter(), lc = C2d->LastParameter();
349 if(!C2d->IsPeriodic()) {
350 if(fc - f2d > Precision::PConfusion()) f2d = fc;
351 if(l2d - lc > Precision::PConfusion()) l2d = lc;
354 C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
356 Geom2dAdaptor_Curve G2dAC(C2d, f2d, l2d);
357 Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
360 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, Loc, f3d,l3d);
362 C3d = BRep_Tool::Curve(newE, f3d, l3d);
365 C3d = BRep_Tool::Curve(E,f3d,l3d);
367 GeomAdaptor_Curve G3dAC(C3d, f3d, l3d);
368 Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
370 Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
371 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
372 Handle(Standard_Type) myT = S->DynamicType();
373 if(myT != STANDARD_TYPE(Geom_Plane)) {
375 Handle(Standard_Type) st = C2d->DynamicType();
376 if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
377 (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
379 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
380 return Standard_True;
382 return Standard_False;
386 S = BRep_Tool::Surface(newF);
389 S->Bounds(Uinf, Usup, Vinf, Vsup);
390 Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
391 u = (Usup - Uinf)*0.1;
392 v = (Vsup - Vinf)*0.1;
393 if(S->IsUPeriodic()) {
394 Standard_Real uperiod = S->UPeriod();
395 if(uperiod < (Usup+2*u-Uinf)) {
396 if(uperiod <= (Usup-Uinf)) {
400 u = (uperiod-(Usup-Uinf))*0.5;
404 if(S->IsVPeriodic()) {
405 Standard_Real vperiod = S->VPeriod();
406 if(vperiod < (Vsup+2*v-Vinf)) {
407 if(vperiod <= (Vsup-Vinf)) {
411 v = (vperiod-(Vsup-Vinf))*0.5;
417 S = BRep_Tool::Surface(F);// Si S est un plan, pas de changement de parametrisation
418 GeomAdaptor_Surface GAS(S);
419 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
420 ProjLib_ComputeApprox ProjOnCurve(G3dAHC,GAHS,Tol);
421 if(ProjOnCurve.BSpline().IsNull()) {
422 Curve2d = Geom2dConvert::CurveToBSplineCurve(ProjOnCurve.Bezier());
423 return Standard_True;
425 Curve2d = ProjOnCurve.BSpline();
426 return Standard_True;
428 GeomAdaptor_Surface GAS(S,Uinf-u,Usup+u,Vinf-v,Vsup+v);
430 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
432 ProjLib_ComputeApproxOnPolarSurface ProjOnCurve(G2dAHC,G3dAHC,GAHS,Tol);
434 if(ProjOnCurve.IsDone()) {
435 Curve2d = ProjOnCurve.BSpline();
437 return Standard_True;
440 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
441 return Standard_True;
445 TopTools_ListIteratorOfListOfShape itled;
446 TColStd_ListIteratorOfListOfTransient itlcu;
448 for (itled.Initialize(myled), itlcu.Initialize(mylcu);
449 itled.More(); // itlcu.More()
450 itled.Next(),itlcu.Next()) {
451 if (itled.Value().IsSame(E)) {
456 if (!itled.More()) { // on stocke l`edge et la curve2d
457 Handle(Geom2d_Curve) C2dBis;
458 Standard_Real f3d,l3d,f2dBis,l2dBis;
459 C2d = new Geom2d_TrimmedCurve(C2d, f2d, l2d);
460 Geom2dAdaptor_Curve G2dAC(C2d, f2d, l2d);
461 Handle(Geom2dAdaptor_HCurve) G2dAHC = new Geom2dAdaptor_HCurve(G2dAC);
462 TopoDS_Edge ERevers = E;
464 // TopoDS_Edge ERevers = TopoDS::Edge(E.Reversed());
465 C2dBis = BRep_Tool::CurveOnSurface(ERevers,F,f2dBis,l2dBis);
466 Handle(Standard_Type) TheTypeC2dBis = C2dBis->DynamicType();
467 C2dBis = new Geom2d_TrimmedCurve(C2dBis,f2dBis, l2dBis);
468 Geom2dAdaptor_Curve G2dACBis(C2dBis, f2dBis, l2dBis);
469 Handle(Geom2dAdaptor_HCurve) G2dAHCBis = new Geom2dAdaptor_HCurve(G2dACBis);
472 Handle(Geom_Curve) C3d = BRep_Tool::Curve(E, f3d,l3d);
475 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
476 return Standard_True;
479 return Standard_False;
482 C3d = BRep_Tool::Curve(newE, f3d,l3d);
484 GeomAdaptor_Curve G3dAC(C3d, f3d, l3d);
485 Handle(GeomAdaptor_HCurve) G3dAHC = new GeomAdaptor_HCurve(G3dAC);
487 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
488 Handle(Standard_Type) myT = S->DynamicType();
490 mylcu.Append(C2dBis);
491 Handle(Standard_Type) st = C2d->DynamicType();
492 if ((st == STANDARD_TYPE(Geom2d_BSplineCurve)) ||
493 (st == STANDARD_TYPE(Geom2d_BezierCurve))) {
495 Curve2d = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
496 return Standard_True;
498 return Standard_False;
502 S = BRep_Tool::Surface(newF);// S est une BSplineSurface : pas besoin de la trimmed
504 Standard_Real Uinf, Usup, Vinf, Vsup, u = 0, v = 0;
505 S->Bounds(Uinf, Usup, Vinf, Vsup);
506 Uinf -= 1e-9; Usup += 1e-9; Vinf -= 1e-9; Vsup += 1e-9;
507 u = (Usup - Uinf)*0.1;
508 v = (Vsup - Vinf)*0.1;
509 if(S->IsUPeriodic()) {
510 Standard_Real uperiod = S->UPeriod();
511 if(uperiod < (Usup+2*u-Uinf))
512 if(uperiod <= (Usup-Uinf))
515 u = (uperiod-(Usup-Uinf))*0.5;
517 if(S->IsVPeriodic()) {
518 Standard_Real vperiod = S->VPeriod();
519 if(vperiod < (Vsup+2*v-Vinf))
520 if(vperiod <= (Vsup-Vinf))
523 v = (vperiod-(Vsup-Vinf))*0.5;
525 GeomAdaptor_Surface GAS(S, Uinf-u,Usup+u,Vinf-v,Vsup+v);
526 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(GAS);
529 ProjLib_ComputeApproxOnPolarSurface
530 ProjOnCurve(G2dAHC,G2dAHCBis,G3dAHC,GAHS,Tol);
532 if(ProjOnCurve.IsDone()) {
533 Curve2d = ProjOnCurve.BSpline();
534 mylcu.Append(ProjOnCurve.Curve2d());
535 return Standard_True;
538 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
539 mylcu.Append(C2dBis);
540 return Standard_True;
543 else { // on est au 2ieme tour
544 C2d = Handle(Geom2d_Curve)::DownCast(itlcu.Value());
545 Handle(Standard_Type) st = C2d->DynamicType();
546 if (!(st == STANDARD_TYPE(Geom2d_BSplineCurve)) &&
547 !(st == STANDARD_TYPE(Geom2d_BezierCurve))) {
548 return Standard_False;
550 Curve2d = Geom2dConvert::CurveToBSplineCurve(C2d);
551 return Standard_True;
555 return Standard_True;
558 //=======================================================================
559 //function : NewParameter
561 //=======================================================================
563 Standard_Boolean BRepTools_NurbsConvertModification::NewParameter
564 (const TopoDS_Vertex& V,
565 const TopoDS_Edge& E,
569 if(BRep_Tool::Degenerated(E))
570 return Standard_False;
571 Standard_Real f, l, param = BRep_Tool::Parameter(V,E);
574 Handle(Geom_Curve) gc = BRep_Tool::Curve(E, L, f, l);
575 if(!myMap.Contains(gc))
576 return Standard_False;
578 Handle(Geom_BSplineCurve) gcc =
579 Handle(Geom_BSplineCurve)::DownCast(myMap.FindFromKey(gc));
581 gcc = Handle(Geom_BSplineCurve)::DownCast(gcc->Transformed(L.Transformation()));
583 GeomAdaptor_Curve ac(gcc);
584 gp_Pnt pnt = BRep_Tool::Pnt(V);
586 Extrema_LocateExtPC proj(pnt, ac, param, f, l, Tol);
588 Standard_Real Dist2Min = proj.SquareDistance();
589 if (Dist2Min < Tol*Tol) {
590 // Standard_Real U_final_point,V_final_point;
591 P = proj.Point().Parameter();
592 return Standard_True;
595 return Standard_False;
598 //=======================================================================
599 //function : Continuity
601 //=======================================================================
603 GeomAbs_Shape BRepTools_NurbsConvertModification::Continuity
604 (const TopoDS_Edge& E,
605 const TopoDS_Face& F1,
606 const TopoDS_Face& F2,
611 return BRep_Tool::Continuity(E,F1,F2);