0023024: Update headers of OCCT files
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_BuildTool.cxx
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
5 //
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.
10 //
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.
13 //
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.
20
21
22 #include <TopOpeBRepDS_BuildTool.ixx>
23
24 #include <TopoDS.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopAbs.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>
42 #include <ElCLib.hxx>
43 #include <gp.hxx>
44 #include <gp_Vec2d.hxx>
45 #include <TopExp.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>
51 #include <gp_Pnt.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>
79 #include <gp_Pnt.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>
85
86 #ifdef DEB
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)
92 {
93   if ( !C3D.IsNull() ) {
94     Standard_Real dp1 = C3D->FirstParameter();
95     Standard_Real dp2 = C3D->LastParameter();
96     cout<<"TopOpeBRepDS_BuildTool : C3D = "<<dp1<<","<<dp2<<endl;
97   }
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;
102   }
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;
107   }
108 }
109 #endif
110
111 #ifdef DRAW
112 #include <TopOpeBRepDS_DRAW.hxx>
113 #endif
114
115 //-----------------------------------------------------------------------
116 //function : PrintSurface
117 //purpose  : print the name of a surface on a stream
118 // a mettre dans TopOpeBRepDS_Dumper.cxx NYI
119 //-----------------------------------------------------------------------
120
121 #ifdef DEB
122 static Standard_OStream& PrintSurface(const TopoDS_Face& F, Standard_OStream& s)
123 {
124   BRepAdaptor_Surface STA_Surface(F);
125   GeomAbs_SurfaceType t =  STA_Surface.GetType();
126   switch(t) {
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;
137   }
138   return s;                                                    
139 }
140 #endif
141
142 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
143
144 //-----------------------------------------------------------------------
145 //function : GetOrigin
146 //purpose  : a mettre dans TopOpeBRepDS_Dumper.cxx NYI
147 //-----------------------------------------------------------------------
148
149 #ifdef DEB
150 static Standard_Boolean GetOrigin(const Handle(Geom2d_Curve)& PCIN, gp_Pnt2d& o)
151 {
152   if (PCIN.IsNull()) return Standard_False;
153   Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCIN);
154   if (PC.IsNull()) return Standard_False;
155
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;
163   }
164   else if (T==STANDARD_TYPE(Geom2d_Line)) {
165     o = Handle(Geom2d_Line)::DownCast(PC)->Location();
166     return Standard_True;
167   }
168   else  {
169     return Standard_False;
170   }
171   return Standard_False;
172 }
173 #endif
174
175 //-----------------------------------------------------------------------
176 //function : GetOrigin
177 //purpose  : a mettre dans TopOpeBRepDS_Dumper.cxx NYI
178 //-----------------------------------------------------------------------
179
180 #ifdef DEB
181 static Standard_Boolean GetOrigin(const Handle(Geom_Curve)& CIN, gp_Pnt& o)
182 {
183   if (CIN.IsNull()) return Standard_False;
184   Handle(Geom_Curve) C = TopOpeBRepTool_ShapeTool::BASISCURVE(CIN);
185   if (C.IsNull()) return Standard_False;
186
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;
194   }
195   else if (T==STANDARD_TYPE(Geom_Line)) {
196     o = Handle(Geom_Line)::DownCast(C)->Position().Location();
197     return Standard_True;
198   }
199   else  {
200     return Standard_False;
201   }
202   return Standard_False;
203 }
204 #endif
205
206 Standard_Boolean FUN_UisoLineOnSphe
207 (const TopoDS_Shape& F,
208  const Handle(Geom2d_Curve)& PC)
209 {  
210   if (PC.IsNull()) return Standard_False;
211
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()));
223   }
224   return isisoU;
225 }
226
227 //=======================================================================
228 //function : TopOpeBRepDS_BuildTool
229 //purpose  : 
230 //=======================================================================
231
232 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
233 myCurveTool(TopOpeBRepTool_APPROX),
234 myOverWrite(Standard_True),
235 myTranslate(Standard_True)
236 {
237 }
238
239 //=======================================================================
240 //function : TopOpeBRepDS_BuildTool
241 //purpose  : 
242 //=======================================================================
243
244 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
245   (const TopOpeBRepTool_OutCurveType O) : 
246 myCurveTool(O),
247 myOverWrite(Standard_True),
248 myTranslate(Standard_True)
249 {
250 }
251
252 //=======================================================================
253 //function : TopOpeBRepDS_BuildTool
254 //purpose  : 
255 //=======================================================================
256
257 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
258   (const TopOpeBRepTool_GeomTool& GT) : 
259 myCurveTool(GT),
260 myOverWrite(Standard_True),
261 myTranslate(Standard_True)
262 {
263 }
264
265 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
266 {
267   return myOverWrite;
268 }
269
270 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
271 {
272   myOverWrite = O;
273 }
274
275 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
276 {
277   return myTranslate;
278 }
279
280 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
281 {
282   myTranslate = T;
283 }
284
285 //=======================================================================
286 //function : GetGeomTool
287 //purpose  : 
288 //=======================================================================
289
290 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const 
291 {
292   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
293   return GT;
294 }
295
296 //=======================================================================
297 //function : ChangeGeomTool
298 //purpose  : 
299 //=======================================================================
300
301 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
302 {
303   TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
304   return GT;
305 }
306
307 //=======================================================================
308 //function : MakeVertex
309 //purpose  : 
310 //=======================================================================
311
312 void  TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V, 
313                                          const TopOpeBRepDS_Point& P)const 
314 {
315   myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
316 }
317
318 #ifdef DEB
319 //-----------------------------------------------------------------------
320 static Standard_OStream& DUMPPNT(const gp_Pnt& P, Standard_OStream& OS)
321 //-----------------------------------------------------------------------
322 { OS<<P.X()<<" "<<P.Y()<<" "<<P.Z(); return OS; }
323 #endif
324
325 //=======================================================================
326 //function : MakeEdge
327 //purpose  : 
328 //=======================================================================
329
330 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E, 
331                                        const TopOpeBRepDS_Curve& C)const 
332 {
333   // Gestion des courbes nulles pour carreaux pointus
334   // RLE 28-6-94
335
336   if (C.Curve().IsNull()) {
337     myBuilder.MakeEdge(TopoDS::Edge(E));
338     myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
339     return;
340   }
341
342   const Handle(Geom_Curve)& GC = C.Curve();
343   myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
344
345   Standard_Boolean addorigin = Standard_False;
346   Standard_Boolean setrange  = Standard_False;
347
348   if (addorigin) {
349     if ( GC->IsClosed() ) {
350       // in case of a closed curve, insert in E a vertex located at the origin
351       // of the curve C.
352       TopoDS_Vertex V;
353       Standard_Real first = GC->FirstParameter();
354       gp_Pnt P = GC->Value(first);
355       myBuilder.MakeVertex(V,P,C.Tolerance());
356       myBuilder.Add(E,V);
357       V.Reverse();
358       myBuilder.Add(E,V);
359       
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);
362       if (!BSC.IsNull()) {
363         if (BSC->Degree() == 1) {
364           myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
365 #ifdef DEB
366           if (TopOpeBRepDS_GettraceBUTO()) {
367             cout<<endl<<"TopOpeBRepDS_BuildTool : ";
368             cout<<"new range of "<< 1 <<" "<<BSC->NbPoles()<<endl;
369           }
370 #endif
371         }
372       }
373       
374 #ifdef DEB
375       if (TopOpeBRepDS_GettraceBUTO()) {
376         cout<<"TopOpeBRepDS_BuildTool : ";
377         cout<<"vertices on parameter "<<first<<endl;
378         cout<<" point is "; DUMPPNT(P,cout); cout<<endl;
379       }
380 #endif
381     }
382   }
383
384   if (setrange) {
385     Standard_Real first,last;
386     Standard_Boolean rangedef = C.Range(first,last);
387     if (rangedef) {
388       Range(E,first,last);
389 #ifdef DEB
390       if (TopOpeBRepDS_GettraceBUTO()) {
391         cout<<"TopOpeBRepDS_BuildTool : ";
392         cout<<"set edge range : "<<first<<" "<<last<<endl;
393       }
394 #endif
395     }
396   }
397 }
398
399 //=======================================================================
400 //function : MakeEdge
401 //purpose  : 
402 //=======================================================================
403
404 void  TopOpeBRepDS_BuildTool::MakeEdge
405 (TopoDS_Shape& E, 
406  const TopOpeBRepDS_Curve& C,
407  const TopOpeBRepDS_DataStructure& BDS) const
408 {
409   // Gestion des courbes nulles pour carreaux pointus
410   // RLE 28-6-94
411
412   TopoDS_Edge& EE = TopoDS::Edge(E);
413
414   if (C.Curve().IsNull()) {
415     myBuilder.MakeEdge(EE);
416     myBuilder.Degenerated(EE,Standard_True);
417     
418     // Creation d'une arete avec PCurve connectee a la BDS Curve 
419     // JYL 22-09-94
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());
428     return;
429   }
430   else {
431     const Handle(Geom_Curve)& GC = C.Curve();
432     myBuilder.MakeEdge(EE,GC,C.Tolerance());
433   }
434
435 }
436
437 //=======================================================================
438 //function : MakeEdge
439 //purpose  : 
440 //=======================================================================
441
442 void  TopOpeBRepDS_BuildTool::MakeEdge
443 (TopoDS_Shape& E, 
444  const Handle(Geom_Curve)& C,
445  const Standard_Real Tol)const 
446 {
447   myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
448 }
449
450
451 //=======================================================================
452 //function : MakeEdge
453 //purpose  : 
454 //=======================================================================
455
456 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
457 {
458   myBuilder.MakeEdge(TopoDS::Edge(E));
459 }
460
461
462 //=======================================================================
463 //function : MakeWire
464 //purpose  : 
465 //=======================================================================
466
467 void  TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const 
468 {
469   myBuilder.MakeWire(TopoDS::Wire(W));
470 }
471
472
473 //=======================================================================
474 //function : MakeFace
475 //purpose  : 
476 //=======================================================================
477
478 void  TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F, 
479                                        const TopOpeBRepDS_Surface& S)const 
480 {
481   myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
482 }
483
484
485 //=======================================================================
486 //function : MakeShell
487 //purpose  : 
488 //=======================================================================
489
490 void  TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const 
491 {
492   myBuilder.MakeShell(TopoDS::Shell(Sh));
493 }
494
495
496 //=======================================================================
497 //function : MakeSolid
498 //purpose  : 
499 //=======================================================================
500
501 void  TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const 
502 {
503   myBuilder.MakeSolid(TopoDS::Solid(S));
504 }
505
506
507 //=======================================================================
508 //function : CopyEdge
509 //purpose  : 
510 //=======================================================================
511
512 void  TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein, 
513                                        TopoDS_Shape& Eou)const 
514 {
515
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
529
530   Standard_Real f,l;
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);
536 }
537
538
539 //=======================================================================
540 //function : GetOrientedEdgeVertices
541 //purpose  : 
542 //=======================================================================
543
544 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
545 (TopoDS_Edge& E,
546  TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
547  Standard_Real& Parmin, Standard_Real& Parmax) const
548 {
549   if ( E.Orientation() == TopAbs_FORWARD) 
550     TopExp::Vertices(E,Vmin,Vmax);
551   else
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);
556   }
557 }
558
559 //=======================================================================
560 //function : UpdateEdgeCurveTol
561 //purpose  : 
562 //=======================================================================
563
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
577
578 {
579   if (C3Dnew.IsNull()) return;
580   BRep_Builder BB;
581
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
592 // abberantes.
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.
595
596
597   newtol = 1.E-7;
598 //  Standard_Real r1,r2;
599 //  r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
600 //  r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
601 //  newtol=tol3d;
602 //  if (r1>newtol) newtol=r1;
603 //  if (r2>newtol) newtol=r2;
604 //#ifdef DEB
605 //  if (TopOpeBRepDS_GettraceDSNC()) cout<<"newtol = "<<newtol<<endl;
606 //#endif
607
608 //  newtol *= 1.5;
609
610   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
611   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
612   
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;
617
618
619 //  newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
620 //  newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
621
622  // +merge 04-07-97
623   Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
624   if(GTC.IsNull()) {
625     Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
626     if(GBSC.IsNull()) {
627       newparmin = parmin;
628       newparmax = parmax;
629     } else {
630       newparmin=C3Dnew->FirstParameter();
631       newparmax=C3Dnew->LastParameter();
632     } 
633   } else {
634     newparmin=C3Dnew->FirstParameter();
635     newparmax=C3Dnew->LastParameter();
636   } // +merge 04-07-97
637
638   if (Vmin.Orientation() == TopAbs_FORWARD) { 
639     BB.UpdateVertex(Vmin,newparmin,E,tolmin);
640     BB.UpdateVertex(Vmax,newparmax,E,tolmax);
641   }
642   else {
643     BB.UpdateVertex(Vmin,newparmax,E,tolmin);
644     BB.UpdateVertex(Vmax,newparmin,E,tolmax);
645   }
646   
647 //  DSBT.Curve3D(E,C3Dnew,newtol);  // -merge 04-07-97
648   Curve3D(E,C3Dnew,newtol);
649   
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();
660     if ( dmdone ) {
661       if ( dm.NbPoints() ) {
662         Standard_Real newpar = dm.LowerDistanceParameter();
663         BB.UpdateVertex(vi,newpar,E,tolvi);
664       }
665     }
666   } // INTERNAL vertex
667 }
668
669 //=======================================================================
670 //function : ApproxCurves
671 //purpose  : 
672 //=======================================================================
673
674 void  TopOpeBRepDS_BuildTool::ApproxCurves
675 (const TopOpeBRepDS_Curve& C,
676  TopoDS_Edge& E,
677  Standard_Integer& inewC,
678  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
679 {
680   TopOpeBRepDS_Curve newC1;
681   inewC = HDS->MakeCurve(C,newC1);
682   TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
683
684 #ifdef DEB
685 //  Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
686   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
687 #endif
688   
689   // C1 curves have been approximated by BSplines of degree 1 :
690   // compute new geometry on curves.
691
692   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
693   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
694   
695   const Handle(Geom_Curve)& C3D = C.Curve();
696   const Handle(Geom2d_Curve)& PC1 = C.Curve1();
697   const Handle(Geom2d_Curve)& PC2 = C.Curve2();
698
699   // Vmin,Vmax = bounding vertices of edge <E>
700   // and their parameters parmin,parmax .
701
702   TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
703   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
704
705 #ifdef DEB
706   if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
707   if (tBUTO) DUMPCURVES(C3D,C);
708 #endif
709   
710   Handle(Geom_Curve)   C3Dnew;
711   Handle(Geom2d_Curve) PC1new;
712   Handle(Geom2d_Curve) PC2new;
713   Standard_Real tolreached3d,tolreached2d;
714   
715   Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
716                          C3D,PC1,PC2,F1,F2,
717                          C3Dnew,PC1new,PC2new,
718                          tolreached3d,tolreached2d);
719
720   Standard_Real newtol,newparmin,newparmax;
721   // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
722   if (!approxMade) {
723 #ifdef DEB
724     cout<<"TopOpeBRepDS_BuildTool::ApproxCurves : approx failed, leave curves of degree 1"
725       <<endl;
726 #endif
727     newtol = BRep_Tool::Tolerance(E);
728     newparmin = parmin;
729     newparmax = parmax;
730     C3Dnew = C3D;
731     PC1new = PC1;
732     PC2new = PC2;
733   }
734   else {
735     UpdateEdgeCurveTol
736       (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
737        newtol,newparmin,newparmax);
738   }
739
740   if (!C3Dnew.IsNull()) {
741     newC.DefineCurve(C3Dnew,newtol,Standard_False);
742     newC.SetRange(newparmin,newparmax);
743   }
744
745   if (!PC1new.IsNull()) newC.Curve1(PC1new);
746   if (!PC2new.IsNull()) newC.Curve2(PC2new);
747 }
748
749
750 //=======================================================================
751 //function : ComputePCurves
752 //purpose  : 
753 //=======================================================================
754 Standard_Boolean FUN_getUV
755 (const Handle(Geom_Surface) surf,
756  const Handle(Geom_Curve) C3D,
757  const Standard_Real par3d,
758  Standard_Real& u0,
759  Standard_Real& v0)
760 {
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;
766 }
767
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)
774 {
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);
780   PCreversed = !sam;
781
782 #ifdef DEB
783 #ifdef DRAW
784   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
785   if (tBUTO) {FUN_draw(P3DC3D); FUN_draw(P3D);}
786 #endif
787 #endif
788
789   if ( PCreversed ) {
790     Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
791     if (!PC.IsNull()) {
792       Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
793       gp_Dir2d d = L->Direction();
794       d.Reverse();
795       L->SetDirection(d);
796     }
797   }
798   return PCreversed;
799 }
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)
805 {
806   // p3df,p3dl : C3d first and last parameters
807   Standard_Real p3df = C3D->FirstParameter();
808   Standard_Real p3dl = C3D->LastParameter();
809
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;
820 #ifdef DEB
821 //  Standard_Real deltav = vsup-vinf;
822 #endif
823
824   Standard_Boolean isvgrowing = (vsup - vinf > -tol);
825   gp_Dir2d vdir;
826   if (isvgrowing) vdir = gp_Dir2d(0,1);
827   else            vdir = gp_Dir2d(0,-1);
828   
829   gp_Pnt2d origin(uinf,vinf);
830   origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
831   Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
832   if (!PC.IsNull()) {  
833     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC); 
834     L->SetLin2d(gp_Lin2d(origin,vdir));
835 #ifdef DEB
836 #ifdef DRAW
837   Standard_Boolean trc = TopOpeBRepDS_GettraceBUTO();
838     if (trc) {
839       FUN_draw(gp_Pnt2d(uinf,vinf));
840       FUN_draw(gp_Pnt2d(usup,vsup));
841       FUN_draw(L,p3dl-p3df);
842     }
843 #endif
844 #endif
845   } // (!PC.IsNull())
846   
847   return Standard_True;
848 }
849
850 void TopOpeBRepDS_BuildTool::ComputePCurves
851 (const TopOpeBRepDS_Curve& C,
852  TopoDS_Edge& E,
853  TopOpeBRepDS_Curve& newC,
854  const Standard_Boolean comppc1,
855  const Standard_Boolean comppc2,
856  const Standard_Boolean compc3d) const
857 {
858 #ifdef DEB
859 //  Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
860   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
861   Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
862 #endif
863   
864   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
865   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
866   
867   const Handle(Geom_Curve)& C3D = C.Curve();
868 #ifdef DEB
869 //  const Handle(Geom2d_Curve)& PC1 = C.Curve1();
870 //  const Handle(Geom2d_Curve)& PC2 = C.Curve2();
871 #endif
872
873   // get bounding vertices Vmin,Vmax supported by the new edge <E>
874   // and their corresponding parameters parmin,parmax .
875
876   TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
877   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
878
879 #ifdef DEB
880   if (tBUTO) cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
881   if (tBUTO) DUMPCURVES(C3D,C);
882 #endif
883
884   Handle(Geom2d_Curve) PC1new;
885   Handle(Geom2d_Curve) PC2new;
886   
887   if(C3D.IsNull()) {
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);
891     
892     r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
893     r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
894     tol = Max(tol,r1);
895     tol = Max(tol,r2);
896     newC.Tolerance(tol);
897     
898     if (!PC1new.IsNull()) newC.Curve1(PC1new);
899     if (!PC2new.IsNull()) newC.Curve2(PC2new);
900
901     return;
902   }
903   
904   Handle(Geom_Curve) C3Dnew = C3D;
905   
906   if ( C3D->IsPeriodic() ) {
907     // ellipse on cone : periodize parmin,parmax
908     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
909     Standard_Real f,l;
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);
915     
916 #ifdef DEB
917     if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
918     if (tBUTO||tTRPE) cout<<"                   --> parmin,parmax "<<parmin<<","<<parmax<<endl;
919 #endif
920   }
921   
922   Standard_Real tolreached3d = C.Tolerance();
923   Standard_Real tolreached2d1 = C.Tolerance();
924   Standard_Real tolreached2d2 = C.Tolerance();
925   
926   if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
927   if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
928   
929   Standard_Real newtol,newparmin,newparmax;
930   UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
931                      newtol,newparmin,newparmax);
932   
933     // xpu : suite merge : 07-07-97
934     // xpu : 17-06-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);
941
942     Standard_Boolean UisoLineOnSphe2 = Standard_False;
943     UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
944     if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
945     // xpu : 17-06-97
946     // xpu : suite merge : 07-07-97
947
948   if (!C3Dnew.IsNull()) {
949     newC.Curve(C3Dnew,newtol);
950     newC.SetRange(newparmin, newparmax);
951   }
952   if (!PC1new.IsNull()) newC.Curve1(PC1new);
953   if (!PC2new.IsNull()) newC.Curve2(PC2new);
954   
955 #ifdef DEB
956   if (tBUTO) DUMPCURVES(C3Dnew,newC);
957 #endif
958 }
959
960 //=======================================================================
961 //function : PutPCurves
962 //purpose  : 
963 //=======================================================================
964
965 void  TopOpeBRepDS_BuildTool::PutPCurves
966 (const TopOpeBRepDS_Curve& newC,
967  TopoDS_Edge& E,
968  const Standard_Boolean comppc1,
969  const Standard_Boolean comppc2) const
970 {
971
972   TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
973   Handle(Geom2d_Curve) PC1 = newC.Curve1();
974   if (!PC1.IsNull() && comppc1) {
975     PCurve(F1,E,PC1);
976   }
977   
978   TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
979   Handle(Geom2d_Curve) PC2 = newC.Curve2();
980   if (!PC2.IsNull() && comppc2) {
981     PCurve(F2,E,PC2);
982   }
983   
984 }
985
986 //=======================================================================
987 //function : RecomputeCurves
988 //purpose  : 
989 //=======================================================================
990
991 void  TopOpeBRepDS_BuildTool::RecomputeCurves
992 (const TopOpeBRepDS_Curve& C,
993 // const TopoDS_Edge& oldE,
994  const TopoDS_Edge& ,
995  TopoDS_Edge& E,
996  Standard_Integer& inewC,
997  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
998 {
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();
1006   
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");
1017   
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);
1024   }
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);
1029 //  }
1030
1031   else {
1032     if (comppc) {
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());
1041       }
1042       else
1043         ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);  
1044       PutPCurves(newC, E, comppc1, comppc2);
1045     }
1046   }
1047 }
1048
1049 //=======================================================================
1050 //function : CopyFace
1051 //purpose  : 
1052 //=======================================================================
1053
1054 void  TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin, 
1055                                        TopoDS_Shape& Fou)const 
1056 {
1057   Fou = Fin.EmptyCopied();
1058 }
1059
1060
1061 //=======================================================================
1062 //function : AddEdgeVertex
1063 //purpose  : 
1064 //=======================================================================
1065
1066 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein, 
1067                                             TopoDS_Shape& Eou, 
1068                                             const TopoDS_Shape& V)const 
1069 {
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);
1075 }
1076
1077
1078 //=======================================================================
1079 //function : AddEdgeVertex
1080 //purpose  : 
1081 //=======================================================================
1082
1083 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E, 
1084                                             const TopoDS_Shape& V)const 
1085 {
1086   myBuilder.Add(E,V);
1087 }
1088
1089
1090 //=======================================================================
1091 //function : AddWireEdge
1092 //purpose  : 
1093 //=======================================================================
1094
1095 void  TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W, 
1096                                           const TopoDS_Shape& E)const 
1097 {
1098   myBuilder.Add(W,E);
1099 }
1100
1101
1102 //=======================================================================
1103 //function : AddFaceWire
1104 //purpose  : 
1105 //=======================================================================
1106
1107 void  TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F, 
1108                                           const TopoDS_Shape& W)const 
1109 {
1110   myBuilder.Add(F,W);
1111 }
1112
1113
1114 //=======================================================================
1115 //function : AddShellFace
1116 //purpose  : 
1117 //=======================================================================
1118
1119 void  TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh, 
1120                                            const TopoDS_Shape& F)const 
1121 {
1122   myBuilder.Add(Sh,F);
1123 }
1124
1125
1126 //=======================================================================
1127 //function : AddSolidShell
1128 //purpose  : 
1129 //=======================================================================
1130
1131 void  TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S, 
1132                                             const TopoDS_Shape& Sh)const 
1133 {
1134   myBuilder.Add(S,Sh);
1135 }
1136
1137
1138 //=======================================================================
1139 //function : Parameter
1140 //purpose  : 
1141 //=======================================================================
1142
1143 void  TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E, 
1144                                         const TopoDS_Shape& V, 
1145                                         const Standard_Real P)const 
1146 {
1147   const TopoDS_Edge&   e = TopoDS::Edge(E);
1148   const TopoDS_Vertex& v = TopoDS::Vertex(V);
1149   Standard_Real p = P;
1150
1151   // 13/07/95 : 
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();
1156 #ifdef DEB
1157     TopAbs_Orientation oV;
1158 #else
1159     TopAbs_Orientation oV=TopAbs_FORWARD;
1160 #endif
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();
1166         break;
1167       }
1168     }
1169     if ( exV.More() ) {
1170       if ( oV == TopAbs_REVERSED ) {
1171         if ( p < f ) {
1172           Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
1173 #ifdef DEB
1174           if (TopOpeBRepDS_GettraceBUTO() ) {
1175             cout<<"BuildTool Parameter : "<<p<<" --> "<<pp<<endl;
1176           }
1177 #endif
1178           p = pp;
1179         }
1180       }
1181     }
1182   }
1183
1184   myBuilder.UpdateVertex(v,p,e,
1185                          0);   // NYI : Tol on new vertex ?? 
1186 }
1187
1188 //=======================================================================
1189 //function : Range
1190 //purpose  : 
1191 //=======================================================================
1192
1193 void  TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E, 
1194                                     const Standard_Real first,
1195                                     const Standard_Real last)const 
1196 {
1197   myBuilder.Range(TopoDS::Edge(E),first,last);
1198 }
1199
1200
1201 //=======================================================================
1202 //function : UpdateEdge
1203 //purpose  : 
1204 //=======================================================================
1205
1206 void  TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
1207                                          TopoDS_Shape& Eou)const
1208 {
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;
1215   
1216   if ( Cou->IsPeriodic() ) {
1217     Standard_Real f2n = f2, l2n = l2;
1218     if ( l2n <= f2n ) {
1219       ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1220       Range(Eou,f2n,l2n);
1221 #ifdef DEB
1222       if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1223         cout<<endl;
1224         cout<<"UpdateEdge f1,l1   "<<f1<<" "<<l1<<endl;
1225         cout<<"UpdateEdge f2,l2   "<<f2<<" "<<l2<<" "<<endl;
1226         cout<<"UpdateEdge f2n,l2n "<<f2n<<" "<<l2n<<endl;
1227         TopExp_Explorer ex;
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;
1233         }
1234       }
1235 #endif
1236     }
1237   }
1238 }
1239
1240 //=======================================================================
1241 //function : Project
1242 //purpose  : project a vertex on a curve
1243 //=======================================================================
1244
1245 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1246                                 const TopoDS_Vertex& V,
1247                                 Standard_Real& p)
1248 {
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;
1261         }
1262       }
1263     }
1264   }
1265   return Standard_False;
1266 }
1267
1268
1269 //=======================================================================
1270 //function : Parameter
1271 //purpose  : 
1272 //=======================================================================
1273
1274 void  TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1275                                         TopoDS_Shape& E,
1276                                         TopoDS_Shape& V)const 
1277 {
1278   Standard_Real newparam;
1279   Project(C.Curve(),TopoDS::Vertex(V),newparam);
1280   Parameter(E,V,newparam);
1281 }
1282
1283
1284 //=======================================================================
1285 //function : Curve3D
1286 //purpose  : 
1287 //=======================================================================
1288
1289 void  TopOpeBRepDS_BuildTool::Curve3D
1290 (TopoDS_Shape& E, 
1291  const Handle(Geom_Curve)& C,
1292  const Standard_Real Tol)const 
1293 {
1294   myBuilder.UpdateEdge(TopoDS::Edge(E),
1295                        C,
1296                        Tol);
1297 }
1298
1299
1300 //=======================================================================
1301 //function : TranslateOnPeriodic
1302 //purpose  : 
1303 //=======================================================================
1304
1305 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1306   (TopoDS_Shape& F,
1307    TopoDS_Shape& E,
1308    Handle(Geom2d_Curve)& PC) const
1309 {
1310   // get range C3Df,C3Dl of 3d curve C3D of E
1311   TopLoc_Location L; 
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
1315  
1316   Standard_Real first = C3Df, last = C3Dl;
1317   if (C3D->IsPeriodic()) {
1318     if ( last < first ) last += Abs(first - last);
1319   }
1320
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 
1324   // with C3D bounds.
1325   Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1326   Standard_Boolean newv = Standard_True;
1327
1328   Standard_Real du,dv;
1329
1330   gp_Pnt2d ptest;
1331   Standard_Real t =(first+last)*.5;
1332   PC->D0(t,ptest);
1333   Standard_Real u1 = ptest.X(), u2 = u1;
1334   Standard_Real v1 = ptest.Y(), v2 = v1;
1335
1336   if (newv) {
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);
1345   }
1346   if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1347   du = u2 - u1, dv = v2 - v1;    
1348
1349   if ( du != 0. || dv != 0.) {
1350 #ifdef DEB
1351     if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1352       cout<<endl;
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;
1358     }
1359 #endif
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));
1363     PC = PCT;
1364   }
1365 }
1366
1367
1368 // RLE - IAB 16 june 94
1369 // should be provided by the BRep_Builder
1370
1371 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1372                                                TopoDS_Edge& E,
1373                                                const TopoDS_Face& F,
1374                                                const TopAbs_Orientation O,
1375                                                const Handle(Geom2d_Curve)& C)
1376 {
1377   // check if there is already a pcurve on non planar faces
1378   Standard_Real f,l;
1379   Handle(Geom2d_Curve) OC;
1380   TopLoc_Location SL;
1381   Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1382   if (GP.IsNull())
1383     OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1384
1385   if (OC.IsNull()) 
1386     B.UpdateEdge(E,C,F,Precision::Confusion());
1387   else {
1388     Standard_Boolean degen = BRep_Tool::Degenerated(E);
1389     if(!degen){
1390       if (O == TopAbs_REVERSED) 
1391         B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1392       else 
1393         B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1394     }
1395   }
1396 }
1397
1398 #ifdef DEB
1399 //------------------------------------------------------------------------
1400 static void DUMPPCURVE(const TopoDS_Edge& EE, 
1401                        const TopoDS_Face& FF,
1402                        const Handle(Geom2d_Curve)& PC)
1403 //------------------------------------------------------------------------
1404 {
1405   TopLoc_Location L; Standard_Real Cf,Cl;
1406   Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1407   if (C->IsPeriodic()) {
1408     cout<<endl;
1409       cout<<"DUMPPCURVE  : ";cout<<" face "; ::PrintSurface(FF,cout); cout<<endl;
1410       cout<<"PCurve type : ";TopOpeBRepDS_Dumper::PrintType(PC,cout); cout<<endl;
1411     gp_Pnt oC; 
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;
1415     
1416     Standard_Real PCf,PCl;
1417     PCf = PC->FirstParameter(); PCl = PC->LastParameter();
1418     gp_Pnt2d oPC; 
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;
1422   }
1423 }
1424 #endif
1425
1426 //=======================================================================
1427 //function : PCurve
1428 //purpose  : 
1429 //=======================================================================
1430
1431 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F, 
1432                                      TopoDS_Shape& E, 
1433                                      const Handle(Geom2d_Curve)& PC)const 
1434 {
1435   if ( ! PC.IsNull() ) {
1436     TopoDS_Face FF = TopoDS::Face(F);
1437     TopoDS_Edge EE = TopoDS::Edge(E);
1438     Handle(Geom2d_Curve) PCT = PC;
1439
1440 #ifdef DEB
1441 #ifdef DRAW
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.);
1446 #endif
1447     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1448 #endif
1449     
1450     // pour iab, ajout de Translate
1451     Standard_Boolean tran = myTranslate;
1452 #ifdef DEB
1453     if ( TopOpeBRepDS_GettraceSANTRAN()) {
1454       tran = Standard_False; 
1455       cout<<"SANS translation de pcurve"<<endl; 
1456     }
1457 #endif
1458
1459     // xpu : 13-06-97 : 
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;
1464     // xpu : 13-06-97
1465
1466     if (tran)      
1467       TranslateOnPeriodic(F,E,PCT);  
1468
1469     if (overwrite) 
1470       myBuilder.UpdateEdge(EE,PCT,FF,0);
1471     else           
1472       TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1473
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
1486     
1487 #ifdef DEB
1488     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1489 #endif
1490   }
1491 }
1492
1493 //=======================================================================
1494 //function : PCurve
1495 //purpose  : 
1496 //=======================================================================
1497
1498 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F, 
1499                                      TopoDS_Shape& E, 
1500                                      const TopOpeBRepDS_Curve& CDS,
1501                                      const Handle(Geom2d_Curve)& PC)const
1502 {
1503   if ( ! PC.IsNull() ) {
1504     TopoDS_Face FF = TopoDS::Face(F);
1505     TopoDS_Edge EE = TopoDS::Edge(E);
1506
1507     Handle(Geom2d_Curve) PCT = PC;
1508     Standard_Real    CDSmin,CDSmax;
1509     Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1510
1511     
1512     TopLoc_Location L; Standard_Real Cf,Cl;
1513     Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1514
1515 #ifdef DEB
1516     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1517 #endif
1518       
1519     if (!C.IsNull()){
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);
1524       if (tran) {
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.));
1534         }
1535         else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1536           delta = (CDSmin - Cf) * dir2d.Y();
1537           PCT->Translate(gp_Vec2d(0.,delta));
1538         }
1539       }
1540     }
1541     
1542     TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1543     
1544 #ifdef DEB
1545     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1546 #endif
1547   }
1548 }
1549
1550
1551 //=======================================================================
1552 //function : Orientation
1553 //purpose  : 
1554 //=======================================================================
1555
1556 void  TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S, 
1557                                           const TopAbs_Orientation O)const 
1558 {
1559   S.Orientation(O);
1560 }
1561
1562
1563 //=======================================================================
1564 //function : Orientation
1565 //purpose  : 
1566 //=======================================================================
1567
1568 TopAbs_Orientation  TopOpeBRepDS_BuildTool::Orientation
1569   (const TopoDS_Shape& S) const
1570 {
1571   return S.Orientation();
1572 }
1573
1574 //=======================================================================
1575 //function : Closed
1576 //purpose  : 
1577 //=======================================================================
1578
1579 void  TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S, 
1580                                      const Standard_Boolean B)const 
1581 {
1582   S.Closed(B);
1583 }
1584
1585
1586 //=======================================================================
1587 //function : Approximation
1588 //purpose  : 
1589 //=======================================================================
1590
1591 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1592 {
1593   return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1594 }
1595
1596 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1597 {
1598   BRep_Builder BB;
1599   TopLoc_Location L;
1600   Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1601   BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1602 }
1603
1604 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1605                                            const TopoDS_Shape& newF) const
1606 {
1607   BRep_Builder BB;
1608   Standard_Real f,l;
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);
1612 }
1613
1614
1615 /* // - merge 04-07-97
1616 //=======================================================================
1617 //function : RecomputeCurve
1618 //purpose  : 
1619 //=======================================================================
1620
1621 void  TopOpeBRepDS_BuildTool::RecomputeCurve
1622 (const TopOpeBRepDS_Curve& C1,
1623  TopoDS_Shape& E,
1624  TopOpeBRepDS_Curve& C2 ) const
1625 {
1626   // - C1 curves have been approximated by BSplines of degree 1 :
1627   // or
1628   // - C1.Curve() is non projectable on at least one of the original
1629   // intersecting faces.
1630
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();
1635   
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");
1648
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);
1654 }
1655
1656 //=======================================================================
1657 //function : RecomputeBSpline1Curve
1658 //purpose  : 
1659 //=======================================================================
1660
1661 void  TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1662 (const TopOpeBRepDS_Curve& C1,
1663  TopoDS_Shape& EE,
1664  TopOpeBRepDS_Curve& C2) const
1665 {
1666 #ifdef DEB
1667   Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1668   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1669 #endif
1670   
1671   // C1 curves have been approximated by BSplines of degree 1 :
1672   // compute new geometry on curves.
1673
1674   TopoDS_Edge& E = TopoDS::Edge(EE);
1675
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();
1681
1682   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1683   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1684   
1685   const Handle(Geom_Curve)&   C3D = C1.Curve();
1686   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1687   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1688
1689   // Vmin,Vmax = bounding vertices of edge <E>
1690   // and their parameters parmin,parmax .
1691
1692   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1693   ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1694
1695 #ifdef DEB
1696   if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
1697   if (tBUTO) DUMPCURVES(C3D,C1);
1698 #endif
1699   
1700   Handle(Geom_Curve)   C3Dnew;
1701   Handle(Geom2d_Curve) PC1new;
1702   Handle(Geom2d_Curve) PC2new;
1703   Standard_Real tolreached3d,tolreached2d;
1704
1705   if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1706     if ( compc3d ) {
1707       C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1708       (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1709     }
1710     if ( comppc1 && (!PC1.IsNull()) ) {
1711       PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1712       (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1713     }
1714     if ( comppc2 && (!PC2.IsNull()) ) {
1715       PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1716       (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1717     }
1718   }
1719
1720   else if ( typec3d == TopOpeBRepTool_APPROX ) {
1721     if (!comppc1 || !comppc2) Standard_NotImplemented::Raise("DSBuildToolAPPROX");
1722     myCurveTool.MakeCurves(parmin,parmax,
1723                            C3D,PC1,PC2,F1,F2,
1724                            C3Dnew,PC1new,PC2new,
1725                            tolreached3d,tolreached2d);
1726   }
1727
1728   else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1729     Standard_NotImplemented::Raise("DSBuildToolINTERPOL");
1730   }
1731
1732   Standard_Real newtol,newparmin,newparmax;
1733   ::FUN_updateEDGECURVETOL
1734     (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1735      newtol,newparmin,newparmax);
1736   
1737   if (!C3Dnew.IsNull()) {
1738     C2.DefineCurve(C3Dnew,newtol,Standard_False);
1739     C2.SetRange(newparmin,newparmax);
1740   }
1741   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1742   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1743 }
1744
1745
1746 //=======================================================================
1747 //function : RecomputeCurveOnCone
1748 //purpose  : 
1749 //=======================================================================
1750
1751 void  TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1752   (const TopOpeBRepDS_Curve& C1,
1753    TopoDS_Shape&             EE,
1754    TopOpeBRepDS_Curve&       C2 ) const
1755 {
1756 #ifdef DEB
1757   Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1758   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1759   Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
1760 #endif
1761   
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())
1765
1766   TopoDS_Edge& E = TopoDS::Edge(EE);
1767   
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();
1773   
1774   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1775   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1776   
1777   const Handle(Geom_Curve)&   C3D = C1.Curve();
1778   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1779   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1780
1781   // get bounding vertices Vmin,Vmax supported by the new edge <E>
1782   // and their corresponding parameters parmin,parmax .
1783
1784   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1785   ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1786
1787 #ifdef DEB
1788   if (tBUTO) {cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
1789               DUMPCURVES(C3D,C1);}
1790 #endif
1791
1792   if ( C3D->IsPeriodic() ) {
1793     // ellipse on cone : periodize parmin,parmax
1794     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1795     Standard_Real f,l;
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);
1800 #ifdef DEB
1801     if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
1802     if (tBUTO||tTRPE) cout<<"                   --> parmin,parmax "<<parmin<<","<<parmax<<endl;
1803 #endif
1804   }
1805   
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);
1815
1816 #ifdef DRAW
1817   if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1818 #endif
1819
1820   Standard_Real newtol,newparmin,newparmax;
1821   FUN_updateEDGECURVETOL
1822   (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1823    newtol,newparmin,newparmax);
1824
1825 //   jyl : 16-06-97
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;
1830 //
1831 //  gp_Pnt P3DC3D;       C3D->D0(par3d,P3DC3D);
1832 //
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);
1838 //    
1839 //#ifdef DEB
1840 //    if (tBUTO && isrev1) cout<<"on retourne PC1"<<endl;
1841 //#endif
1842 //
1843 //  }
1844 //
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);
1850 //
1851 //#ifdef DEB
1852 //    if (tBUTO && isrev2) cout<<"on retourne PC2"<<endl;
1853 //#endif
1854 //  }
1855
1856   // xpu : 17-06-97
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);
1864   }
1865   Standard_Boolean UisoLineOnSphe2 = Standard_False;
1866   UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1867   if (UisoLineOnSphe2) {
1868     ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1869   } // xpu : 17-06-97
1870
1871   if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1872   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1873   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1874   
1875 #ifdef DEB
1876   if (tBUTO) DUMPCURVES(C3Dnew,C2);
1877 #endif
1878 }*/ // - merge 04-07-97
1879
1880