1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Surface.hxx>
21 #include <Extrema_ExtPC.hxx>
22 #include <Extrema_POnCurv.hxx>
23 #include <Geom2d_BezierCurve.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Conic.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom2d_Ellipse.hxx>
29 #include <Geom2d_Hyperbola.hxx>
30 #include <Geom2d_Line.hxx>
31 #include <Geom2d_OffsetCurve.hxx>
32 #include <Geom2d_Parabola.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <Geom_BezierCurve.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <Geom_Circle.hxx>
37 #include <Geom_Conic.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_Ellipse.hxx>
40 #include <Geom_Hyperbola.hxx>
41 #include <Geom_Line.hxx>
42 #include <Geom_OffsetCurve.hxx>
43 #include <Geom_Parabola.hxx>
44 #include <Geom_Plane.hxx>
45 #include <Geom_SphericalSurface.hxx>
46 #include <Geom_Surface.hxx>
47 #include <Geom_TrimmedCurve.hxx>
48 #include <GeomAdaptor_Curve.hxx>
49 #include <GeomAPI_ProjectPointOnCurve.hxx>
50 #include <GeomAPI_ProjectPointOnSurf.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <gp_Vec2d.hxx>
55 #include <Precision.hxx>
56 #include <Standard_NotImplemented.hxx>
57 #include <Standard_ProgramError.hxx>
58 #include <TCollection_AsciiString.hxx>
61 #include <TopExp_Explorer.hxx>
62 #include <TopLoc_Location.hxx>
64 #include <TopoDS_Edge.hxx>
65 #include <TopoDS_Face.hxx>
66 #include <TopoDS_Shape.hxx>
67 #include <TopoDS_Vertex.hxx>
68 #include <TopOpeBRepDS_BuildTool.hxx>
69 #include <TopOpeBRepDS_Curve.hxx>
70 #include <TopOpeBRepDS_DataStructure.hxx>
71 #include <TopOpeBRepDS_Dumper.hxx>
72 #include <TopOpeBRepDS_HDataStructure.hxx>
73 #include <TopOpeBRepDS_Point.hxx>
74 #include <TopOpeBRepDS_Surface.hxx>
75 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
76 #include <TopOpeBRepTool_GeomTool.hxx>
77 #include <TopOpeBRepTool_OutCurveType.hxx>
78 #include <TopOpeBRepTool_ShapeTool.hxx>
80 // includes especially needed by the static Project function
82 #include <TopOpeBRepDS_DRAW.hxx>
83 #include <Geom2d_Curve.hxx>
86 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
88 Standard_Boolean FUN_UisoLineOnSphe
89 (const TopoDS_Shape& F,
90 const Handle(Geom2d_Curve)& PC)
92 if (PC.IsNull()) return Standard_False;
94 Handle(Geom_Surface) SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
95 Handle(Geom2d_Curve) LLL = ::BASISCURVE2D(PC);
96 Handle(Standard_Type) TS = SSS->DynamicType();
97 Handle(Standard_Type) T2 = LLL->DynamicType();
98 Standard_Boolean issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface));
99 Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
100 Standard_Boolean isisoU = Standard_False;
101 if (issphere && isline2d) {
102 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
103 const gp_Dir2d& d = L->Direction();
104 isisoU = (Abs(d.X()) < Precision::Parametric(Precision::Confusion()));
109 //=======================================================================
110 //function : TopOpeBRepDS_BuildTool
112 //=======================================================================
114 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
115 myCurveTool(TopOpeBRepTool_APPROX),
116 myOverWrite(Standard_True),
117 myTranslate(Standard_True)
121 //=======================================================================
122 //function : TopOpeBRepDS_BuildTool
124 //=======================================================================
126 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
127 (const TopOpeBRepTool_OutCurveType O) :
129 myOverWrite(Standard_True),
130 myTranslate(Standard_True)
134 //=======================================================================
135 //function : TopOpeBRepDS_BuildTool
137 //=======================================================================
139 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
140 (const TopOpeBRepTool_GeomTool& GT) :
142 myOverWrite(Standard_True),
143 myTranslate(Standard_True)
147 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
152 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
157 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
162 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
167 //=======================================================================
168 //function : GetGeomTool
170 //=======================================================================
172 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const
174 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
178 //=======================================================================
179 //function : ChangeGeomTool
181 //=======================================================================
183 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
185 TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
189 //=======================================================================
190 //function : MakeVertex
192 //=======================================================================
194 void TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V,
195 const TopOpeBRepDS_Point& P)const
197 myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
200 //=======================================================================
201 //function : MakeEdge
203 //=======================================================================
205 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
206 const TopOpeBRepDS_Curve& C)const
208 // Gestion des courbes nulles pour carreaux pointus
211 if (C.Curve().IsNull()) {
212 myBuilder.MakeEdge(TopoDS::Edge(E));
213 myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
217 const Handle(Geom_Curve)& GC = C.Curve();
218 myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
220 Standard_Boolean addorigin = Standard_False;
221 Standard_Boolean setrange = Standard_False;
224 if ( GC->IsClosed() ) {
225 // in case of a closed curve, insert in E a vertex located at the origin
228 Standard_Real first = GC->FirstParameter();
229 gp_Pnt P = GC->Value(first);
230 myBuilder.MakeVertex(V,P,C.Tolerance());
235 // If the curve is a degree 1 bspline set the range to 1 .. NbPoles
236 Handle(Geom_BSplineCurve) BSC = Handle(Geom_BSplineCurve)::DownCast(GC);
238 if (BSC->Degree() == 1) {
239 myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
246 Standard_Real first,last;
247 Standard_Boolean rangedef = C.Range(first,last);
254 //=======================================================================
255 //function : MakeEdge
257 //=======================================================================
259 void TopOpeBRepDS_BuildTool::MakeEdge
261 const TopOpeBRepDS_Curve& C,
262 const TopOpeBRepDS_DataStructure& BDS) const
264 // Gestion des courbes nulles pour carreaux pointus
267 TopoDS_Edge& EE = TopoDS::Edge(E);
269 if (C.Curve().IsNull()) {
270 myBuilder.MakeEdge(EE);
271 myBuilder.Degenerated(EE,Standard_True);
273 // Creation d'une arete avec PCurve connectee a la BDS Curve
275 Handle(TopOpeBRepDS_Interference) I = C.GetSCI1();
276 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI;
277 SCI=Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(I);
278 Standard_Integer iS = SCI->Support();
279 const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
280 const Handle(Geom_Surface)& GS = DSS.Surface();
281 const Handle(Geom2d_Curve)& PC = SCI->PCurve();
282 myBuilder.UpdateEdge(EE,PC,GS,TopLoc_Location(),DSS.Tolerance());
286 const Handle(Geom_Curve)& GC = C.Curve();
287 myBuilder.MakeEdge(EE,GC,C.Tolerance());
292 //=======================================================================
293 //function : MakeEdge
295 //=======================================================================
297 void TopOpeBRepDS_BuildTool::MakeEdge
299 const Handle(Geom_Curve)& C,
300 const Standard_Real Tol)const
302 myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
306 //=======================================================================
307 //function : MakeEdge
309 //=======================================================================
311 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
313 myBuilder.MakeEdge(TopoDS::Edge(E));
317 //=======================================================================
318 //function : MakeWire
320 //=======================================================================
322 void TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const
324 myBuilder.MakeWire(TopoDS::Wire(W));
328 //=======================================================================
329 //function : MakeFace
331 //=======================================================================
333 void TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F,
334 const TopOpeBRepDS_Surface& S)const
336 myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
340 //=======================================================================
341 //function : MakeShell
343 //=======================================================================
345 void TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const
347 myBuilder.MakeShell(TopoDS::Shell(Sh));
351 //=======================================================================
352 //function : MakeSolid
354 //=======================================================================
356 void TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const
358 myBuilder.MakeSolid(TopoDS::Solid(S));
362 //=======================================================================
363 //function : CopyEdge
365 //=======================================================================
367 void TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein,
368 TopoDS_Shape& Eou)const
371 // Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
372 // apres modification de la primitive Sphere pour parametrisation de
373 // l'arete meridienne en -pi/2,+pi/2.
374 // Ein est l'arete de couture complete d'une sphere complete
375 // BRep_Tool::Range(Ein) --> -pi/2,+pi/2
376 // BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
377 // NYI reflexion sur la notion de Range d'une arete et de la geometrie
378 // NYI sous jacente dans le cas ou, par construction, les vertex d'une
379 // NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
380 // NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
381 // On redefinit desormais le range de l'arete Eou, a la place de se
382 // contenter du simplissime Eou = Ein.EmptyCopied();
383 // merci les amis : correction bug PRO2586
386 TopoDS_Edge E1 = TopoDS::Edge(Ein);
387 BRep_Tool::Range(E1,f,l);
388 Eou = Ein.EmptyCopied();
389 TopoDS_Edge E2 = TopoDS::Edge(Eou);
390 myBuilder.Range(E2,f,l);
394 //=======================================================================
395 //function : GetOrientedEdgeVertices
397 //=======================================================================
399 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
401 TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
402 Standard_Real& Parmin, Standard_Real& Parmax) const
404 if ( E.Orientation() == TopAbs_FORWARD)
405 TopExp::Vertices(E,Vmin,Vmax);
407 TopExp::Vertices(E,Vmax,Vmin);
408 if ( !Vmin.IsNull() && !Vmax.IsNull()) {
409 Parmin = BRep_Tool::Parameter(Vmin,E);
410 Parmax = BRep_Tool::Parameter(Vmax,E);
414 //=======================================================================
415 //function : UpdateEdgeCurveTol
417 //=======================================================================
419 void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
420 //(const TopoDS_Face& F1,const TopoDS_Face& F2,
421 (const TopoDS_Face& ,const TopoDS_Face& ,
422 TopoDS_Edge& E, const Handle(Geom_Curve)& C3Dnew,
423 // const Standard_Real tol3d,
424 const Standard_Real ,
425 // const Standard_Real tol2d1,
426 const Standard_Real ,
427 // const Standard_Real tol2d2,
428 const Standard_Real ,
429 Standard_Real& newtol,
430 Standard_Real& newparmin,
431 Standard_Real& newparmax) const
434 if (C3Dnew.IsNull()) return;
437 // newtol = max des tolerances atteintes en 3d
438 // JMB le 06 Juillet 1999
439 // les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade,
440 // elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
441 // 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
442 // d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
443 // plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la topologie
444 // a coder des tolerances enormes dans les pieces resultats rendant celles-ci inexpoitables.
445 // De plus on essayait de rafiner la tolerance en appelant les UResolution sur les surfaces support.
446 // sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et peut amener a des valeurs
448 // On decide donc de laisser la tolerance de l'edge telle qu'elle est afin d'avoir un comportement similaire
449 // a 2.0. Jusqu'a present on a constate que des problemes avec la methode de calcul d'erreur des approx.
453 // Standard_Real r1,r2;
454 // r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
455 // r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
457 // if (r1>newtol) newtol=r1;
458 // if (r2>newtol) newtol=r2;
462 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
463 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
465 Standard_Real tolmin=BRep_Tool::Tolerance(Vmin);
466 if(newtol>tolmin) tolmin=newtol;
467 Standard_Real tolmax=BRep_Tool::Tolerance(Vmax);
468 if(newtol>tolmax) tolmax=newtol;
471 // newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
472 // newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
475 Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
477 Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
482 newparmin=C3Dnew->FirstParameter();
483 newparmax=C3Dnew->LastParameter();
486 newparmin=C3Dnew->FirstParameter();
487 newparmax=C3Dnew->LastParameter();
490 if (Vmin.Orientation() == TopAbs_FORWARD) {
491 BB.UpdateVertex(Vmin,newparmin,E,tolmin);
492 BB.UpdateVertex(Vmax,newparmax,E,tolmax);
495 BB.UpdateVertex(Vmin,newparmax,E,tolmin);
496 BB.UpdateVertex(Vmax,newparmin,E,tolmax);
499 // DSBT.Curve3D(E,C3Dnew,newtol); // -merge 04-07-97
500 Curve3D(E,C3Dnew,newtol);
502 // projection des vertex INTERNAL de E pour parametrage
503 // sur la nouvelle courbe C3Dnew de l'arete E
504 TopExp_Explorer exi(E,TopAbs_VERTEX);
505 for (;exi.More(); exi.Next() ) {
506 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
507 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
508 gp_Pnt P = BRep_Tool::Pnt(vi);
509 Standard_Real tolvi=TopOpeBRepTool_ShapeTool::Tolerance(vi);
510 GeomAPI_ProjectPointOnCurve dm(P,C3Dnew,newparmin,newparmax);
511 Standard_Boolean dmdone = dm.Extrema().IsDone();
513 if ( dm.NbPoints() ) {
514 Standard_Real newpar = dm.LowerDistanceParameter();
515 BB.UpdateVertex(vi,newpar,E,tolvi);
521 //=======================================================================
522 //function : ApproxCurves
524 //=======================================================================
526 void TopOpeBRepDS_BuildTool::ApproxCurves
527 (const TopOpeBRepDS_Curve& C,
529 Standard_Integer& inewC,
530 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
532 TopOpeBRepDS_Curve newC1;
533 inewC = HDS->MakeCurve(C,newC1);
534 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
536 // C1 curves have been approximated by BSplines of degree 1 :
537 // compute new geometry on curves.
539 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
540 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
542 const Handle(Geom_Curve)& C3D = C.Curve();
543 const Handle(Geom2d_Curve)& PC1 = C.Curve1();
544 const Handle(Geom2d_Curve)& PC2 = C.Curve2();
546 // Vmin,Vmax = bounding vertices of edge <E>
547 // and their parameters parmin,parmax .
549 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
550 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
552 Handle(Geom_Curve) C3Dnew;
553 Handle(Geom2d_Curve) PC1new;
554 Handle(Geom2d_Curve) PC2new;
555 Standard_Real tolreached3d,tolreached2d;
557 Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
559 C3Dnew,PC1new,PC2new,
560 tolreached3d,tolreached2d);
562 Standard_Real newtol,newparmin,newparmax;
563 // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
565 newtol = BRep_Tool::Tolerance(E);
574 (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
575 newtol,newparmin,newparmax);
578 if (!C3Dnew.IsNull()) {
579 newC.DefineCurve(C3Dnew,newtol,Standard_False);
580 newC.SetRange(newparmin,newparmax);
583 if (!PC1new.IsNull()) newC.Curve1(PC1new);
584 if (!PC2new.IsNull()) newC.Curve2(PC2new);
588 //=======================================================================
589 //function : ComputePCurves
591 //=======================================================================
592 Standard_Boolean FUN_getUV
593 (const Handle(Geom_Surface) surf,
594 const Handle(Geom_Curve) C3D,
595 const Standard_Real par3d,
599 gp_Pnt P3d; C3D->D0(par3d,P3d);
600 GeomAPI_ProjectPointOnSurf pons(P3d,surf);
601 if (pons.NbPoints() < 1) return Standard_False;
602 pons.LowerDistanceParameters(u0,v0);
603 return Standard_True;
606 Standard_Boolean FUN_reversePC
607 (Handle(Geom2d_Curve) PCnew,
608 const TopoDS_Face& F,
609 const gp_Pnt& P3DC3D,
610 const Standard_Real par2d,
611 const Standard_Real tol)
613 gp_Pnt2d P2D; PCnew->D0(par2d,P2D);
614 BRepAdaptor_Surface BAS(F,Standard_False);
615 gp_Pnt P3D = BAS.Value(P2D.X(),P2D.Y());
616 Standard_Boolean PCreversed = Standard_False;
617 Standard_Boolean sam = P3D.IsEqual(P3DC3D,tol);
621 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
623 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
624 gp_Dir2d d = L->Direction();
631 Standard_Boolean FUN_makeUisoLineOnSphe
632 (const TopoDS_Face& F, // with geometry the spherical surface
633 const Handle(Geom_Curve) C3D,
634 Handle(Geom2d_Curve) PCnew,
635 const Standard_Real tol3d)
637 // p3df,p3dl : C3d first and last parameters
638 Standard_Real p3df = C3D->FirstParameter();
639 Standard_Real p3dl = C3D->LastParameter();
641 // u0,v0 : C3d(par3d) UV parameters
642 Standard_Real deltainf = 0.243234, deltasup = 0.543345;
643 Standard_Real par3dinf = (1-deltainf)*p3df + deltainf*p3dl;
644 Standard_Real par3dsup = (1-deltasup)*p3df + deltasup*p3dl;
645 Standard_Real uinf,vinf,usup,vsup;
646 Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
647 if (!FUN_getUV(surf,C3D,par3dinf,uinf,vinf)) return Standard_False;
648 if (!FUN_getUV(surf,C3D,par3dsup,usup,vsup)) return Standard_False;
649 Standard_Real tol = Precision::Parametric(tol3d);
650 if (Abs(uinf-usup) > tol) return Standard_False;
652 Standard_Boolean isvgrowing = (vsup - vinf > -tol);
654 if (isvgrowing) vdir = gp_Dir2d(0,1);
655 else vdir = gp_Dir2d(0,-1);
657 gp_Pnt2d origin(uinf,vinf);
658 origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
659 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
661 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
662 L->SetLin2d(gp_Lin2d(origin,vdir));
665 return Standard_True;
668 void TopOpeBRepDS_BuildTool::ComputePCurves
669 (const TopOpeBRepDS_Curve& C,
671 TopOpeBRepDS_Curve& newC,
672 const Standard_Boolean comppc1,
673 const Standard_Boolean comppc2,
674 const Standard_Boolean compc3d) const
676 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
677 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
679 const Handle(Geom_Curve)& C3D = C.Curve();
681 // get bounding vertices Vmin,Vmax supported by the new edge <E>
682 // and their corresponding parameters parmin,parmax .
684 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
685 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
687 Handle(Geom2d_Curve) PC1new;
688 Handle(Geom2d_Curve) PC2new;
691 Standard_Real tolreached2d1 = Precision::Confusion(), tolreached2d2 = Precision::Confusion(), r1, r2, tol=Precision::Confusion();
692 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3D,tolreached2d1);
693 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3D,tolreached2d2);
695 r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
696 r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
701 if (!PC1new.IsNull()) newC.Curve1(PC1new);
702 if (!PC2new.IsNull()) newC.Curve2(PC2new);
707 Handle(Geom_Curve) C3Dnew = C3D;
709 if ( C3D->IsPeriodic() ) {
710 // ellipse on cone : periodize parmin,parmax
711 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
713 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
714 else { f = parmax; l = parmin; }
715 parmin = f; parmax = l;
716 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
717 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
721 Standard_Real tolreached3d = C.Tolerance();
722 Standard_Real tolreached2d1 = C.Tolerance();
723 Standard_Real tolreached2d2 = C.Tolerance();
725 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
726 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
728 Standard_Real newtol,newparmin,newparmax;
729 UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
730 newtol,newparmin,newparmax);
732 // xpu : suite merge : 07-07-97
734 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
735 // est une isos de la sphere
736 // NYI : enlever FUN_reversePC
737 Standard_Boolean UisoLineOnSphe1 = Standard_False;
738 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
739 if (UisoLineOnSphe1) ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
741 Standard_Boolean UisoLineOnSphe2 = Standard_False;
742 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
743 if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
745 // xpu : suite merge : 07-07-97
747 if (!C3Dnew.IsNull()) {
748 newC.Curve(C3Dnew,newtol);
749 newC.SetRange(newparmin, newparmax);
751 if (!PC1new.IsNull()) newC.Curve1(PC1new);
752 if (!PC2new.IsNull()) newC.Curve2(PC2new);
755 //=======================================================================
756 //function : PutPCurves
758 //=======================================================================
760 void TopOpeBRepDS_BuildTool::PutPCurves
761 (const TopOpeBRepDS_Curve& newC,
763 const Standard_Boolean comppc1,
764 const Standard_Boolean comppc2) const
767 TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
768 Handle(Geom2d_Curve) PC1 = newC.Curve1();
769 if (!PC1.IsNull() && comppc1) {
773 TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
774 Handle(Geom2d_Curve) PC2 = newC.Curve2();
775 if (!PC2.IsNull() && comppc2) {
781 //=======================================================================
782 //function : RecomputeCurves
784 //=======================================================================
786 void TopOpeBRepDS_BuildTool::RecomputeCurves
787 (const TopOpeBRepDS_Curve& C,
788 // const TopoDS_Edge& oldE,
791 Standard_Integer& inewC,
792 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
794 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
795 const Standard_Boolean compc3d = GT.CompC3D();
796 const Standard_Boolean comppc1 = GT.CompPC1();
797 const Standard_Boolean comppc2 = GT.CompPC2();
798 const Standard_Boolean comppc = comppc1 || comppc2;
799 const Standard_Boolean iswalk = C.IsWalk();
800 const Standard_Boolean approx = Approximation();
802 const Handle(Geom_Curve)& C3D = C.Curve();
803 if (comppc1 && C.Shape1().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
804 if (comppc2 && C.Shape2().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
805 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(E,Vmin,Vmax);
806 if ( Vmin.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
807 if ( Vmax.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
809 if (iswalk && approx) {
810 if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
811 ApproxCurves(C, E, inewC, HDS);
812 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
813 PutPCurves(newC, E, comppc1, comppc2);
815 // else if (iswalk && interpol) {
816 // InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
817 // TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
818 // PutPCurves(newC, E, comppc1, comppc2);
823 TopOpeBRepDS_Curve newC1;
824 inewC = HDS->MakeCurve(C,newC1);
825 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
826 if(iswalk && !approx) {
827 if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
828 newC.Curve1(C.Curve1());
829 newC.Curve2(C.Curve2());
832 ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);
833 PutPCurves(newC, E, comppc1, comppc2);
838 //=======================================================================
839 //function : CopyFace
841 //=======================================================================
843 void TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin,
844 TopoDS_Shape& Fou)const
846 Fou = Fin.EmptyCopied();
850 //=======================================================================
851 //function : AddEdgeVertex
853 //=======================================================================
855 void TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
857 const TopoDS_Shape& V)const
859 myBuilder.Add(Eou,V);
860 TopoDS_Edge e1 = TopoDS::Edge(Ein);
861 TopoDS_Edge e2 = TopoDS::Edge(Eou);
862 TopoDS_Vertex v1 = TopoDS::Vertex(V);
863 myBuilder.Transfert(e1,e2,v1,v1);
867 //=======================================================================
868 //function : AddEdgeVertex
870 //=======================================================================
872 void TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E,
873 const TopoDS_Shape& V)const
879 //=======================================================================
880 //function : AddWireEdge
882 //=======================================================================
884 void TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W,
885 const TopoDS_Shape& E)const
891 //=======================================================================
892 //function : AddFaceWire
894 //=======================================================================
896 void TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F,
897 const TopoDS_Shape& W)const
903 //=======================================================================
904 //function : AddShellFace
906 //=======================================================================
908 void TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh,
909 const TopoDS_Shape& F)const
915 //=======================================================================
916 //function : AddSolidShell
918 //=======================================================================
920 void TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S,
921 const TopoDS_Shape& Sh)const
927 //=======================================================================
928 //function : Parameter
930 //=======================================================================
932 void TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E,
933 const TopoDS_Shape& V,
934 const Standard_Real P)const
936 const TopoDS_Edge& e = TopoDS::Edge(E);
937 const TopoDS_Vertex& v = TopoDS::Vertex(V);
941 TopLoc_Location loc; Standard_Real f,l;
942 Handle(Geom_Curve) C = BRep_Tool::Curve(e,loc,f,l);
943 if ( !C.IsNull() && C->IsPeriodic()) {
944 Standard_Real per = C->Period();
946 TopAbs_Orientation oV=TopAbs_FORWARD;
948 TopExp_Explorer exV(e,TopAbs_VERTEX);
949 for (; exV.More(); exV.Next()) {
950 const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
951 if ( vofe.IsSame(v) ) {
952 oV = vofe.Orientation();
957 if ( oV == TopAbs_REVERSED ) {
959 Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
966 myBuilder.UpdateVertex(v,p,e,
967 0); // NYI : Tol on new vertex ??
970 //=======================================================================
973 //=======================================================================
975 void TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E,
976 const Standard_Real first,
977 const Standard_Real last)const
979 myBuilder.Range(TopoDS::Edge(E),first,last);
983 //=======================================================================
984 //function : UpdateEdge
986 //=======================================================================
988 void TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
989 TopoDS_Shape& Eou)const
994 Handle(Geom_Curve) Cin = BRep_Tool::Curve(TopoDS::Edge(Ein),loc,f1,l1);
995 Handle(Geom_Curve) Cou = BRep_Tool::Curve(TopoDS::Edge(Eou),loc,f2,l2);
996 if (Cin.IsNull() || Cou.IsNull()) return;
998 if ( Cou->IsPeriodic() ) {
999 Standard_Real f2n = f2, l2n = l2;
1001 ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1007 //=======================================================================
1008 //function : Project
1009 //purpose : project a vertex on a curve
1010 //=======================================================================
1012 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1013 const TopoDS_Vertex& V,
1016 gp_Pnt P = BRep_Tool::Pnt(V);
1017 Standard_Real tol = BRep_Tool::Tolerance(V);
1018 GeomAdaptor_Curve GAC(C);
1019 Extrema_ExtPC extrema(P,GAC);
1020 if (extrema.IsDone()) {
1021 Standard_Integer i,n = extrema.NbExt();
1022 for (i = 1; i <= n; i++) {
1023 if (extrema.IsMin(i)) {
1024 Extrema_POnCurv EPOC = extrema.Point(i);
1025 if (P.Distance(EPOC.Value()) <= tol) {
1026 p = EPOC.Parameter();
1027 return Standard_True;
1032 return Standard_False;
1036 //=======================================================================
1037 //function : Parameter
1039 //=======================================================================
1041 void TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1043 TopoDS_Shape& V)const
1045 Standard_Real newparam;
1046 Project(C.Curve(),TopoDS::Vertex(V),newparam);
1047 Parameter(E,V,newparam);
1051 //=======================================================================
1052 //function : Curve3D
1054 //=======================================================================
1056 void TopOpeBRepDS_BuildTool::Curve3D
1058 const Handle(Geom_Curve)& C,
1059 const Standard_Real Tol)const
1061 myBuilder.UpdateEdge(TopoDS::Edge(E),
1067 //=======================================================================
1068 //function : TranslateOnPeriodic
1070 //=======================================================================
1072 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1075 Handle(Geom2d_Curve)& PC) const
1077 // get range C3Df,C3Dl of 3d curve C3D of E
1079 Standard_Real C3Df,C3Dl;
1080 // Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
1081 Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl); // 13-07-97: xpu
1083 Standard_Real first = C3Df, last = C3Dl;
1084 if (C3D->IsPeriodic()) {
1085 if ( last < first ) last += Abs(first - last);
1088 // jyl-xpu : 13-06-97 :
1089 // if <PC> is U isoline on sphere, a special parametrization
1090 // is to provide, we compute <PC> (which is a line) bounds
1092 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1093 Standard_Boolean newv = Standard_True;
1095 Standard_Real du,dv;
1098 Standard_Real t =(first+last)*.5;
1100 Standard_Real u1 = ptest.X(), u2 = u1;
1101 Standard_Real v1 = ptest.Y(), v2 = v1;
1104 if (UisoLineOnSphe) {
1105 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl);
1106 GeomAdaptor_Curve GC(c3d); gp_Pnt p3dtest = GC.Value(t);
1107 Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(F));
1108 GeomAPI_ProjectPointOnSurf pons(p3dtest,surf);
1109 if (!(pons.NbPoints() < 1))
1110 pons.LowerDistanceParameters(u2,v2);
1111 } else TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1113 if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1114 du = u2 - u1, dv = v2 - v1;
1116 if ( du != 0. || dv != 0.) {
1117 // translate curve PC of du,dv
1118 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(PC->Copy());
1119 PCT->Translate(gp_Vec2d(du,dv));
1125 // RLE - IAB 16 june 94
1126 // should be provided by the BRep_Builder
1128 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1130 const TopoDS_Face& F,
1131 const TopAbs_Orientation O,
1132 const Handle(Geom2d_Curve)& C)
1134 // check if there is already a pcurve on non planar faces
1136 Handle(Geom2d_Curve) OC;
1138 Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1140 OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1143 B.UpdateEdge(E,C,F,Precision::Confusion());
1145 Standard_Boolean degen = BRep_Tool::Degenerated(E);
1147 if (O == TopAbs_REVERSED)
1148 B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1150 B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1155 //=======================================================================
1158 //=======================================================================
1160 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1162 const Handle(Geom2d_Curve)& PC)const
1164 if ( ! PC.IsNull() ) {
1165 TopoDS_Face FF = TopoDS::Face(F);
1166 TopoDS_Edge EE = TopoDS::Edge(E);
1167 Handle(Geom2d_Curve) PCT = PC;
1169 // pour iab, ajout de Translate
1170 Standard_Boolean tran = myTranslate;
1173 // recompute twice the pcurve boundaries if OverWrite
1174 // if the pcurve <PC> is U isoline on sphere -> to avoid.
1175 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1176 Standard_Boolean overwrite = UisoLineOnSphe? Standard_False:myOverWrite;
1180 TranslateOnPeriodic(F,E,PCT);
1183 myBuilder.UpdateEdge(EE,PCT,FF,0);
1185 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1187 // parametrage sur la nouvelle courbe 2d
1188 TopExp_Explorer exi(E,TopAbs_VERTEX);
1189 for (;exi.More(); exi.Next() ) {
1190 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
1191 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
1192 Standard_Real tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
1193 // NYI tester l'existence d'au moins
1194 // NYI un parametrage de vi sur EE (en 3d ou en 2d)
1195 // NYI --> a faire dans BRep_Tool
1196 Standard_Real newpar = BRep_Tool::Parameter(vi,EE);
1197 myBuilder.UpdateVertex(vi,newpar,EE,FF,tolvi);
1198 } // INTERNAL vertex
1202 //=======================================================================
1205 //=======================================================================
1207 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1209 const TopOpeBRepDS_Curve& CDS,
1210 const Handle(Geom2d_Curve)& PC)const
1212 if ( ! PC.IsNull() ) {
1213 TopoDS_Face FF = TopoDS::Face(F);
1214 TopoDS_Edge EE = TopoDS::Edge(E);
1216 Handle(Geom2d_Curve) PCT = PC;
1217 Standard_Real CDSmin,CDSmax;
1218 Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1221 TopLoc_Location L; Standard_Real Cf,Cl;
1222 Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1225 Standard_Boolean deca = (Abs(Cf - CDSmin) > Precision::PConfusion());
1226 Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast(PCT);
1227 Standard_Boolean isline2d = !line2d.IsNull();
1228 Standard_Boolean tran=(rangedef && deca && C->IsPeriodic() && isline2d);
1230 TopLoc_Location Loc;
1231 const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
1232 Standard_Boolean isUperio = Surf->IsUPeriodic();
1233 Standard_Boolean isVperio = Surf->IsVPeriodic();
1234 gp_Dir2d dir2d = line2d->Direction();
1235 Standard_Real delta;
1236 if (isUperio && dir2d.IsParallel(gp::DX2d(),Precision::Angular())) {
1237 delta = (CDSmin - Cf) * dir2d.X();
1238 PCT->Translate(gp_Vec2d(delta,0.));
1240 else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1241 delta = (CDSmin - Cf) * dir2d.Y();
1242 PCT->Translate(gp_Vec2d(0.,delta));
1247 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1252 //=======================================================================
1253 //function : Orientation
1255 //=======================================================================
1257 void TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S,
1258 const TopAbs_Orientation O)const
1264 //=======================================================================
1265 //function : Orientation
1267 //=======================================================================
1269 TopAbs_Orientation TopOpeBRepDS_BuildTool::Orientation
1270 (const TopoDS_Shape& S) const
1272 return S.Orientation();
1275 //=======================================================================
1278 //=======================================================================
1280 void TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S,
1281 const Standard_Boolean B)const
1287 //=======================================================================
1288 //function : Approximation
1290 //=======================================================================
1292 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1294 return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1297 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1301 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1302 BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1305 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1306 const TopoDS_Shape& newF) const
1310 const Handle(Geom2d_Curve)& PC = BRep_Tool::CurveOnSurface(TopoDS::Edge(E),TopoDS::Face(oldF),f,l);
1311 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
1312 BB.UpdateEdge(TopoDS::Edge(E),PC,TopoDS::Face(newF),tol);
1316 /* // - merge 04-07-97
1317 //=======================================================================
1318 //function : RecomputeCurve
1320 //=======================================================================
1322 void TopOpeBRepDS_BuildTool::RecomputeCurve
1323 (const TopOpeBRepDS_Curve& C1,
1325 TopOpeBRepDS_Curve& C2 ) const
1327 // - C1 curves have been approximated by BSplines of degree 1 :
1329 // - C1.Curve() is non projectable on at least one of the original
1330 // intersecting faces.
1332 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1333 Standard_Boolean compc3d = GT.CompC3D();
1334 Standard_Boolean comppc1 = GT.CompPC1();
1335 Standard_Boolean comppc2 = GT.CompPC2();
1337 const Handle(Geom_Curve)& C3D = C1.Curve();
1338 if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1339 if (comppc1 && C2.Shape1().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1340 if (comppc2 && C2.Shape2().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1341 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
1342 if ( Vmin.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1343 if ( Vmax.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1345 Standard_Boolean kbspl1 = Standard_False;
1346 Handle(Geom_BSplineCurve) BS = Handle(Geom_BSplineCurve)::DownCast(C3D);
1347 if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
1348 if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
1349 else RecomputeCurveOnCone(C1,E,C2);
1352 //=======================================================================
1353 //function : RecomputeBSpline1Curve
1355 //=======================================================================
1357 void TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1358 (const TopOpeBRepDS_Curve& C1,
1360 TopOpeBRepDS_Curve& C2) const
1362 // C1 curves have been approximated by BSplines of degree 1 :
1363 // compute new geometry on curves.
1365 TopoDS_Edge& E = TopoDS::Edge(EE);
1367 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1368 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1369 Standard_Boolean compc3d = GT.CompC3D();
1370 Standard_Boolean comppc1 = GT.CompPC1();
1371 Standard_Boolean comppc2 = GT.CompPC2();
1373 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1374 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1376 const Handle(Geom_Curve)& C3D = C1.Curve();
1377 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1378 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1380 // Vmin,Vmax = bounding vertices of edge <E>
1381 // and their parameters parmin,parmax .
1383 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1384 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1387 Handle(Geom_Curve) C3Dnew;
1388 Handle(Geom2d_Curve) PC1new;
1389 Handle(Geom2d_Curve) PC2new;
1390 Standard_Real tolreached3d,tolreached2d;
1392 if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1394 C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1395 (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1397 if ( comppc1 && (!PC1.IsNull()) ) {
1398 PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1399 (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1401 if ( comppc2 && (!PC2.IsNull()) ) {
1402 PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1403 (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1407 else if ( typec3d == TopOpeBRepTool_APPROX ) {
1408 if (!comppc1 || !comppc2) throw Standard_NotImplemented("DSBuildToolAPPROX");
1409 myCurveTool.MakeCurves(parmin,parmax,
1411 C3Dnew,PC1new,PC2new,
1412 tolreached3d,tolreached2d);
1415 else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1416 throw Standard_NotImplemented("DSBuildToolINTERPOL");
1419 Standard_Real newtol,newparmin,newparmax;
1420 ::FUN_updateEDGECURVETOL
1421 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1422 newtol,newparmin,newparmax);
1424 if (!C3Dnew.IsNull()) {
1425 C2.DefineCurve(C3Dnew,newtol,Standard_False);
1426 C2.SetRange(newparmin,newparmax);
1428 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1429 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1433 //=======================================================================
1434 //function : RecomputeCurveOnCone
1436 //=======================================================================
1438 void TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1439 (const TopOpeBRepDS_Curve& C1,
1441 TopOpeBRepDS_Curve& C2 ) const
1443 // C1 Pcurves have not been computed because C1 Curve is not projectable
1444 // on one at least of the intersecting faces giving C1 Curve.
1445 // (see TopOpeBRepTool_CurveTool::IsProjectable())
1447 TopoDS_Edge& E = TopoDS::Edge(EE);
1449 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1450 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1451 Standard_Boolean compc3d = GT.CompC3D();
1452 Standard_Boolean comppc1 = GT.CompPC1();
1453 Standard_Boolean comppc2 = GT.CompPC2();
1455 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1456 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1458 const Handle(Geom_Curve)& C3D = C1.Curve();
1459 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1460 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1462 // get bounding vertices Vmin,Vmax supported by the new edge <E>
1463 // and their corresponding parameters parmin,parmax .
1465 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1466 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1468 if ( C3D->IsPeriodic() ) {
1469 // ellipse on cone : periodize parmin,parmax
1470 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1472 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
1473 else { f = parmax; l = parmin; }
1474 parmin = f; parmax = l;
1475 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
1478 Handle(Geom_TrimmedCurve) C3Dnew;
1479 Handle(Geom2d_Curve) PC1new;
1480 Handle(Geom2d_Curve) PC2new;
1481 Standard_Real tolreached3d = C1.Tolerance();
1482 Standard_Real tolreached2d1 = C1.Tolerance();
1483 Standard_Real tolreached2d2 = C1.Tolerance();
1484 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
1485 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
1486 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
1489 if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1492 Standard_Real newtol,newparmin,newparmax;
1493 FUN_updateEDGECURVETOL
1494 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1495 newtol,newparmin,newparmax);
1498 // Standard_Real fac = 0.3798123578771;
1499 // Standard_Real tol = newtol;
1500 // Standard_Real par3d = (1-fac)*newparmin + (fac)*newparmax;
1501 // Standard_Real par2d = par3d - newparmin;
1503 // gp_Pnt P3DC3D; C3D->D0(par3d,P3DC3D);
1505 // Standard_Boolean UisoLineOnSphe1 = Standard_False;
1506 // UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1507 // if (UisoLineOnSphe1) {
1508 // Standard_Real isrev1 =
1509 // ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
1514 // Standard_Boolean UisoLineOnSphe2 = Standard_False;
1515 // UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1516 // if (UisoLineOnSphe2) {
1517 // Standard_Real isrev2 =
1518 // ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
1523 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
1524 // est une isos de la sphere
1525 // NYI : enlever FUN_reversePC
1526 Standard_Boolean UisoLineOnSphe1 = Standard_False;
1527 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1528 if (UisoLineOnSphe1) {
1529 ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
1531 Standard_Boolean UisoLineOnSphe2 = Standard_False;
1532 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1533 if (UisoLineOnSphe2) {
1534 ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1537 if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1538 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1539 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1540 }*/ // - merge 04-07-97