1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-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.
22 #include <TopOpeBRepDS_BuildTool.ixx>
25 #include <TopExp_Explorer.hxx>
27 #include <BRep_Tool.hxx>
28 #include <TopOpeBRepTool_GeomTool.hxx>
29 #include <TopOpeBRepTool_ShapeTool.hxx>
30 #include <TopOpeBRepTool_OutCurveType.hxx>
31 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
32 #include <Precision.hxx>
33 #include <Geom_Surface.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_TrimmedCurve.hxx>
38 #include <GeomAPI_ProjectPointOnCurve.hxx>
39 #include <GeomAPI_ProjectPointOnSurf.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Vertex.hxx>
44 #include <gp_Vec2d.hxx>
46 #include <TopLoc_Location.hxx>
47 #include <TopOpeBRepTool_ShapeTool.hxx>
48 #include <Geom_SphericalSurface.hxx>
49 #include <Standard_ProgramError.hxx>
50 #include <Standard_NotImplemented.hxx>
52 #include <gp_Pnt2d.hxx>
53 #include <TopOpeBRepDS_Dumper.hxx>
54 #include <BRepAdaptor_Surface.hxx>
55 #include <Geom2d_Conic.hxx>
56 #include <Geom2d_Circle.hxx>
57 #include <Geom2d_Line.hxx>
58 #include <Geom2d_Ellipse.hxx>
59 #include <Geom2d_Parabola.hxx>
60 #include <Geom2d_Hyperbola.hxx>
61 #include <Geom2d_BezierCurve.hxx>
62 #include <Geom2d_BSplineCurve.hxx>
63 #include <Geom2d_TrimmedCurve.hxx>
64 #include <Geom2d_OffsetCurve.hxx>
65 #include <Geom_Conic.hxx>
66 #include <Geom_Circle.hxx>
67 #include <Geom_Line.hxx>
68 #include <Geom_Ellipse.hxx>
69 #include <Geom_Parabola.hxx>
70 #include <Geom_Hyperbola.hxx>
71 #include <Geom_BezierCurve.hxx>
72 #include <Geom_BSplineCurve.hxx>
73 #include <Geom_TrimmedCurve.hxx>
74 #include <Geom_OffsetCurve.hxx>
75 // includes especially needed by the static Project function
76 #include <BRep_Tool.hxx>
77 #include <GeomAdaptor_Curve.hxx>
78 #include <Extrema_ExtPC.hxx>
80 #include <Extrema_POnCurv.hxx>
81 #include <Geom_Curve.hxx>
82 #include <Geom_BSplineCurve.hxx>
83 #include <TCollection_AsciiString.hxx>
84 #include <Geom2d_TrimmedCurve.hxx>
87 extern Standard_Boolean TopOpeBRepDS_GettraceDSNC();
88 extern Standard_Boolean TopOpeBRepDS_GettraceBUTO();
89 extern Standard_Boolean TopOpeBRepDS_GettraceTRPE();
90 extern Standard_Boolean TopOpeBRepDS_GettraceSANTRAN();
91 static void DUMPCURVES(const Handle(Geom_Curve)& C3D,const TopOpeBRepDS_Curve& C)
93 if ( !C3D.IsNull() ) {
94 Standard_Real dp1 = C3D->FirstParameter();
95 Standard_Real dp2 = C3D->LastParameter();
96 cout<<"TopOpeBRepDS_BuildTool : C3D = "<<dp1<<","<<dp2<<endl;
98 if ( !C.Curve1().IsNull() ) {
99 Standard_Real dp1 = C.Curve1()->FirstParameter();
100 Standard_Real dp2 = C.Curve1()->LastParameter();
101 cout<<"TopOpeBRepDS_BuildTool : PC1 = "<<dp1<<","<<dp2<<endl;
103 if ( !C.Curve2().IsNull() ) {
104 Standard_Real dp1 = C.Curve2()->FirstParameter();
105 Standard_Real dp2 = C.Curve2()->LastParameter();
106 cout<<"TopOpeBRepDS_BuildTool : PC2 = "<<dp1<<","<<dp2<<endl;
112 #include <TopOpeBRepDS_DRAW.hxx>
115 //-----------------------------------------------------------------------
116 //function : PrintSurface
117 //purpose : print the name of a surface on a stream
118 // a mettre dans TopOpeBRepDS_Dumper.cxx NYI
119 //-----------------------------------------------------------------------
122 static Standard_OStream& PrintSurface(const TopoDS_Face& F, Standard_OStream& s)
124 BRepAdaptor_Surface STA_Surface(F);
125 GeomAbs_SurfaceType t = STA_Surface.GetType();
127 case GeomAbs_Plane : s<<"PLANE"; break;
128 case GeomAbs_Cylinder : s<<"CYLINDER"; break;
129 case GeomAbs_Cone : s<<"CONE"; break;
130 case GeomAbs_Sphere : s<<"SPHERE"; break;
131 case GeomAbs_Torus : s<<"TORUS"; break;
132 case GeomAbs_BezierSurface : s<<"BEZIERSURFACE"; break;
133 case GeomAbs_BSplineSurface : s<<"BSPLINESURFACE"; break;
134 case GeomAbs_SurfaceOfRevolution : s<<"SURFACEOFREVOLUTION"; break;
135 case GeomAbs_SurfaceOfExtrusion : s<<"SURFACEOFEXTRUSION"; break;
136 case GeomAbs_OtherSurface : default : s<<"OTHERSURFACE"; break;
142 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
144 //-----------------------------------------------------------------------
145 //function : GetOrigin
146 //purpose : a mettre dans TopOpeBRepDS_Dumper.cxx NYI
147 //-----------------------------------------------------------------------
150 static Standard_Boolean GetOrigin(const Handle(Geom2d_Curve)& PCIN, gp_Pnt2d& o)
152 if (PCIN.IsNull()) return Standard_False;
153 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCIN);
154 if (PC.IsNull()) return Standard_False;
156 Handle(Standard_Type) T = PC->DynamicType();
157 if ((T==STANDARD_TYPE(Geom2d_Circle)) ||
158 (T==STANDARD_TYPE(Geom2d_Ellipse)) ||
159 (T==STANDARD_TYPE(Geom2d_Parabola)) ||
160 (T==STANDARD_TYPE(Geom2d_Hyperbola))) {
161 o = Handle(Geom2d_Conic)::DownCast(PC)->Location();
162 return Standard_True;
164 else if (T==STANDARD_TYPE(Geom2d_Line)) {
165 o = Handle(Geom2d_Line)::DownCast(PC)->Location();
166 return Standard_True;
169 return Standard_False;
171 // return Standard_False;
175 //-----------------------------------------------------------------------
176 //function : GetOrigin
177 //purpose : a mettre dans TopOpeBRepDS_Dumper.cxx NYI
178 //-----------------------------------------------------------------------
181 static Standard_Boolean GetOrigin(const Handle(Geom_Curve)& CIN, gp_Pnt& o)
183 if (CIN.IsNull()) return Standard_False;
184 Handle(Geom_Curve) C = TopOpeBRepTool_ShapeTool::BASISCURVE(CIN);
185 if (C.IsNull()) return Standard_False;
187 Handle(Standard_Type) T = C->DynamicType();
188 if ((T==STANDARD_TYPE(Geom_Circle)) ||
189 (T==STANDARD_TYPE(Geom_Ellipse)) ||
190 (T==STANDARD_TYPE(Geom_Parabola)) ||
191 (T==STANDARD_TYPE(Geom_Hyperbola))) {
192 o = Handle(Geom_Conic)::DownCast(C)->Location();
193 return Standard_True;
195 else if (T==STANDARD_TYPE(Geom_Line)) {
196 o = Handle(Geom_Line)::DownCast(C)->Position().Location();
197 return Standard_True;
200 return Standard_False;
205 Standard_Boolean FUN_UisoLineOnSphe
206 (const TopoDS_Shape& F,
207 const Handle(Geom2d_Curve)& PC)
209 if (PC.IsNull()) return Standard_False;
211 Handle(Geom_Surface) SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
212 Handle(Geom2d_Curve) LLL = ::BASISCURVE2D(PC);
213 Handle(Standard_Type) TS = SSS->DynamicType();
214 Handle(Standard_Type) T2 = LLL->DynamicType();
215 Standard_Boolean issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface));
216 Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
217 Standard_Boolean isisoU = Standard_False;
218 if (issphere && isline2d) {
219 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
220 const gp_Dir2d& d = L->Direction();
221 isisoU = (Abs(d.X()) < Precision::Parametric(Precision::Confusion()));
226 //=======================================================================
227 //function : TopOpeBRepDS_BuildTool
229 //=======================================================================
231 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
232 myCurveTool(TopOpeBRepTool_APPROX),
233 myOverWrite(Standard_True),
234 myTranslate(Standard_True)
238 //=======================================================================
239 //function : TopOpeBRepDS_BuildTool
241 //=======================================================================
243 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
244 (const TopOpeBRepTool_OutCurveType O) :
246 myOverWrite(Standard_True),
247 myTranslate(Standard_True)
251 //=======================================================================
252 //function : TopOpeBRepDS_BuildTool
254 //=======================================================================
256 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
257 (const TopOpeBRepTool_GeomTool& GT) :
259 myOverWrite(Standard_True),
260 myTranslate(Standard_True)
264 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
269 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
274 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
279 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
284 //=======================================================================
285 //function : GetGeomTool
287 //=======================================================================
289 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const
291 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
295 //=======================================================================
296 //function : ChangeGeomTool
298 //=======================================================================
300 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
302 TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
306 //=======================================================================
307 //function : MakeVertex
309 //=======================================================================
311 void TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V,
312 const TopOpeBRepDS_Point& P)const
314 myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
318 //-----------------------------------------------------------------------
319 static Standard_OStream& DUMPPNT(const gp_Pnt& P, Standard_OStream& OS)
320 //-----------------------------------------------------------------------
321 { OS<<P.X()<<" "<<P.Y()<<" "<<P.Z(); return OS; }
324 //=======================================================================
325 //function : MakeEdge
327 //=======================================================================
329 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
330 const TopOpeBRepDS_Curve& C)const
332 // Gestion des courbes nulles pour carreaux pointus
335 if (C.Curve().IsNull()) {
336 myBuilder.MakeEdge(TopoDS::Edge(E));
337 myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
341 const Handle(Geom_Curve)& GC = C.Curve();
342 myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
344 Standard_Boolean addorigin = Standard_False;
345 Standard_Boolean setrange = Standard_False;
348 if ( GC->IsClosed() ) {
349 // in case of a closed curve, insert in E a vertex located at the origin
352 Standard_Real first = GC->FirstParameter();
353 gp_Pnt P = GC->Value(first);
354 myBuilder.MakeVertex(V,P,C.Tolerance());
359 // If the curve is a degree 1 bspline set the range to 1 .. NbPoles
360 Handle(Geom_BSplineCurve) BSC = Handle(Geom_BSplineCurve)::DownCast(GC);
362 if (BSC->Degree() == 1) {
363 myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
365 if (TopOpeBRepDS_GettraceBUTO()) {
366 cout<<endl<<"TopOpeBRepDS_BuildTool : ";
367 cout<<"new range of "<< 1 <<" "<<BSC->NbPoles()<<endl;
374 if (TopOpeBRepDS_GettraceBUTO()) {
375 cout<<"TopOpeBRepDS_BuildTool : ";
376 cout<<"vertices on parameter "<<first<<endl;
377 cout<<" point is "; DUMPPNT(P,cout); cout<<endl;
384 Standard_Real first,last;
385 Standard_Boolean rangedef = C.Range(first,last);
389 if (TopOpeBRepDS_GettraceBUTO()) {
390 cout<<"TopOpeBRepDS_BuildTool : ";
391 cout<<"set edge range : "<<first<<" "<<last<<endl;
398 //=======================================================================
399 //function : MakeEdge
401 //=======================================================================
403 void TopOpeBRepDS_BuildTool::MakeEdge
405 const TopOpeBRepDS_Curve& C,
406 const TopOpeBRepDS_DataStructure& BDS) const
408 // Gestion des courbes nulles pour carreaux pointus
411 TopoDS_Edge& EE = TopoDS::Edge(E);
413 if (C.Curve().IsNull()) {
414 myBuilder.MakeEdge(EE);
415 myBuilder.Degenerated(EE,Standard_True);
417 // Creation d'une arete avec PCurve connectee a la BDS Curve
419 Handle(TopOpeBRepDS_Interference) I = C.GetSCI1();
420 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI;
421 SCI=Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(I);
422 Standard_Integer iS = SCI->Support();
423 const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
424 const Handle(Geom_Surface)& GS = DSS.Surface();
425 const Handle(Geom2d_Curve)& PC = SCI->PCurve();
426 myBuilder.UpdateEdge(EE,PC,GS,TopLoc_Location(),DSS.Tolerance());
430 const Handle(Geom_Curve)& GC = C.Curve();
431 myBuilder.MakeEdge(EE,GC,C.Tolerance());
436 //=======================================================================
437 //function : MakeEdge
439 //=======================================================================
441 void TopOpeBRepDS_BuildTool::MakeEdge
443 const Handle(Geom_Curve)& C,
444 const Standard_Real Tol)const
446 myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
450 //=======================================================================
451 //function : MakeEdge
453 //=======================================================================
455 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
457 myBuilder.MakeEdge(TopoDS::Edge(E));
461 //=======================================================================
462 //function : MakeWire
464 //=======================================================================
466 void TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const
468 myBuilder.MakeWire(TopoDS::Wire(W));
472 //=======================================================================
473 //function : MakeFace
475 //=======================================================================
477 void TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F,
478 const TopOpeBRepDS_Surface& S)const
480 myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
484 //=======================================================================
485 //function : MakeShell
487 //=======================================================================
489 void TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const
491 myBuilder.MakeShell(TopoDS::Shell(Sh));
495 //=======================================================================
496 //function : MakeSolid
498 //=======================================================================
500 void TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const
502 myBuilder.MakeSolid(TopoDS::Solid(S));
506 //=======================================================================
507 //function : CopyEdge
509 //=======================================================================
511 void TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein,
512 TopoDS_Shape& Eou)const
515 // Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
516 // apres modification de la primitive Sphere pour parametrisation de
517 // l'arete meridienne en -pi/2,+pi/2.
518 // Ein est l'arete de couture complete d'une sphere complete
519 // BRep_Tool::Range(Ein) --> -pi/2,+pi/2
520 // BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
521 // NYI reflexion sur la notion de Range d'une arete et de la geometrie
522 // NYI sous jacente dans le cas ou, par construction, les vertex d'une
523 // NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
524 // NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
525 // On redefinit desormais le range de l'arete Eou, a la place de se
526 // contenter du simplissime Eou = Ein.EmptyCopied();
527 // merci les amis : correction bug PRO2586
530 TopoDS_Edge E1 = TopoDS::Edge(Ein);
531 BRep_Tool::Range(E1,f,l);
532 Eou = Ein.EmptyCopied();
533 TopoDS_Edge E2 = TopoDS::Edge(Eou);
534 myBuilder.Range(E2,f,l);
538 //=======================================================================
539 //function : GetOrientedEdgeVertices
541 //=======================================================================
543 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
545 TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
546 Standard_Real& Parmin, Standard_Real& Parmax) const
548 if ( E.Orientation() == TopAbs_FORWARD)
549 TopExp::Vertices(E,Vmin,Vmax);
551 TopExp::Vertices(E,Vmax,Vmin);
552 if ( !Vmin.IsNull() && !Vmax.IsNull()) {
553 Parmin = BRep_Tool::Parameter(Vmin,E);
554 Parmax = BRep_Tool::Parameter(Vmax,E);
558 //=======================================================================
559 //function : UpdateEdgeCurveTol
561 //=======================================================================
563 void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
564 //(const TopoDS_Face& F1,const TopoDS_Face& F2,
565 (const TopoDS_Face& ,const TopoDS_Face& ,
566 TopoDS_Edge& E, const Handle(Geom_Curve)& C3Dnew,
567 // const Standard_Real tol3d,
568 const Standard_Real ,
569 // const Standard_Real tol2d1,
570 const Standard_Real ,
571 // const Standard_Real tol2d2,
572 const Standard_Real ,
573 Standard_Real& newtol,
574 Standard_Real& newparmin,
575 Standard_Real& newparmax) const
578 if (C3Dnew.IsNull()) return;
581 // newtol = max des tolerances atteintes en 3d
582 // JMB le 06 Juillet 1999
583 // les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade,
584 // elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
585 // 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
586 // d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
587 // plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la topologie
588 // a coder des tolerances enormes dans les pieces resultats rendant celles-ci inexpoitables.
589 // De plus on essayait de rafiner la tolerance en appelant les UResolution sur les surfaces support.
590 // sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et peut amener a des valeurs
592 // On decide donc de laisser la tolerance de l'edge telle qu'elle est afin d'avoir un comportement similaire
593 // a 2.0. Jusqu'a present on a constate que des problemes avec la methode de calcul d'erreur des approx.
597 // Standard_Real r1,r2;
598 // r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
599 // r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
601 // if (r1>newtol) newtol=r1;
602 // if (r2>newtol) newtol=r2;
604 // if (TopOpeBRepDS_GettraceDSNC()) cout<<"newtol = "<<newtol<<endl;
609 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
610 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
612 Standard_Real tolmin=BRep_Tool::Tolerance(Vmin);
613 if(newtol>tolmin) tolmin=newtol;
614 Standard_Real tolmax=BRep_Tool::Tolerance(Vmax);
615 if(newtol>tolmax) tolmax=newtol;
618 // newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
619 // newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
622 Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
624 Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
629 newparmin=C3Dnew->FirstParameter();
630 newparmax=C3Dnew->LastParameter();
633 newparmin=C3Dnew->FirstParameter();
634 newparmax=C3Dnew->LastParameter();
637 if (Vmin.Orientation() == TopAbs_FORWARD) {
638 BB.UpdateVertex(Vmin,newparmin,E,tolmin);
639 BB.UpdateVertex(Vmax,newparmax,E,tolmax);
642 BB.UpdateVertex(Vmin,newparmax,E,tolmin);
643 BB.UpdateVertex(Vmax,newparmin,E,tolmax);
646 // DSBT.Curve3D(E,C3Dnew,newtol); // -merge 04-07-97
647 Curve3D(E,C3Dnew,newtol);
649 // projection des vertex INTERNAL de E pour parametrage
650 // sur la nouvelle courbe C3Dnew de l'arete E
651 TopExp_Explorer exi(E,TopAbs_VERTEX);
652 for (;exi.More(); exi.Next() ) {
653 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
654 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
655 gp_Pnt P = BRep_Tool::Pnt(vi);
656 Standard_Real tolvi=TopOpeBRepTool_ShapeTool::Tolerance(vi);
657 GeomAPI_ProjectPointOnCurve dm(P,C3Dnew,newparmin,newparmax);
658 Standard_Boolean dmdone = dm.Extrema().IsDone();
660 if ( dm.NbPoints() ) {
661 Standard_Real newpar = dm.LowerDistanceParameter();
662 BB.UpdateVertex(vi,newpar,E,tolvi);
668 //=======================================================================
669 //function : ApproxCurves
671 //=======================================================================
673 void TopOpeBRepDS_BuildTool::ApproxCurves
674 (const TopOpeBRepDS_Curve& C,
676 Standard_Integer& inewC,
677 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
679 TopOpeBRepDS_Curve newC1;
680 inewC = HDS->MakeCurve(C,newC1);
681 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
684 // Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
685 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
688 // C1 curves have been approximated by BSplines of degree 1 :
689 // compute new geometry on curves.
691 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
692 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
694 const Handle(Geom_Curve)& C3D = C.Curve();
695 const Handle(Geom2d_Curve)& PC1 = C.Curve1();
696 const Handle(Geom2d_Curve)& PC2 = C.Curve2();
698 // Vmin,Vmax = bounding vertices of edge <E>
699 // and their parameters parmin,parmax .
701 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
702 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
705 if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
706 if (tBUTO) DUMPCURVES(C3D,C);
709 Handle(Geom_Curve) C3Dnew;
710 Handle(Geom2d_Curve) PC1new;
711 Handle(Geom2d_Curve) PC2new;
712 Standard_Real tolreached3d,tolreached2d;
714 Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
716 C3Dnew,PC1new,PC2new,
717 tolreached3d,tolreached2d);
719 Standard_Real newtol,newparmin,newparmax;
720 // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
723 cout<<"TopOpeBRepDS_BuildTool::ApproxCurves : approx failed, leave curves of degree 1"
726 newtol = BRep_Tool::Tolerance(E);
735 (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
736 newtol,newparmin,newparmax);
739 if (!C3Dnew.IsNull()) {
740 newC.DefineCurve(C3Dnew,newtol,Standard_False);
741 newC.SetRange(newparmin,newparmax);
744 if (!PC1new.IsNull()) newC.Curve1(PC1new);
745 if (!PC2new.IsNull()) newC.Curve2(PC2new);
749 //=======================================================================
750 //function : ComputePCurves
752 //=======================================================================
753 Standard_Boolean FUN_getUV
754 (const Handle(Geom_Surface) surf,
755 const Handle(Geom_Curve) C3D,
756 const Standard_Real par3d,
760 gp_Pnt P3d; C3D->D0(par3d,P3d);
761 GeomAPI_ProjectPointOnSurf pons(P3d,surf);
762 if (pons.NbPoints() < 1) return Standard_False;
763 pons.LowerDistanceParameters(u0,v0);
764 return Standard_True;
767 Standard_Boolean FUN_reversePC
768 (Handle(Geom2d_Curve) PCnew,
769 const TopoDS_Face& F,
770 const gp_Pnt& P3DC3D,
771 const Standard_Real par2d,
772 const Standard_Real tol)
774 gp_Pnt2d P2D; PCnew->D0(par2d,P2D);
775 BRepAdaptor_Surface BAS(F,Standard_False);
776 gp_Pnt P3D = BAS.Value(P2D.X(),P2D.Y());
777 Standard_Boolean PCreversed = Standard_False;
778 Standard_Boolean sam = P3D.IsEqual(P3DC3D,tol);
783 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
784 if (tBUTO) {FUN_draw(P3DC3D); FUN_draw(P3D);}
789 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
791 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
792 gp_Dir2d d = L->Direction();
799 Standard_Boolean FUN_makeUisoLineOnSphe
800 (const TopoDS_Face& F, // with geometry the spherical surface
801 const Handle(Geom_Curve) C3D,
802 Handle(Geom2d_Curve) PCnew,
803 const Standard_Real tol3d)
805 // p3df,p3dl : C3d first and last parameters
806 Standard_Real p3df = C3D->FirstParameter();
807 Standard_Real p3dl = C3D->LastParameter();
809 // u0,v0 : C3d(par3d) UV parameters
810 Standard_Real deltainf = 0.243234, deltasup = 0.543345;
811 Standard_Real par3dinf = (1-deltainf)*p3df + deltainf*p3dl;
812 Standard_Real par3dsup = (1-deltasup)*p3df + deltasup*p3dl;
813 Standard_Real uinf,vinf,usup,vsup;
814 Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
815 if (!FUN_getUV(surf,C3D,par3dinf,uinf,vinf)) return Standard_False;
816 if (!FUN_getUV(surf,C3D,par3dsup,usup,vsup)) return Standard_False;
817 Standard_Real tol = Precision::Parametric(tol3d);
818 if (Abs(uinf-usup) > tol) return Standard_False;
820 // Standard_Real deltav = vsup-vinf;
823 Standard_Boolean isvgrowing = (vsup - vinf > -tol);
825 if (isvgrowing) vdir = gp_Dir2d(0,1);
826 else vdir = gp_Dir2d(0,-1);
828 gp_Pnt2d origin(uinf,vinf);
829 origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
830 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
832 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
833 L->SetLin2d(gp_Lin2d(origin,vdir));
836 Standard_Boolean trc = TopOpeBRepDS_GettraceBUTO();
838 FUN_draw(gp_Pnt2d(uinf,vinf));
839 FUN_draw(gp_Pnt2d(usup,vsup));
840 FUN_draw(L,p3dl-p3df);
846 return Standard_True;
849 void TopOpeBRepDS_BuildTool::ComputePCurves
850 (const TopOpeBRepDS_Curve& C,
852 TopOpeBRepDS_Curve& newC,
853 const Standard_Boolean comppc1,
854 const Standard_Boolean comppc2,
855 const Standard_Boolean compc3d) const
858 // Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
859 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
860 Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
863 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
864 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
866 const Handle(Geom_Curve)& C3D = C.Curve();
868 // const Handle(Geom2d_Curve)& PC1 = C.Curve1();
869 // const Handle(Geom2d_Curve)& PC2 = C.Curve2();
872 // get bounding vertices Vmin,Vmax supported by the new edge <E>
873 // and their corresponding parameters parmin,parmax .
875 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
876 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
879 if (tBUTO) cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
880 if (tBUTO) DUMPCURVES(C3D,C);
883 Handle(Geom2d_Curve) PC1new;
884 Handle(Geom2d_Curve) PC2new;
887 Standard_Real tolreached2d1, tolreached2d2, r1, r2, tol=0;
888 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3D,tolreached2d1);
889 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3D,tolreached2d2);
891 r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
892 r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
897 if (!PC1new.IsNull()) newC.Curve1(PC1new);
898 if (!PC2new.IsNull()) newC.Curve2(PC2new);
903 Handle(Geom_Curve) C3Dnew = C3D;
905 if ( C3D->IsPeriodic() ) {
906 // ellipse on cone : periodize parmin,parmax
907 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
909 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
910 else { f = parmax; l = parmin; }
911 parmin = f; parmax = l;
912 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
913 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
916 if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
917 if (tBUTO||tTRPE) cout<<" --> parmin,parmax "<<parmin<<","<<parmax<<endl;
921 Standard_Real tolreached3d = C.Tolerance();
922 Standard_Real tolreached2d1 = C.Tolerance();
923 Standard_Real tolreached2d2 = C.Tolerance();
925 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
926 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
928 Standard_Real newtol,newparmin,newparmax;
929 UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
930 newtol,newparmin,newparmax);
932 // xpu : suite merge : 07-07-97
934 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
935 // est une isos de la sphere
936 // NYI : enlever FUN_reversePC
937 Standard_Boolean UisoLineOnSphe1 = Standard_False;
938 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
939 if (UisoLineOnSphe1) ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
941 Standard_Boolean UisoLineOnSphe2 = Standard_False;
942 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
943 if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
945 // xpu : suite merge : 07-07-97
947 if (!C3Dnew.IsNull()) {
948 newC.Curve(C3Dnew,newtol);
949 newC.SetRange(newparmin, newparmax);
951 if (!PC1new.IsNull()) newC.Curve1(PC1new);
952 if (!PC2new.IsNull()) newC.Curve2(PC2new);
955 if (tBUTO) DUMPCURVES(C3Dnew,newC);
959 //=======================================================================
960 //function : PutPCurves
962 //=======================================================================
964 void TopOpeBRepDS_BuildTool::PutPCurves
965 (const TopOpeBRepDS_Curve& newC,
967 const Standard_Boolean comppc1,
968 const Standard_Boolean comppc2) const
971 TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
972 Handle(Geom2d_Curve) PC1 = newC.Curve1();
973 if (!PC1.IsNull() && comppc1) {
977 TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
978 Handle(Geom2d_Curve) PC2 = newC.Curve2();
979 if (!PC2.IsNull() && comppc2) {
985 //=======================================================================
986 //function : RecomputeCurves
988 //=======================================================================
990 void TopOpeBRepDS_BuildTool::RecomputeCurves
991 (const TopOpeBRepDS_Curve& C,
992 // const TopoDS_Edge& oldE,
995 Standard_Integer& inewC,
996 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
998 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
999 const Standard_Boolean compc3d = GT.CompC3D();
1000 const Standard_Boolean comppc1 = GT.CompPC1();
1001 const Standard_Boolean comppc2 = GT.CompPC2();
1002 const Standard_Boolean comppc = comppc1 || comppc2;
1003 const Standard_Boolean iswalk = C.IsWalk();
1004 const Standard_Boolean approx = Approximation();
1006 const Handle(Geom_Curve)& C3D = C.Curve();
1007 if (comppc1 && C.Shape1().IsNull()) Standard_ProgramError::Raise
1008 ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1009 if (comppc2 && C.Shape2().IsNull()) Standard_ProgramError::Raise
1010 ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1011 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(E,Vmin,Vmax);
1012 if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1013 ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1014 if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1015 ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1017 if (iswalk && approx) {
1018 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1019 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1020 ApproxCurves(C, E, inewC, HDS);
1021 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1022 PutPCurves(newC, E, comppc1, comppc2);
1024 // else if (iswalk && interpol) {
1025 // InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
1026 // TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1027 // PutPCurves(newC, E, comppc1, comppc2);
1032 TopOpeBRepDS_Curve newC1;
1033 inewC = HDS->MakeCurve(C,newC1);
1034 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1035 if(iswalk && !approx) {
1036 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1037 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1038 newC.Curve1(C.Curve1());
1039 newC.Curve2(C.Curve2());
1042 ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);
1043 PutPCurves(newC, E, comppc1, comppc2);
1048 //=======================================================================
1049 //function : CopyFace
1051 //=======================================================================
1053 void TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin,
1054 TopoDS_Shape& Fou)const
1056 Fou = Fin.EmptyCopied();
1060 //=======================================================================
1061 //function : AddEdgeVertex
1063 //=======================================================================
1065 void TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
1067 const TopoDS_Shape& V)const
1069 myBuilder.Add(Eou,V);
1070 TopoDS_Edge e1 = TopoDS::Edge(Ein);
1071 TopoDS_Edge e2 = TopoDS::Edge(Eou);
1072 TopoDS_Vertex v1 = TopoDS::Vertex(V);
1073 myBuilder.Transfert(e1,e2,v1,v1);
1077 //=======================================================================
1078 //function : AddEdgeVertex
1080 //=======================================================================
1082 void TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E,
1083 const TopoDS_Shape& V)const
1089 //=======================================================================
1090 //function : AddWireEdge
1092 //=======================================================================
1094 void TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W,
1095 const TopoDS_Shape& E)const
1101 //=======================================================================
1102 //function : AddFaceWire
1104 //=======================================================================
1106 void TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F,
1107 const TopoDS_Shape& W)const
1113 //=======================================================================
1114 //function : AddShellFace
1116 //=======================================================================
1118 void TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh,
1119 const TopoDS_Shape& F)const
1121 myBuilder.Add(Sh,F);
1125 //=======================================================================
1126 //function : AddSolidShell
1128 //=======================================================================
1130 void TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S,
1131 const TopoDS_Shape& Sh)const
1133 myBuilder.Add(S,Sh);
1137 //=======================================================================
1138 //function : Parameter
1140 //=======================================================================
1142 void TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E,
1143 const TopoDS_Shape& V,
1144 const Standard_Real P)const
1146 const TopoDS_Edge& e = TopoDS::Edge(E);
1147 const TopoDS_Vertex& v = TopoDS::Vertex(V);
1148 Standard_Real p = P;
1151 TopLoc_Location loc; Standard_Real f,l;
1152 Handle(Geom_Curve) C = BRep_Tool::Curve(e,loc,f,l);
1153 if ( !C.IsNull() && C->IsPeriodic()) {
1154 Standard_Real per = C->Period();
1156 TopAbs_Orientation oV;
1158 TopAbs_Orientation oV=TopAbs_FORWARD;
1160 TopExp_Explorer exV(e,TopAbs_VERTEX);
1161 for (; exV.More(); exV.Next()) {
1162 const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
1163 if ( vofe.IsSame(v) ) {
1164 oV = vofe.Orientation();
1169 if ( oV == TopAbs_REVERSED ) {
1171 Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
1173 if (TopOpeBRepDS_GettraceBUTO() ) {
1174 cout<<"BuildTool Parameter : "<<p<<" --> "<<pp<<endl;
1183 myBuilder.UpdateVertex(v,p,e,
1184 0); // NYI : Tol on new vertex ??
1187 //=======================================================================
1190 //=======================================================================
1192 void TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E,
1193 const Standard_Real first,
1194 const Standard_Real last)const
1196 myBuilder.Range(TopoDS::Edge(E),first,last);
1200 //=======================================================================
1201 //function : UpdateEdge
1203 //=======================================================================
1205 void TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
1206 TopoDS_Shape& Eou)const
1208 TopLoc_Location loc;
1209 Standard_Real f1,l1;
1210 Standard_Real f2,l2;
1211 Handle(Geom_Curve) Cin = BRep_Tool::Curve(TopoDS::Edge(Ein),loc,f1,l1);
1212 Handle(Geom_Curve) Cou = BRep_Tool::Curve(TopoDS::Edge(Eou),loc,f2,l2);
1213 if (Cin.IsNull() || Cou.IsNull()) return;
1215 if ( Cou->IsPeriodic() ) {
1216 Standard_Real f2n = f2, l2n = l2;
1218 ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1221 if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1223 cout<<"UpdateEdge f1,l1 "<<f1<<" "<<l1<<endl;
1224 cout<<"UpdateEdge f2,l2 "<<f2<<" "<<l2<<" "<<endl;
1225 cout<<"UpdateEdge f2n,l2n "<<f2n<<" "<<l2n<<endl;
1227 for (ex.Init(Eou,TopAbs_VERTEX); ex.More(); ex.Next()) {
1228 TopoDS_Vertex v = TopoDS::Vertex(ex.Current());
1229 Standard_Real par = BRep_Tool::Parameter(v,TopoDS::Edge(Eou));
1230 TopAbs_Orientation o = v.Orientation();
1231 cout<<"BuildTool vertex ";TopAbs::Print(o,cout); cout<<" "<<par<<endl;
1239 //=======================================================================
1240 //function : Project
1241 //purpose : project a vertex on a curve
1242 //=======================================================================
1244 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1245 const TopoDS_Vertex& V,
1248 gp_Pnt P = BRep_Tool::Pnt(V);
1249 Standard_Real tol = BRep_Tool::Tolerance(V);
1250 GeomAdaptor_Curve GAC(C);
1251 Extrema_ExtPC extrema(P,GAC);
1252 if (extrema.IsDone()) {
1253 Standard_Integer i,n = extrema.NbExt();
1254 for (i = 1; i <= n; i++) {
1255 if (extrema.IsMin(i)) {
1256 Extrema_POnCurv EPOC = extrema.Point(i);
1257 if (P.Distance(EPOC.Value()) <= tol) {
1258 p = EPOC.Parameter();
1259 return Standard_True;
1264 return Standard_False;
1268 //=======================================================================
1269 //function : Parameter
1271 //=======================================================================
1273 void TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1275 TopoDS_Shape& V)const
1277 Standard_Real newparam;
1278 Project(C.Curve(),TopoDS::Vertex(V),newparam);
1279 Parameter(E,V,newparam);
1283 //=======================================================================
1284 //function : Curve3D
1286 //=======================================================================
1288 void TopOpeBRepDS_BuildTool::Curve3D
1290 const Handle(Geom_Curve)& C,
1291 const Standard_Real Tol)const
1293 myBuilder.UpdateEdge(TopoDS::Edge(E),
1299 //=======================================================================
1300 //function : TranslateOnPeriodic
1302 //=======================================================================
1304 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1307 Handle(Geom2d_Curve)& PC) const
1309 // get range C3Df,C3Dl of 3d curve C3D of E
1311 Standard_Real C3Df,C3Dl;
1312 // Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
1313 Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl); // 13-07-97: xpu
1315 Standard_Real first = C3Df, last = C3Dl;
1316 if (C3D->IsPeriodic()) {
1317 if ( last < first ) last += Abs(first - last);
1320 // jyl-xpu : 13-06-97 :
1321 // if <PC> is U isoline on sphere, a special parametrization
1322 // is to provide, we compute <PC> (which is a line) bounds
1324 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1325 Standard_Boolean newv = Standard_True;
1327 Standard_Real du,dv;
1330 Standard_Real t =(first+last)*.5;
1332 Standard_Real u1 = ptest.X(), u2 = u1;
1333 Standard_Real v1 = ptest.Y(), v2 = v1;
1336 if (UisoLineOnSphe) {
1337 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl);
1338 GeomAdaptor_Curve GC(c3d); gp_Pnt p3dtest = GC.Value(t);
1339 Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(F));
1340 GeomAPI_ProjectPointOnSurf pons(p3dtest,surf);
1341 if (!(pons.NbPoints() < 1))
1342 pons.LowerDistanceParameters(u2,v2);
1343 } else TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1345 if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1346 du = u2 - u1, dv = v2 - v1;
1348 if ( du != 0. || dv != 0.) {
1350 if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1352 cout<<"TranslateOnPeriodic : Curve range "<<C3Df<<" "<<C3Dl<<endl;
1353 Standard_Real PCf,PCl;
1354 BRep_Tool::Range(TopoDS::Edge(E),TopoDS::Face(F),PCf,PCl);
1355 cout<<"TranslateOnPeriodic : PCurve range "<<PCf<<" "<<PCl<<endl;
1356 cout<<"TranslateOnPeriodic : translation "<<du<<" "<<dv<<endl;
1359 // translate curve PC of du,dv
1360 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(PC->Copy());
1361 PCT->Translate(gp_Vec2d(du,dv));
1367 // RLE - IAB 16 june 94
1368 // should be provided by the BRep_Builder
1370 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1372 const TopoDS_Face& F,
1373 const TopAbs_Orientation O,
1374 const Handle(Geom2d_Curve)& C)
1376 // check if there is already a pcurve on non planar faces
1378 Handle(Geom2d_Curve) OC;
1380 Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1382 OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1385 B.UpdateEdge(E,C,F,Precision::Confusion());
1387 Standard_Boolean degen = BRep_Tool::Degenerated(E);
1389 if (O == TopAbs_REVERSED)
1390 B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1392 B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1398 //------------------------------------------------------------------------
1399 static void DUMPPCURVE(const TopoDS_Edge& EE,
1400 const TopoDS_Face& FF,
1401 const Handle(Geom2d_Curve)& PC)
1402 //------------------------------------------------------------------------
1404 TopLoc_Location L; Standard_Real Cf,Cl;
1405 Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1406 if (C->IsPeriodic()) {
1408 cout<<"DUMPPCURVE : ";cout<<" face "; ::PrintSurface(FF,cout); cout<<endl;
1409 cout<<"PCurve type : ";TopOpeBRepDS_Dumper::PrintType(PC,cout); cout<<endl;
1411 if (::GetOrigin(C,oC))
1412 cout<<"(E)Curve origin : "<<oC.X()<<" "<<oC.Y()<<" "<<oC.Z()<<endl;
1413 cout<<"(E)Curve range : Cf,Cl = "<<Cf<<" "<<Cl<<endl;
1415 Standard_Real PCf,PCl;
1416 PCf = PC->FirstParameter(); PCl = PC->LastParameter();
1418 if (::GetOrigin(PC,oPC))
1419 cout<<"(PC)PCurve origin : "<<oPC.X()<<" "<<oPC.Y()<<endl;
1420 cout<<"(PC)PCurve range : PCf,PCl = "<<PCf<<" "<<PCl<<endl;
1425 //=======================================================================
1428 //=======================================================================
1430 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1432 const Handle(Geom2d_Curve)& PC)const
1434 if ( ! PC.IsNull() ) {
1435 TopoDS_Face FF = TopoDS::Face(F);
1436 TopoDS_Edge EE = TopoDS::Edge(E);
1437 Handle(Geom2d_Curve) PCT = PC;
1441 Standard_Boolean trc = Standard_False;
1442 if (trc) FUN_draw(FF);
1443 if (trc) FUN_draw(EE);
1444 if (trc) FUN_draw(PC,0.);
1446 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1449 // pour iab, ajout de Translate
1450 Standard_Boolean tran = myTranslate;
1452 if ( TopOpeBRepDS_GettraceSANTRAN()) {
1453 tran = Standard_False;
1454 cout<<"SANS translation de pcurve"<<endl;
1459 // recompute twice the pcurve boundaries if OverWrite
1460 // if the pcurve <PC> is U isoline on sphere -> to avoid.
1461 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1462 Standard_Boolean overwrite = UisoLineOnSphe? Standard_False:myOverWrite;
1466 TranslateOnPeriodic(F,E,PCT);
1469 myBuilder.UpdateEdge(EE,PCT,FF,0);
1471 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1473 // parametrage sur la nouvelle courbe 2d
1474 TopExp_Explorer exi(E,TopAbs_VERTEX);
1475 for (;exi.More(); exi.Next() ) {
1476 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
1477 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
1478 Standard_Real tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
1479 // NYI tester l'existence d'au moins
1480 // NYI un parametrage de vi sur EE (en 3d ou en 2d)
1481 // NYI --> a faire dans BRep_Tool
1482 Standard_Real newpar = BRep_Tool::Parameter(vi,EE);
1483 myBuilder.UpdateVertex(vi,newpar,EE,FF,tolvi);
1484 } // INTERNAL vertex
1487 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1492 //=======================================================================
1495 //=======================================================================
1497 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1499 const TopOpeBRepDS_Curve& CDS,
1500 const Handle(Geom2d_Curve)& PC)const
1502 if ( ! PC.IsNull() ) {
1503 TopoDS_Face FF = TopoDS::Face(F);
1504 TopoDS_Edge EE = TopoDS::Edge(E);
1506 Handle(Geom2d_Curve) PCT = PC;
1507 Standard_Real CDSmin,CDSmax;
1508 Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1511 TopLoc_Location L; Standard_Real Cf,Cl;
1512 Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1515 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1519 Standard_Boolean deca = (Abs(Cf - CDSmin) > Precision::PConfusion());
1520 Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast(PCT);
1521 Standard_Boolean isline2d = !line2d.IsNull();
1522 Standard_Boolean tran=(rangedef && deca && C->IsPeriodic() && isline2d);
1524 TopLoc_Location Loc;
1525 const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
1526 Standard_Boolean isUperio = Surf->IsUPeriodic();
1527 Standard_Boolean isVperio = Surf->IsVPeriodic();
1528 gp_Dir2d dir2d = line2d->Direction();
1529 Standard_Real delta;
1530 if (isUperio && dir2d.IsParallel(gp::DX2d(),Precision::Angular())) {
1531 delta = (CDSmin - Cf) * dir2d.X();
1532 PCT->Translate(gp_Vec2d(delta,0.));
1534 else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1535 delta = (CDSmin - Cf) * dir2d.Y();
1536 PCT->Translate(gp_Vec2d(0.,delta));
1541 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1544 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1550 //=======================================================================
1551 //function : Orientation
1553 //=======================================================================
1555 void TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S,
1556 const TopAbs_Orientation O)const
1562 //=======================================================================
1563 //function : Orientation
1565 //=======================================================================
1567 TopAbs_Orientation TopOpeBRepDS_BuildTool::Orientation
1568 (const TopoDS_Shape& S) const
1570 return S.Orientation();
1573 //=======================================================================
1576 //=======================================================================
1578 void TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S,
1579 const Standard_Boolean B)const
1585 //=======================================================================
1586 //function : Approximation
1588 //=======================================================================
1590 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1592 return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1595 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1599 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1600 BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1603 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1604 const TopoDS_Shape& newF) const
1608 const Handle(Geom2d_Curve)& PC = BRep_Tool::CurveOnSurface(TopoDS::Edge(E),TopoDS::Face(oldF),f,l);
1609 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
1610 BB.UpdateEdge(TopoDS::Edge(E),PC,TopoDS::Face(newF),tol);
1614 /* // - merge 04-07-97
1615 //=======================================================================
1616 //function : RecomputeCurve
1618 //=======================================================================
1620 void TopOpeBRepDS_BuildTool::RecomputeCurve
1621 (const TopOpeBRepDS_Curve& C1,
1623 TopOpeBRepDS_Curve& C2 ) const
1625 // - C1 curves have been approximated by BSplines of degree 1 :
1627 // - C1.Curve() is non projectable on at least one of the original
1628 // intersecting faces.
1630 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1631 Standard_Boolean compc3d = GT.CompC3D();
1632 Standard_Boolean comppc1 = GT.CompPC1();
1633 Standard_Boolean comppc2 = GT.CompPC2();
1635 const Handle(Geom_Curve)& C3D = C1.Curve();
1636 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1637 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1638 if (comppc1 && C2.Shape1().IsNull()) Standard_ProgramError::Raise
1639 ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1640 if (comppc2 && C2.Shape2().IsNull()) Standard_ProgramError::Raise
1641 ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1642 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
1643 if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1644 ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1645 if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1646 ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1648 Standard_Boolean kbspl1 = Standard_False;
1649 Handle(Geom_BSplineCurve) BS = Handle(Geom_BSplineCurve)::DownCast(C3D);
1650 if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
1651 if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
1652 else RecomputeCurveOnCone(C1,E,C2);
1655 //=======================================================================
1656 //function : RecomputeBSpline1Curve
1658 //=======================================================================
1660 void TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1661 (const TopOpeBRepDS_Curve& C1,
1663 TopOpeBRepDS_Curve& C2) const
1666 Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1667 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1670 // C1 curves have been approximated by BSplines of degree 1 :
1671 // compute new geometry on curves.
1673 TopoDS_Edge& E = TopoDS::Edge(EE);
1675 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1676 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1677 Standard_Boolean compc3d = GT.CompC3D();
1678 Standard_Boolean comppc1 = GT.CompPC1();
1679 Standard_Boolean comppc2 = GT.CompPC2();
1681 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1682 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1684 const Handle(Geom_Curve)& C3D = C1.Curve();
1685 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1686 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1688 // Vmin,Vmax = bounding vertices of edge <E>
1689 // and their parameters parmin,parmax .
1691 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1692 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1695 if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
1696 if (tBUTO) DUMPCURVES(C3D,C1);
1699 Handle(Geom_Curve) C3Dnew;
1700 Handle(Geom2d_Curve) PC1new;
1701 Handle(Geom2d_Curve) PC2new;
1702 Standard_Real tolreached3d,tolreached2d;
1704 if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1706 C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1707 (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1709 if ( comppc1 && (!PC1.IsNull()) ) {
1710 PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1711 (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1713 if ( comppc2 && (!PC2.IsNull()) ) {
1714 PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1715 (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1719 else if ( typec3d == TopOpeBRepTool_APPROX ) {
1720 if (!comppc1 || !comppc2) Standard_NotImplemented::Raise("DSBuildToolAPPROX");
1721 myCurveTool.MakeCurves(parmin,parmax,
1723 C3Dnew,PC1new,PC2new,
1724 tolreached3d,tolreached2d);
1727 else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1728 Standard_NotImplemented::Raise("DSBuildToolINTERPOL");
1731 Standard_Real newtol,newparmin,newparmax;
1732 ::FUN_updateEDGECURVETOL
1733 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1734 newtol,newparmin,newparmax);
1736 if (!C3Dnew.IsNull()) {
1737 C2.DefineCurve(C3Dnew,newtol,Standard_False);
1738 C2.SetRange(newparmin,newparmax);
1740 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1741 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1745 //=======================================================================
1746 //function : RecomputeCurveOnCone
1748 //=======================================================================
1750 void TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1751 (const TopOpeBRepDS_Curve& C1,
1753 TopOpeBRepDS_Curve& C2 ) const
1756 Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1757 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1758 Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
1761 // C1 Pcurves have not been computed because C1 Curve is not projectable
1762 // on one at least of the intersecting faces giving C1 Curve.
1763 // (see TopOpeBRepTool_CurveTool::IsProjectable())
1765 TopoDS_Edge& E = TopoDS::Edge(EE);
1767 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1768 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1769 Standard_Boolean compc3d = GT.CompC3D();
1770 Standard_Boolean comppc1 = GT.CompPC1();
1771 Standard_Boolean comppc2 = GT.CompPC2();
1773 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1774 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1776 const Handle(Geom_Curve)& C3D = C1.Curve();
1777 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1778 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1780 // get bounding vertices Vmin,Vmax supported by the new edge <E>
1781 // and their corresponding parameters parmin,parmax .
1783 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1784 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1787 if (tBUTO) {cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
1788 DUMPCURVES(C3D,C1);}
1791 if ( C3D->IsPeriodic() ) {
1792 // ellipse on cone : periodize parmin,parmax
1793 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1795 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
1796 else { f = parmax; l = parmin; }
1797 parmin = f; parmax = l;
1798 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
1800 if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
1801 if (tBUTO||tTRPE) cout<<" --> parmin,parmax "<<parmin<<","<<parmax<<endl;
1805 Handle(Geom_TrimmedCurve) C3Dnew;
1806 Handle(Geom2d_Curve) PC1new;
1807 Handle(Geom2d_Curve) PC2new;
1808 Standard_Real tolreached3d = C1.Tolerance();
1809 Standard_Real tolreached2d1 = C1.Tolerance();
1810 Standard_Real tolreached2d2 = C1.Tolerance();
1811 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
1812 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
1813 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
1816 if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1819 Standard_Real newtol,newparmin,newparmax;
1820 FUN_updateEDGECURVETOL
1821 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1822 newtol,newparmin,newparmax);
1825 // Standard_Real fac = 0.3798123578771;
1826 // Standard_Real tol = newtol;
1827 // Standard_Real par3d = (1-fac)*newparmin + (fac)*newparmax;
1828 // Standard_Real par2d = par3d - newparmin;
1830 // gp_Pnt P3DC3D; C3D->D0(par3d,P3DC3D);
1832 // Standard_Boolean UisoLineOnSphe1 = Standard_False;
1833 // UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1834 // if (UisoLineOnSphe1) {
1835 // Standard_Real isrev1 =
1836 // ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
1839 // if (tBUTO && isrev1) cout<<"on retourne PC1"<<endl;
1844 // Standard_Boolean UisoLineOnSphe2 = Standard_False;
1845 // UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1846 // if (UisoLineOnSphe2) {
1847 // Standard_Real isrev2 =
1848 // ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
1851 // if (tBUTO && isrev2) cout<<"on retourne PC2"<<endl;
1856 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
1857 // est une isos de la sphere
1858 // NYI : enlever FUN_reversePC
1859 Standard_Boolean UisoLineOnSphe1 = Standard_False;
1860 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1861 if (UisoLineOnSphe1) {
1862 ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
1864 Standard_Boolean UisoLineOnSphe2 = Standard_False;
1865 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1866 if (UisoLineOnSphe2) {
1867 ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1870 if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1871 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1872 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1875 if (tBUTO) DUMPCURVES(C3Dnew,C2);
1877 }*/ // - merge 04-07-97