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 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSNC();
88 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceBUTO();
89 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceTRPE();
90 Standard_EXPORT 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;
202 return Standard_False;
206 Standard_Boolean FUN_UisoLineOnSphe
207 (const TopoDS_Shape& F,
208 const Handle(Geom2d_Curve)& PC)
210 if (PC.IsNull()) return Standard_False;
212 Handle(Geom_Surface) SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
213 Handle(Geom2d_Curve) LLL = ::BASISCURVE2D(PC);
214 Handle(Standard_Type) TS = SSS->DynamicType();
215 Handle(Standard_Type) T2 = LLL->DynamicType();
216 Standard_Boolean issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface));
217 Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
218 Standard_Boolean isisoU = Standard_False;
219 if (issphere && isline2d) {
220 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
221 const gp_Dir2d& d = L->Direction();
222 isisoU = (Abs(d.X()) < Precision::Parametric(Precision::Confusion()));
227 //=======================================================================
228 //function : TopOpeBRepDS_BuildTool
230 //=======================================================================
232 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
233 myCurveTool(TopOpeBRepTool_APPROX),
234 myOverWrite(Standard_True),
235 myTranslate(Standard_True)
239 //=======================================================================
240 //function : TopOpeBRepDS_BuildTool
242 //=======================================================================
244 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
245 (const TopOpeBRepTool_OutCurveType O) :
247 myOverWrite(Standard_True),
248 myTranslate(Standard_True)
252 //=======================================================================
253 //function : TopOpeBRepDS_BuildTool
255 //=======================================================================
257 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
258 (const TopOpeBRepTool_GeomTool& GT) :
260 myOverWrite(Standard_True),
261 myTranslate(Standard_True)
265 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
270 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
275 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
280 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
285 //=======================================================================
286 //function : GetGeomTool
288 //=======================================================================
290 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const
292 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
296 //=======================================================================
297 //function : ChangeGeomTool
299 //=======================================================================
301 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
303 TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
307 //=======================================================================
308 //function : MakeVertex
310 //=======================================================================
312 void TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V,
313 const TopOpeBRepDS_Point& P)const
315 myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
319 //-----------------------------------------------------------------------
320 static Standard_OStream& DUMPPNT(const gp_Pnt& P, Standard_OStream& OS)
321 //-----------------------------------------------------------------------
322 { OS<<P.X()<<" "<<P.Y()<<" "<<P.Z(); return OS; }
325 //=======================================================================
326 //function : MakeEdge
328 //=======================================================================
330 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
331 const TopOpeBRepDS_Curve& C)const
333 // Gestion des courbes nulles pour carreaux pointus
336 if (C.Curve().IsNull()) {
337 myBuilder.MakeEdge(TopoDS::Edge(E));
338 myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
342 const Handle(Geom_Curve)& GC = C.Curve();
343 myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
345 Standard_Boolean addorigin = Standard_False;
346 Standard_Boolean setrange = Standard_False;
349 if ( GC->IsClosed() ) {
350 // in case of a closed curve, insert in E a vertex located at the origin
353 Standard_Real first = GC->FirstParameter();
354 gp_Pnt P = GC->Value(first);
355 myBuilder.MakeVertex(V,P,C.Tolerance());
360 // If the curve is a degree 1 bspline set the range to 1 .. NbPoles
361 Handle(Geom_BSplineCurve) BSC = Handle(Geom_BSplineCurve)::DownCast(GC);
363 if (BSC->Degree() == 1) {
364 myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
366 if (TopOpeBRepDS_GettraceBUTO()) {
367 cout<<endl<<"TopOpeBRepDS_BuildTool : ";
368 cout<<"new range of "<< 1 <<" "<<BSC->NbPoles()<<endl;
375 if (TopOpeBRepDS_GettraceBUTO()) {
376 cout<<"TopOpeBRepDS_BuildTool : ";
377 cout<<"vertices on parameter "<<first<<endl;
378 cout<<" point is "; DUMPPNT(P,cout); cout<<endl;
385 Standard_Real first,last;
386 Standard_Boolean rangedef = C.Range(first,last);
390 if (TopOpeBRepDS_GettraceBUTO()) {
391 cout<<"TopOpeBRepDS_BuildTool : ";
392 cout<<"set edge range : "<<first<<" "<<last<<endl;
399 //=======================================================================
400 //function : MakeEdge
402 //=======================================================================
404 void TopOpeBRepDS_BuildTool::MakeEdge
406 const TopOpeBRepDS_Curve& C,
407 const TopOpeBRepDS_DataStructure& BDS) const
409 // Gestion des courbes nulles pour carreaux pointus
412 TopoDS_Edge& EE = TopoDS::Edge(E);
414 if (C.Curve().IsNull()) {
415 myBuilder.MakeEdge(EE);
416 myBuilder.Degenerated(EE,Standard_True);
418 // Creation d'une arete avec PCurve connectee a la BDS Curve
420 Handle(TopOpeBRepDS_Interference) I = C.GetSCI1();
421 Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI;
422 SCI=Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(I);
423 Standard_Integer iS = SCI->Support();
424 const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
425 const Handle(Geom_Surface)& GS = DSS.Surface();
426 const Handle(Geom2d_Curve)& PC = SCI->PCurve();
427 myBuilder.UpdateEdge(EE,PC,GS,TopLoc_Location(),DSS.Tolerance());
431 const Handle(Geom_Curve)& GC = C.Curve();
432 myBuilder.MakeEdge(EE,GC,C.Tolerance());
437 //=======================================================================
438 //function : MakeEdge
440 //=======================================================================
442 void TopOpeBRepDS_BuildTool::MakeEdge
444 const Handle(Geom_Curve)& C,
445 const Standard_Real Tol)const
447 myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
451 //=======================================================================
452 //function : MakeEdge
454 //=======================================================================
456 void TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
458 myBuilder.MakeEdge(TopoDS::Edge(E));
462 //=======================================================================
463 //function : MakeWire
465 //=======================================================================
467 void TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const
469 myBuilder.MakeWire(TopoDS::Wire(W));
473 //=======================================================================
474 //function : MakeFace
476 //=======================================================================
478 void TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F,
479 const TopOpeBRepDS_Surface& S)const
481 myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
485 //=======================================================================
486 //function : MakeShell
488 //=======================================================================
490 void TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const
492 myBuilder.MakeShell(TopoDS::Shell(Sh));
496 //=======================================================================
497 //function : MakeSolid
499 //=======================================================================
501 void TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const
503 myBuilder.MakeSolid(TopoDS::Solid(S));
507 //=======================================================================
508 //function : CopyEdge
510 //=======================================================================
512 void TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein,
513 TopoDS_Shape& Eou)const
516 // Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
517 // apres modification de la primitive Sphere pour parametrisation de
518 // l'arete meridienne en -pi/2,+pi/2.
519 // Ein est l'arete de couture complete d'une sphere complete
520 // BRep_Tool::Range(Ein) --> -pi/2,+pi/2
521 // BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
522 // NYI reflexion sur la notion de Range d'une arete et de la geometrie
523 // NYI sous jacente dans le cas ou, par construction, les vertex d'une
524 // NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
525 // NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
526 // On redefinit desormais le range de l'arete Eou, a la place de se
527 // contenter du simplissime Eou = Ein.EmptyCopied();
528 // merci les amis : correction bug PRO2586
531 TopoDS_Edge E1 = TopoDS::Edge(Ein);
532 BRep_Tool::Range(E1,f,l);
533 Eou = Ein.EmptyCopied();
534 TopoDS_Edge E2 = TopoDS::Edge(Eou);
535 myBuilder.Range(E2,f,l);
539 //=======================================================================
540 //function : GetOrientedEdgeVertices
542 //=======================================================================
544 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
546 TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
547 Standard_Real& Parmin, Standard_Real& Parmax) const
549 if ( E.Orientation() == TopAbs_FORWARD)
550 TopExp::Vertices(E,Vmin,Vmax);
552 TopExp::Vertices(E,Vmax,Vmin);
553 if ( !Vmin.IsNull() && !Vmax.IsNull()) {
554 Parmin = BRep_Tool::Parameter(Vmin,E);
555 Parmax = BRep_Tool::Parameter(Vmax,E);
559 //=======================================================================
560 //function : UpdateEdgeCurveTol
562 //=======================================================================
564 void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
565 //(const TopoDS_Face& F1,const TopoDS_Face& F2,
566 (const TopoDS_Face& ,const TopoDS_Face& ,
567 TopoDS_Edge& E, const Handle(Geom_Curve)& C3Dnew,
568 // const Standard_Real tol3d,
569 const Standard_Real ,
570 // const Standard_Real tol2d1,
571 const Standard_Real ,
572 // const Standard_Real tol2d2,
573 const Standard_Real ,
574 Standard_Real& newtol,
575 Standard_Real& newparmin,
576 Standard_Real& newparmax) const
579 if (C3Dnew.IsNull()) return;
582 // newtol = max des tolerances atteintes en 3d
583 // JMB le 06 Juillet 1999
584 // les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade,
585 // elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
586 // 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
587 // d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
588 // plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la topologie
589 // a coder des tolerances enormes dans les pieces resultats rendant celles-ci inexpoitables.
590 // De plus on essayait de rafiner la tolerance en appelant les UResolution sur les surfaces support.
591 // sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et peut amener a des valeurs
593 // On decide donc de laisser la tolerance de l'edge telle qu'elle est afin d'avoir un comportement similaire
594 // a 2.0. Jusqu'a present on a constate que des problemes avec la methode de calcul d'erreur des approx.
598 // Standard_Real r1,r2;
599 // r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
600 // r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
602 // if (r1>newtol) newtol=r1;
603 // if (r2>newtol) newtol=r2;
605 // if (TopOpeBRepDS_GettraceDSNC()) cout<<"newtol = "<<newtol<<endl;
610 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
611 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
613 Standard_Real tolmin=BRep_Tool::Tolerance(Vmin);
614 if(newtol>tolmin) tolmin=newtol;
615 Standard_Real tolmax=BRep_Tool::Tolerance(Vmax);
616 if(newtol>tolmax) tolmax=newtol;
619 // newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
620 // newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
623 Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
625 Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
630 newparmin=C3Dnew->FirstParameter();
631 newparmax=C3Dnew->LastParameter();
634 newparmin=C3Dnew->FirstParameter();
635 newparmax=C3Dnew->LastParameter();
638 if (Vmin.Orientation() == TopAbs_FORWARD) {
639 BB.UpdateVertex(Vmin,newparmin,E,tolmin);
640 BB.UpdateVertex(Vmax,newparmax,E,tolmax);
643 BB.UpdateVertex(Vmin,newparmax,E,tolmin);
644 BB.UpdateVertex(Vmax,newparmin,E,tolmax);
647 // DSBT.Curve3D(E,C3Dnew,newtol); // -merge 04-07-97
648 Curve3D(E,C3Dnew,newtol);
650 // projection des vertex INTERNAL de E pour parametrage
651 // sur la nouvelle courbe C3Dnew de l'arete E
652 TopExp_Explorer exi(E,TopAbs_VERTEX);
653 for (;exi.More(); exi.Next() ) {
654 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
655 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
656 gp_Pnt P = BRep_Tool::Pnt(vi);
657 Standard_Real tolvi=TopOpeBRepTool_ShapeTool::Tolerance(vi);
658 GeomAPI_ProjectPointOnCurve dm(P,C3Dnew,newparmin,newparmax);
659 Standard_Boolean dmdone = dm.Extrema().IsDone();
661 if ( dm.NbPoints() ) {
662 Standard_Real newpar = dm.LowerDistanceParameter();
663 BB.UpdateVertex(vi,newpar,E,tolvi);
669 //=======================================================================
670 //function : ApproxCurves
672 //=======================================================================
674 void TopOpeBRepDS_BuildTool::ApproxCurves
675 (const TopOpeBRepDS_Curve& C,
677 Standard_Integer& inewC,
678 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
680 TopOpeBRepDS_Curve newC1;
681 inewC = HDS->MakeCurve(C,newC1);
682 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
685 // Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
686 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
689 // C1 curves have been approximated by BSplines of degree 1 :
690 // compute new geometry on curves.
692 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
693 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
695 const Handle(Geom_Curve)& C3D = C.Curve();
696 const Handle(Geom2d_Curve)& PC1 = C.Curve1();
697 const Handle(Geom2d_Curve)& PC2 = C.Curve2();
699 // Vmin,Vmax = bounding vertices of edge <E>
700 // and their parameters parmin,parmax .
702 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
703 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
706 if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
707 if (tBUTO) DUMPCURVES(C3D,C);
710 Handle(Geom_Curve) C3Dnew;
711 Handle(Geom2d_Curve) PC1new;
712 Handle(Geom2d_Curve) PC2new;
713 Standard_Real tolreached3d,tolreached2d;
715 Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
717 C3Dnew,PC1new,PC2new,
718 tolreached3d,tolreached2d);
720 Standard_Real newtol,newparmin,newparmax;
721 // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
724 cout<<"TopOpeBRepDS_BuildTool::ApproxCurves : approx failed, leave curves of degree 1"
727 newtol = BRep_Tool::Tolerance(E);
736 (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
737 newtol,newparmin,newparmax);
740 if (!C3Dnew.IsNull()) {
741 newC.DefineCurve(C3Dnew,newtol,Standard_False);
742 newC.SetRange(newparmin,newparmax);
745 if (!PC1new.IsNull()) newC.Curve1(PC1new);
746 if (!PC2new.IsNull()) newC.Curve2(PC2new);
750 //=======================================================================
751 //function : ComputePCurves
753 //=======================================================================
754 Standard_Boolean FUN_getUV
755 (const Handle(Geom_Surface) surf,
756 const Handle(Geom_Curve) C3D,
757 const Standard_Real par3d,
761 gp_Pnt P3d; C3D->D0(par3d,P3d);
762 GeomAPI_ProjectPointOnSurf pons(P3d,surf);
763 if (pons.NbPoints() < 1) return Standard_False;
764 pons.LowerDistanceParameters(u0,v0);
765 return Standard_True;
768 Standard_Boolean FUN_reversePC
769 (Handle(Geom2d_Curve) PCnew,
770 const TopoDS_Face& F,
771 const gp_Pnt& P3DC3D,
772 const Standard_Real par2d,
773 const Standard_Real tol)
775 gp_Pnt2d P2D; PCnew->D0(par2d,P2D);
776 BRepAdaptor_Surface BAS(F,Standard_False);
777 gp_Pnt P3D = BAS.Value(P2D.X(),P2D.Y());
778 Standard_Boolean PCreversed = Standard_False;
779 Standard_Boolean sam = P3D.IsEqual(P3DC3D,tol);
784 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
785 if (tBUTO) {FUN_draw(P3DC3D); FUN_draw(P3D);}
790 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
792 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
793 gp_Dir2d d = L->Direction();
800 Standard_Boolean FUN_makeUisoLineOnSphe
801 (const TopoDS_Face& F, // with geometry the spherical surface
802 const Handle(Geom_Curve) C3D,
803 Handle(Geom2d_Curve) PCnew,
804 const Standard_Real tol3d)
806 // p3df,p3dl : C3d first and last parameters
807 Standard_Real p3df = C3D->FirstParameter();
808 Standard_Real p3dl = C3D->LastParameter();
810 // u0,v0 : C3d(par3d) UV parameters
811 Standard_Real deltainf = 0.243234, deltasup = 0.543345;
812 Standard_Real par3dinf = (1-deltainf)*p3df + deltainf*p3dl;
813 Standard_Real par3dsup = (1-deltasup)*p3df + deltasup*p3dl;
814 Standard_Real uinf,vinf,usup,vsup;
815 Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
816 if (!FUN_getUV(surf,C3D,par3dinf,uinf,vinf)) return Standard_False;
817 if (!FUN_getUV(surf,C3D,par3dsup,usup,vsup)) return Standard_False;
818 Standard_Real tol = Precision::Parametric(tol3d);
819 if (Abs(uinf-usup) > tol) return Standard_False;
821 // Standard_Real deltav = vsup-vinf;
824 Standard_Boolean isvgrowing = (vsup - vinf > -tol);
826 if (isvgrowing) vdir = gp_Dir2d(0,1);
827 else vdir = gp_Dir2d(0,-1);
829 gp_Pnt2d origin(uinf,vinf);
830 origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
831 Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
833 Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
834 L->SetLin2d(gp_Lin2d(origin,vdir));
837 Standard_Boolean trc = TopOpeBRepDS_GettraceBUTO();
839 FUN_draw(gp_Pnt2d(uinf,vinf));
840 FUN_draw(gp_Pnt2d(usup,vsup));
841 FUN_draw(L,p3dl-p3df);
847 return Standard_True;
850 void TopOpeBRepDS_BuildTool::ComputePCurves
851 (const TopOpeBRepDS_Curve& C,
853 TopOpeBRepDS_Curve& newC,
854 const Standard_Boolean comppc1,
855 const Standard_Boolean comppc2,
856 const Standard_Boolean compc3d) const
859 // Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
860 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
861 Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
864 const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
865 const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
867 const Handle(Geom_Curve)& C3D = C.Curve();
869 // const Handle(Geom2d_Curve)& PC1 = C.Curve1();
870 // const Handle(Geom2d_Curve)& PC2 = C.Curve2();
873 // get bounding vertices Vmin,Vmax supported by the new edge <E>
874 // and their corresponding parameters parmin,parmax .
876 TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
877 GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
880 if (tBUTO) cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
881 if (tBUTO) DUMPCURVES(C3D,C);
884 Handle(Geom2d_Curve) PC1new;
885 Handle(Geom2d_Curve) PC2new;
888 Standard_Real tolreached2d1, tolreached2d2, r1, r2, tol=0;
889 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3D,tolreached2d1);
890 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3D,tolreached2d2);
892 r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
893 r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
898 if (!PC1new.IsNull()) newC.Curve1(PC1new);
899 if (!PC2new.IsNull()) newC.Curve2(PC2new);
904 Handle(Geom_Curve) C3Dnew = C3D;
906 if ( C3D->IsPeriodic() ) {
907 // ellipse on cone : periodize parmin,parmax
908 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
910 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
911 else { f = parmax; l = parmin; }
912 parmin = f; parmax = l;
913 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
914 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
917 if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
918 if (tBUTO||tTRPE) cout<<" --> parmin,parmax "<<parmin<<","<<parmax<<endl;
922 Standard_Real tolreached3d = C.Tolerance();
923 Standard_Real tolreached2d1 = C.Tolerance();
924 Standard_Real tolreached2d2 = C.Tolerance();
926 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
927 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
929 Standard_Real newtol,newparmin,newparmax;
930 UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
931 newtol,newparmin,newparmax);
933 // xpu : suite merge : 07-07-97
935 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
936 // est une isos de la sphere
937 // NYI : enlever FUN_reversePC
938 Standard_Boolean UisoLineOnSphe1 = Standard_False;
939 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
940 if (UisoLineOnSphe1) ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
942 Standard_Boolean UisoLineOnSphe2 = Standard_False;
943 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
944 if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
946 // xpu : suite merge : 07-07-97
948 if (!C3Dnew.IsNull()) {
949 newC.Curve(C3Dnew,newtol);
950 newC.SetRange(newparmin, newparmax);
952 if (!PC1new.IsNull()) newC.Curve1(PC1new);
953 if (!PC2new.IsNull()) newC.Curve2(PC2new);
956 if (tBUTO) DUMPCURVES(C3Dnew,newC);
960 //=======================================================================
961 //function : PutPCurves
963 //=======================================================================
965 void TopOpeBRepDS_BuildTool::PutPCurves
966 (const TopOpeBRepDS_Curve& newC,
968 const Standard_Boolean comppc1,
969 const Standard_Boolean comppc2) const
972 TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
973 Handle(Geom2d_Curve) PC1 = newC.Curve1();
974 if (!PC1.IsNull() && comppc1) {
978 TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
979 Handle(Geom2d_Curve) PC2 = newC.Curve2();
980 if (!PC2.IsNull() && comppc2) {
986 //=======================================================================
987 //function : RecomputeCurves
989 //=======================================================================
991 void TopOpeBRepDS_BuildTool::RecomputeCurves
992 (const TopOpeBRepDS_Curve& C,
993 // const TopoDS_Edge& oldE,
996 Standard_Integer& inewC,
997 const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
999 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1000 const Standard_Boolean compc3d = GT.CompC3D();
1001 const Standard_Boolean comppc1 = GT.CompPC1();
1002 const Standard_Boolean comppc2 = GT.CompPC2();
1003 const Standard_Boolean comppc = comppc1 || comppc2;
1004 const Standard_Boolean iswalk = C.IsWalk();
1005 const Standard_Boolean approx = Approximation();
1007 const Handle(Geom_Curve)& C3D = C.Curve();
1008 if (comppc1 && C.Shape1().IsNull()) Standard_ProgramError::Raise
1009 ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1010 if (comppc2 && C.Shape2().IsNull()) Standard_ProgramError::Raise
1011 ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1012 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(E,Vmin,Vmax);
1013 if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1014 ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1015 if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1016 ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1018 if (iswalk && approx) {
1019 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1020 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1021 ApproxCurves(C, E, inewC, HDS);
1022 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1023 PutPCurves(newC, E, comppc1, comppc2);
1025 // else if (iswalk && interpol) {
1026 // InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
1027 // TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1028 // PutPCurves(newC, E, comppc1, comppc2);
1033 TopOpeBRepDS_Curve newC1;
1034 inewC = HDS->MakeCurve(C,newC1);
1035 TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1036 if(iswalk && !approx) {
1037 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1038 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1039 newC.Curve1(C.Curve1());
1040 newC.Curve2(C.Curve2());
1043 ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);
1044 PutPCurves(newC, E, comppc1, comppc2);
1049 //=======================================================================
1050 //function : CopyFace
1052 //=======================================================================
1054 void TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin,
1055 TopoDS_Shape& Fou)const
1057 Fou = Fin.EmptyCopied();
1061 //=======================================================================
1062 //function : AddEdgeVertex
1064 //=======================================================================
1066 void TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
1068 const TopoDS_Shape& V)const
1070 myBuilder.Add(Eou,V);
1071 TopoDS_Edge e1 = TopoDS::Edge(Ein);
1072 TopoDS_Edge e2 = TopoDS::Edge(Eou);
1073 TopoDS_Vertex v1 = TopoDS::Vertex(V);
1074 myBuilder.Transfert(e1,e2,v1,v1);
1078 //=======================================================================
1079 //function : AddEdgeVertex
1081 //=======================================================================
1083 void TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E,
1084 const TopoDS_Shape& V)const
1090 //=======================================================================
1091 //function : AddWireEdge
1093 //=======================================================================
1095 void TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W,
1096 const TopoDS_Shape& E)const
1102 //=======================================================================
1103 //function : AddFaceWire
1105 //=======================================================================
1107 void TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F,
1108 const TopoDS_Shape& W)const
1114 //=======================================================================
1115 //function : AddShellFace
1117 //=======================================================================
1119 void TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh,
1120 const TopoDS_Shape& F)const
1122 myBuilder.Add(Sh,F);
1126 //=======================================================================
1127 //function : AddSolidShell
1129 //=======================================================================
1131 void TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S,
1132 const TopoDS_Shape& Sh)const
1134 myBuilder.Add(S,Sh);
1138 //=======================================================================
1139 //function : Parameter
1141 //=======================================================================
1143 void TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E,
1144 const TopoDS_Shape& V,
1145 const Standard_Real P)const
1147 const TopoDS_Edge& e = TopoDS::Edge(E);
1148 const TopoDS_Vertex& v = TopoDS::Vertex(V);
1149 Standard_Real p = P;
1152 TopLoc_Location loc; Standard_Real f,l;
1153 Handle(Geom_Curve) C = BRep_Tool::Curve(e,loc,f,l);
1154 if ( !C.IsNull() && C->IsPeriodic()) {
1155 Standard_Real per = C->Period();
1157 TopAbs_Orientation oV;
1159 TopAbs_Orientation oV=TopAbs_FORWARD;
1161 TopExp_Explorer exV(e,TopAbs_VERTEX);
1162 for (; exV.More(); exV.Next()) {
1163 const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
1164 if ( vofe.IsSame(v) ) {
1165 oV = vofe.Orientation();
1170 if ( oV == TopAbs_REVERSED ) {
1172 Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
1174 if (TopOpeBRepDS_GettraceBUTO() ) {
1175 cout<<"BuildTool Parameter : "<<p<<" --> "<<pp<<endl;
1184 myBuilder.UpdateVertex(v,p,e,
1185 0); // NYI : Tol on new vertex ??
1188 //=======================================================================
1191 //=======================================================================
1193 void TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E,
1194 const Standard_Real first,
1195 const Standard_Real last)const
1197 myBuilder.Range(TopoDS::Edge(E),first,last);
1201 //=======================================================================
1202 //function : UpdateEdge
1204 //=======================================================================
1206 void TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
1207 TopoDS_Shape& Eou)const
1209 TopLoc_Location loc;
1210 Standard_Real f1,l1;
1211 Standard_Real f2,l2;
1212 Handle(Geom_Curve) Cin = BRep_Tool::Curve(TopoDS::Edge(Ein),loc,f1,l1);
1213 Handle(Geom_Curve) Cou = BRep_Tool::Curve(TopoDS::Edge(Eou),loc,f2,l2);
1214 if (Cin.IsNull() || Cou.IsNull()) return;
1216 if ( Cou->IsPeriodic() ) {
1217 Standard_Real f2n = f2, l2n = l2;
1219 ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1222 if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1224 cout<<"UpdateEdge f1,l1 "<<f1<<" "<<l1<<endl;
1225 cout<<"UpdateEdge f2,l2 "<<f2<<" "<<l2<<" "<<endl;
1226 cout<<"UpdateEdge f2n,l2n "<<f2n<<" "<<l2n<<endl;
1228 for (ex.Init(Eou,TopAbs_VERTEX); ex.More(); ex.Next()) {
1229 TopoDS_Vertex v = TopoDS::Vertex(ex.Current());
1230 Standard_Real par = BRep_Tool::Parameter(v,TopoDS::Edge(Eou));
1231 TopAbs_Orientation o = v.Orientation();
1232 cout<<"BuildTool vertex ";TopAbs::Print(o,cout); cout<<" "<<par<<endl;
1240 //=======================================================================
1241 //function : Project
1242 //purpose : project a vertex on a curve
1243 //=======================================================================
1245 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1246 const TopoDS_Vertex& V,
1249 gp_Pnt P = BRep_Tool::Pnt(V);
1250 Standard_Real tol = BRep_Tool::Tolerance(V);
1251 GeomAdaptor_Curve GAC(C);
1252 Extrema_ExtPC extrema(P,GAC);
1253 if (extrema.IsDone()) {
1254 Standard_Integer i,n = extrema.NbExt();
1255 for (i = 1; i <= n; i++) {
1256 if (extrema.IsMin(i)) {
1257 Extrema_POnCurv EPOC = extrema.Point(i);
1258 if (P.Distance(EPOC.Value()) <= tol) {
1259 p = EPOC.Parameter();
1260 return Standard_True;
1265 return Standard_False;
1269 //=======================================================================
1270 //function : Parameter
1272 //=======================================================================
1274 void TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1276 TopoDS_Shape& V)const
1278 Standard_Real newparam;
1279 Project(C.Curve(),TopoDS::Vertex(V),newparam);
1280 Parameter(E,V,newparam);
1284 //=======================================================================
1285 //function : Curve3D
1287 //=======================================================================
1289 void TopOpeBRepDS_BuildTool::Curve3D
1291 const Handle(Geom_Curve)& C,
1292 const Standard_Real Tol)const
1294 myBuilder.UpdateEdge(TopoDS::Edge(E),
1300 //=======================================================================
1301 //function : TranslateOnPeriodic
1303 //=======================================================================
1305 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1308 Handle(Geom2d_Curve)& PC) const
1310 // get range C3Df,C3Dl of 3d curve C3D of E
1312 Standard_Real C3Df,C3Dl;
1313 // Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
1314 Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl); // 13-07-97: xpu
1316 Standard_Real first = C3Df, last = C3Dl;
1317 if (C3D->IsPeriodic()) {
1318 if ( last < first ) last += Abs(first - last);
1321 // jyl-xpu : 13-06-97 :
1322 // if <PC> is U isoline on sphere, a special parametrization
1323 // is to provide, we compute <PC> (which is a line) bounds
1325 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1326 Standard_Boolean newv = Standard_True;
1328 Standard_Real du,dv;
1331 Standard_Real t =(first+last)*.5;
1333 Standard_Real u1 = ptest.X(), u2 = u1;
1334 Standard_Real v1 = ptest.Y(), v2 = v1;
1337 if (UisoLineOnSphe) {
1338 Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl);
1339 GeomAdaptor_Curve GC(c3d); gp_Pnt p3dtest = GC.Value(t);
1340 Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(F));
1341 GeomAPI_ProjectPointOnSurf pons(p3dtest,surf);
1342 if (!(pons.NbPoints() < 1))
1343 pons.LowerDistanceParameters(u2,v2);
1344 } else TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1346 if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1347 du = u2 - u1, dv = v2 - v1;
1349 if ( du != 0. || dv != 0.) {
1351 if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1353 cout<<"TranslateOnPeriodic : Curve range "<<C3Df<<" "<<C3Dl<<endl;
1354 Standard_Real PCf,PCl;
1355 BRep_Tool::Range(TopoDS::Edge(E),TopoDS::Face(F),PCf,PCl);
1356 cout<<"TranslateOnPeriodic : PCurve range "<<PCf<<" "<<PCl<<endl;
1357 cout<<"TranslateOnPeriodic : translation "<<du<<" "<<dv<<endl;
1360 // translate curve PC of du,dv
1361 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(PC->Copy());
1362 PCT->Translate(gp_Vec2d(du,dv));
1368 // RLE - IAB 16 june 94
1369 // should be provided by the BRep_Builder
1371 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1373 const TopoDS_Face& F,
1374 const TopAbs_Orientation O,
1375 const Handle(Geom2d_Curve)& C)
1377 // check if there is already a pcurve on non planar faces
1379 Handle(Geom2d_Curve) OC;
1381 Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1383 OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1386 B.UpdateEdge(E,C,F,Precision::Confusion());
1388 Standard_Boolean degen = BRep_Tool::Degenerated(E);
1390 if (O == TopAbs_REVERSED)
1391 B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1393 B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1399 //------------------------------------------------------------------------
1400 static void DUMPPCURVE(const TopoDS_Edge& EE,
1401 const TopoDS_Face& FF,
1402 const Handle(Geom2d_Curve)& PC)
1403 //------------------------------------------------------------------------
1405 TopLoc_Location L; Standard_Real Cf,Cl;
1406 Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1407 if (C->IsPeriodic()) {
1409 cout<<"DUMPPCURVE : ";cout<<" face "; ::PrintSurface(FF,cout); cout<<endl;
1410 cout<<"PCurve type : ";TopOpeBRepDS_Dumper::PrintType(PC,cout); cout<<endl;
1412 if (::GetOrigin(C,oC))
1413 cout<<"(E)Curve origin : "<<oC.X()<<" "<<oC.Y()<<" "<<oC.Z()<<endl;
1414 cout<<"(E)Curve range : Cf,Cl = "<<Cf<<" "<<Cl<<endl;
1416 Standard_Real PCf,PCl;
1417 PCf = PC->FirstParameter(); PCl = PC->LastParameter();
1419 if (::GetOrigin(PC,oPC))
1420 cout<<"(PC)PCurve origin : "<<oPC.X()<<" "<<oPC.Y()<<endl;
1421 cout<<"(PC)PCurve range : PCf,PCl = "<<PCf<<" "<<PCl<<endl;
1426 //=======================================================================
1429 //=======================================================================
1431 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1433 const Handle(Geom2d_Curve)& PC)const
1435 if ( ! PC.IsNull() ) {
1436 TopoDS_Face FF = TopoDS::Face(F);
1437 TopoDS_Edge EE = TopoDS::Edge(E);
1438 Handle(Geom2d_Curve) PCT = PC;
1442 Standard_Boolean trc = Standard_False;
1443 if (trc) FUN_draw(FF);
1444 if (trc) FUN_draw(EE);
1445 if (trc) FUN_draw(PC,0.);
1447 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1450 // pour iab, ajout de Translate
1451 Standard_Boolean tran = myTranslate;
1453 if ( TopOpeBRepDS_GettraceSANTRAN()) {
1454 tran = Standard_False;
1455 cout<<"SANS translation de pcurve"<<endl;
1460 // recompute twice the pcurve boundaries if OverWrite
1461 // if the pcurve <PC> is U isoline on sphere -> to avoid.
1462 Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1463 Standard_Boolean overwrite = UisoLineOnSphe? Standard_False:myOverWrite;
1467 TranslateOnPeriodic(F,E,PCT);
1470 myBuilder.UpdateEdge(EE,PCT,FF,0);
1472 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1474 // parametrage sur la nouvelle courbe 2d
1475 TopExp_Explorer exi(E,TopAbs_VERTEX);
1476 for (;exi.More(); exi.Next() ) {
1477 const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
1478 if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
1479 Standard_Real tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
1480 // NYI tester l'existence d'au moins
1481 // NYI un parametrage de vi sur EE (en 3d ou en 2d)
1482 // NYI --> a faire dans BRep_Tool
1483 Standard_Real newpar = BRep_Tool::Parameter(vi,EE);
1484 myBuilder.UpdateVertex(vi,newpar,EE,FF,tolvi);
1485 } // INTERNAL vertex
1488 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1493 //=======================================================================
1496 //=======================================================================
1498 void TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1500 const TopOpeBRepDS_Curve& CDS,
1501 const Handle(Geom2d_Curve)& PC)const
1503 if ( ! PC.IsNull() ) {
1504 TopoDS_Face FF = TopoDS::Face(F);
1505 TopoDS_Edge EE = TopoDS::Edge(E);
1507 Handle(Geom2d_Curve) PCT = PC;
1508 Standard_Real CDSmin,CDSmax;
1509 Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1512 TopLoc_Location L; Standard_Real Cf,Cl;
1513 Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1516 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1520 Standard_Boolean deca = (Abs(Cf - CDSmin) > Precision::PConfusion());
1521 Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast(PCT);
1522 Standard_Boolean isline2d = !line2d.IsNull();
1523 Standard_Boolean tran=(rangedef && deca && C->IsPeriodic() && isline2d);
1525 TopLoc_Location Loc;
1526 const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
1527 Standard_Boolean isUperio = Surf->IsUPeriodic();
1528 Standard_Boolean isVperio = Surf->IsVPeriodic();
1529 gp_Dir2d dir2d = line2d->Direction();
1530 Standard_Real delta;
1531 if (isUperio && dir2d.IsParallel(gp::DX2d(),Precision::Angular())) {
1532 delta = (CDSmin - Cf) * dir2d.X();
1533 PCT->Translate(gp_Vec2d(delta,0.));
1535 else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1536 delta = (CDSmin - Cf) * dir2d.Y();
1537 PCT->Translate(gp_Vec2d(0.,delta));
1542 TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1545 if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1551 //=======================================================================
1552 //function : Orientation
1554 //=======================================================================
1556 void TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S,
1557 const TopAbs_Orientation O)const
1563 //=======================================================================
1564 //function : Orientation
1566 //=======================================================================
1568 TopAbs_Orientation TopOpeBRepDS_BuildTool::Orientation
1569 (const TopoDS_Shape& S) const
1571 return S.Orientation();
1574 //=======================================================================
1577 //=======================================================================
1579 void TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S,
1580 const Standard_Boolean B)const
1586 //=======================================================================
1587 //function : Approximation
1589 //=======================================================================
1591 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1593 return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1596 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1600 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1601 BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1604 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1605 const TopoDS_Shape& newF) const
1609 const Handle(Geom2d_Curve)& PC = BRep_Tool::CurveOnSurface(TopoDS::Edge(E),TopoDS::Face(oldF),f,l);
1610 Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
1611 BB.UpdateEdge(TopoDS::Edge(E),PC,TopoDS::Face(newF),tol);
1615 /* // - merge 04-07-97
1616 //=======================================================================
1617 //function : RecomputeCurve
1619 //=======================================================================
1621 void TopOpeBRepDS_BuildTool::RecomputeCurve
1622 (const TopOpeBRepDS_Curve& C1,
1624 TopOpeBRepDS_Curve& C2 ) const
1626 // - C1 curves have been approximated by BSplines of degree 1 :
1628 // - C1.Curve() is non projectable on at least one of the original
1629 // intersecting faces.
1631 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1632 Standard_Boolean compc3d = GT.CompC3D();
1633 Standard_Boolean comppc1 = GT.CompPC1();
1634 Standard_Boolean comppc2 = GT.CompPC2();
1636 const Handle(Geom_Curve)& C3D = C1.Curve();
1637 if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1638 ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1639 if (comppc1 && C2.Shape1().IsNull()) Standard_ProgramError::Raise
1640 ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1641 if (comppc2 && C2.Shape2().IsNull()) Standard_ProgramError::Raise
1642 ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1643 TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
1644 if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1645 ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1646 if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1647 ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1649 Standard_Boolean kbspl1 = Standard_False;
1650 Handle(Geom_BSplineCurve) BS = Handle(Geom_BSplineCurve)::DownCast(C3D);
1651 if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
1652 if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
1653 else RecomputeCurveOnCone(C1,E,C2);
1656 //=======================================================================
1657 //function : RecomputeBSpline1Curve
1659 //=======================================================================
1661 void TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1662 (const TopOpeBRepDS_Curve& C1,
1664 TopOpeBRepDS_Curve& C2) const
1667 Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1668 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1671 // C1 curves have been approximated by BSplines of degree 1 :
1672 // compute new geometry on curves.
1674 TopoDS_Edge& E = TopoDS::Edge(EE);
1676 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1677 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1678 Standard_Boolean compc3d = GT.CompC3D();
1679 Standard_Boolean comppc1 = GT.CompPC1();
1680 Standard_Boolean comppc2 = GT.CompPC2();
1682 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1683 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1685 const Handle(Geom_Curve)& C3D = C1.Curve();
1686 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1687 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1689 // Vmin,Vmax = bounding vertices of edge <E>
1690 // and their parameters parmin,parmax .
1692 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1693 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1696 if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
1697 if (tBUTO) DUMPCURVES(C3D,C1);
1700 Handle(Geom_Curve) C3Dnew;
1701 Handle(Geom2d_Curve) PC1new;
1702 Handle(Geom2d_Curve) PC2new;
1703 Standard_Real tolreached3d,tolreached2d;
1705 if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1707 C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1708 (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1710 if ( comppc1 && (!PC1.IsNull()) ) {
1711 PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1712 (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1714 if ( comppc2 && (!PC2.IsNull()) ) {
1715 PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1716 (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1720 else if ( typec3d == TopOpeBRepTool_APPROX ) {
1721 if (!comppc1 || !comppc2) Standard_NotImplemented::Raise("DSBuildToolAPPROX");
1722 myCurveTool.MakeCurves(parmin,parmax,
1724 C3Dnew,PC1new,PC2new,
1725 tolreached3d,tolreached2d);
1728 else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1729 Standard_NotImplemented::Raise("DSBuildToolINTERPOL");
1732 Standard_Real newtol,newparmin,newparmax;
1733 ::FUN_updateEDGECURVETOL
1734 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1735 newtol,newparmin,newparmax);
1737 if (!C3Dnew.IsNull()) {
1738 C2.DefineCurve(C3Dnew,newtol,Standard_False);
1739 C2.SetRange(newparmin,newparmax);
1741 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1742 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1746 //=======================================================================
1747 //function : RecomputeCurveOnCone
1749 //=======================================================================
1751 void TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1752 (const TopOpeBRepDS_Curve& C1,
1754 TopOpeBRepDS_Curve& C2 ) const
1757 Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1758 Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1759 Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
1762 // C1 Pcurves have not been computed because C1 Curve is not projectable
1763 // on one at least of the intersecting faces giving C1 Curve.
1764 // (see TopOpeBRepTool_CurveTool::IsProjectable())
1766 TopoDS_Edge& E = TopoDS::Edge(EE);
1768 const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1769 TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1770 Standard_Boolean compc3d = GT.CompC3D();
1771 Standard_Boolean comppc1 = GT.CompPC1();
1772 Standard_Boolean comppc2 = GT.CompPC2();
1774 const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1775 const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1777 const Handle(Geom_Curve)& C3D = C1.Curve();
1778 const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1779 const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1781 // get bounding vertices Vmin,Vmax supported by the new edge <E>
1782 // and their corresponding parameters parmin,parmax .
1784 TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1785 ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1788 if (tBUTO) {cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
1789 DUMPCURVES(C3D,C1);}
1792 if ( C3D->IsPeriodic() ) {
1793 // ellipse on cone : periodize parmin,parmax
1794 Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1796 if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
1797 else { f = parmax; l = parmin; }
1798 parmin = f; parmax = l;
1799 ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
1801 if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
1802 if (tBUTO||tTRPE) cout<<" --> parmin,parmax "<<parmin<<","<<parmax<<endl;
1806 Handle(Geom_TrimmedCurve) C3Dnew;
1807 Handle(Geom2d_Curve) PC1new;
1808 Handle(Geom2d_Curve) PC2new;
1809 Standard_Real tolreached3d = C1.Tolerance();
1810 Standard_Real tolreached2d1 = C1.Tolerance();
1811 Standard_Real tolreached2d2 = C1.Tolerance();
1812 if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
1813 if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
1814 if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
1817 if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1820 Standard_Real newtol,newparmin,newparmax;
1821 FUN_updateEDGECURVETOL
1822 (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1823 newtol,newparmin,newparmax);
1826 // Standard_Real fac = 0.3798123578771;
1827 // Standard_Real tol = newtol;
1828 // Standard_Real par3d = (1-fac)*newparmin + (fac)*newparmax;
1829 // Standard_Real par2d = par3d - newparmin;
1831 // gp_Pnt P3DC3D; C3D->D0(par3d,P3DC3D);
1833 // Standard_Boolean UisoLineOnSphe1 = Standard_False;
1834 // UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1835 // if (UisoLineOnSphe1) {
1836 // Standard_Real isrev1 =
1837 // ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
1840 // if (tBUTO && isrev1) cout<<"on retourne PC1"<<endl;
1845 // Standard_Boolean UisoLineOnSphe2 = Standard_False;
1846 // UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1847 // if (UisoLineOnSphe2) {
1848 // Standard_Real isrev2 =
1849 // ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
1852 // if (tBUTO && isrev2) cout<<"on retourne PC2"<<endl;
1857 // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
1858 // est une isos de la sphere
1859 // NYI : enlever FUN_reversePC
1860 Standard_Boolean UisoLineOnSphe1 = Standard_False;
1861 UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1862 if (UisoLineOnSphe1) {
1863 ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
1865 Standard_Boolean UisoLineOnSphe2 = Standard_False;
1866 UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1867 if (UisoLineOnSphe2) {
1868 ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1871 if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1872 if (!PC1new.IsNull()) C2.Curve1(PC1new);
1873 if (!PC2new.IsNull()) C2.Curve2(PC2new);
1876 if (tBUTO) DUMPCURVES(C3Dnew,C2);
1878 }*/ // - merge 04-07-97