b5613eeed098a45ecd073702a2b1f4163206e274
[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 extern Standard_Boolean TopOpeBRepDS_GettraceDSNC();
88 extern Standard_Boolean TopOpeBRepDS_GettraceBUTO();
89 extern Standard_Boolean TopOpeBRepDS_GettraceTRPE();
90 extern Standard_Boolean TopOpeBRepDS_GettraceSANTRAN();
91 static void DUMPCURVES(const Handle(Geom_Curve)& C3D,const TopOpeBRepDS_Curve& C)
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 }
203 #endif
204
205 Standard_Boolean FUN_UisoLineOnSphe
206 (const TopoDS_Shape& F,
207  const Handle(Geom2d_Curve)& PC)
208 {  
209   if (PC.IsNull()) return Standard_False;
210
211   Handle(Geom_Surface) SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
212   Handle(Geom2d_Curve) LLL = ::BASISCURVE2D(PC);
213   Handle(Standard_Type) TS = SSS->DynamicType();
214   Handle(Standard_Type) T2 = LLL->DynamicType();
215   Standard_Boolean issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface)); 
216   Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
217   Standard_Boolean isisoU = Standard_False;
218   if (issphere && isline2d) {
219     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
220     const gp_Dir2d& d = L->Direction();
221     isisoU = (Abs(d.X()) < Precision::Parametric(Precision::Confusion()));
222   }
223   return isisoU;
224 }
225
226 //=======================================================================
227 //function : TopOpeBRepDS_BuildTool
228 //purpose  : 
229 //=======================================================================
230
231 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
232 myCurveTool(TopOpeBRepTool_APPROX),
233 myOverWrite(Standard_True),
234 myTranslate(Standard_True)
235 {
236 }
237
238 //=======================================================================
239 //function : TopOpeBRepDS_BuildTool
240 //purpose  : 
241 //=======================================================================
242
243 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
244   (const TopOpeBRepTool_OutCurveType O) : 
245 myCurveTool(O),
246 myOverWrite(Standard_True),
247 myTranslate(Standard_True)
248 {
249 }
250
251 //=======================================================================
252 //function : TopOpeBRepDS_BuildTool
253 //purpose  : 
254 //=======================================================================
255
256 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
257   (const TopOpeBRepTool_GeomTool& GT) : 
258 myCurveTool(GT),
259 myOverWrite(Standard_True),
260 myTranslate(Standard_True)
261 {
262 }
263
264 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
265 {
266   return myOverWrite;
267 }
268
269 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
270 {
271   myOverWrite = O;
272 }
273
274 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
275 {
276   return myTranslate;
277 }
278
279 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
280 {
281   myTranslate = T;
282 }
283
284 //=======================================================================
285 //function : GetGeomTool
286 //purpose  : 
287 //=======================================================================
288
289 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const 
290 {
291   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
292   return GT;
293 }
294
295 //=======================================================================
296 //function : ChangeGeomTool
297 //purpose  : 
298 //=======================================================================
299
300 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
301 {
302   TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
303   return GT;
304 }
305
306 //=======================================================================
307 //function : MakeVertex
308 //purpose  : 
309 //=======================================================================
310
311 void  TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V, 
312                                          const TopOpeBRepDS_Point& P)const 
313 {
314   myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
315 }
316
317 #ifdef DEB
318 //-----------------------------------------------------------------------
319 static Standard_OStream& DUMPPNT(const gp_Pnt& P, Standard_OStream& OS)
320 //-----------------------------------------------------------------------
321 { OS<<P.X()<<" "<<P.Y()<<" "<<P.Z(); return OS; }
322 #endif
323
324 //=======================================================================
325 //function : MakeEdge
326 //purpose  : 
327 //=======================================================================
328
329 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E, 
330                                        const TopOpeBRepDS_Curve& C)const 
331 {
332   // Gestion des courbes nulles pour carreaux pointus
333   // RLE 28-6-94
334
335   if (C.Curve().IsNull()) {
336     myBuilder.MakeEdge(TopoDS::Edge(E));
337     myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
338     return;
339   }
340
341   const Handle(Geom_Curve)& GC = C.Curve();
342   myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
343
344   Standard_Boolean addorigin = Standard_False;
345   Standard_Boolean setrange  = Standard_False;
346
347   if (addorigin) {
348     if ( GC->IsClosed() ) {
349       // in case of a closed curve, insert in E a vertex located at the origin
350       // of the curve C.
351       TopoDS_Vertex V;
352       Standard_Real first = GC->FirstParameter();
353       gp_Pnt P = GC->Value(first);
354       myBuilder.MakeVertex(V,P,C.Tolerance());
355       myBuilder.Add(E,V);
356       V.Reverse();
357       myBuilder.Add(E,V);
358       
359       // If the curve is a degree 1 bspline set the range to 1 .. NbPoles
360       Handle(Geom_BSplineCurve) BSC = Handle(Geom_BSplineCurve)::DownCast(GC);
361       if (!BSC.IsNull()) {
362         if (BSC->Degree() == 1) {
363           myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
364 #ifdef DEB
365           if (TopOpeBRepDS_GettraceBUTO()) {
366             cout<<endl<<"TopOpeBRepDS_BuildTool : ";
367             cout<<"new range of "<< 1 <<" "<<BSC->NbPoles()<<endl;
368           }
369 #endif
370         }
371       }
372       
373 #ifdef DEB
374       if (TopOpeBRepDS_GettraceBUTO()) {
375         cout<<"TopOpeBRepDS_BuildTool : ";
376         cout<<"vertices on parameter "<<first<<endl;
377         cout<<" point is "; DUMPPNT(P,cout); cout<<endl;
378       }
379 #endif
380     }
381   }
382
383   if (setrange) {
384     Standard_Real first,last;
385     Standard_Boolean rangedef = C.Range(first,last);
386     if (rangedef) {
387       Range(E,first,last);
388 #ifdef DEB
389       if (TopOpeBRepDS_GettraceBUTO()) {
390         cout<<"TopOpeBRepDS_BuildTool : ";
391         cout<<"set edge range : "<<first<<" "<<last<<endl;
392       }
393 #endif
394     }
395   }
396 }
397
398 //=======================================================================
399 //function : MakeEdge
400 //purpose  : 
401 //=======================================================================
402
403 void  TopOpeBRepDS_BuildTool::MakeEdge
404 (TopoDS_Shape& E, 
405  const TopOpeBRepDS_Curve& C,
406  const TopOpeBRepDS_DataStructure& BDS) const
407 {
408   // Gestion des courbes nulles pour carreaux pointus
409   // RLE 28-6-94
410
411   TopoDS_Edge& EE = TopoDS::Edge(E);
412
413   if (C.Curve().IsNull()) {
414     myBuilder.MakeEdge(EE);
415     myBuilder.Degenerated(EE,Standard_True);
416     
417     // Creation d'une arete avec PCurve connectee a la BDS Curve 
418     // JYL 22-09-94
419     Handle(TopOpeBRepDS_Interference) I = C.GetSCI1();
420     Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI;
421     SCI=Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(I);
422     Standard_Integer iS = SCI->Support();
423     const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
424     const Handle(Geom_Surface)& GS  = DSS.Surface();
425     const Handle(Geom2d_Curve)& PC  = SCI->PCurve();
426     myBuilder.UpdateEdge(EE,PC,GS,TopLoc_Location(),DSS.Tolerance());
427     return;
428   }
429   else {
430     const Handle(Geom_Curve)& GC = C.Curve();
431     myBuilder.MakeEdge(EE,GC,C.Tolerance());
432   }
433
434 }
435
436 //=======================================================================
437 //function : MakeEdge
438 //purpose  : 
439 //=======================================================================
440
441 void  TopOpeBRepDS_BuildTool::MakeEdge
442 (TopoDS_Shape& E, 
443  const Handle(Geom_Curve)& C,
444  const Standard_Real Tol)const 
445 {
446   myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
447 }
448
449
450 //=======================================================================
451 //function : MakeEdge
452 //purpose  : 
453 //=======================================================================
454
455 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
456 {
457   myBuilder.MakeEdge(TopoDS::Edge(E));
458 }
459
460
461 //=======================================================================
462 //function : MakeWire
463 //purpose  : 
464 //=======================================================================
465
466 void  TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const 
467 {
468   myBuilder.MakeWire(TopoDS::Wire(W));
469 }
470
471
472 //=======================================================================
473 //function : MakeFace
474 //purpose  : 
475 //=======================================================================
476
477 void  TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F, 
478                                        const TopOpeBRepDS_Surface& S)const 
479 {
480   myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
481 }
482
483
484 //=======================================================================
485 //function : MakeShell
486 //purpose  : 
487 //=======================================================================
488
489 void  TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const 
490 {
491   myBuilder.MakeShell(TopoDS::Shell(Sh));
492 }
493
494
495 //=======================================================================
496 //function : MakeSolid
497 //purpose  : 
498 //=======================================================================
499
500 void  TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const 
501 {
502   myBuilder.MakeSolid(TopoDS::Solid(S));
503 }
504
505
506 //=======================================================================
507 //function : CopyEdge
508 //purpose  : 
509 //=======================================================================
510
511 void  TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein, 
512                                        TopoDS_Shape& Eou)const 
513 {
514
515   // Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
516   // apres modification de la primitive Sphere pour parametrisation de 
517   // l'arete meridienne en -pi/2,+pi/2.
518   // Ein est l'arete de couture complete d'une sphere complete
519   // BRep_Tool::Range(Ein) --> -pi/2,+pi/2
520   // BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
521   // NYI reflexion sur la notion de Range d'une arete et de la geometrie
522   // NYI sous jacente dans le cas ou, par construction, les vertex d'une
523   // NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
524   // NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
525   // On redefinit desormais le range de l'arete Eou, a la place de se 
526   // contenter du simplissime Eou = Ein.EmptyCopied();
527   // merci les amis : correction bug PRO2586
528
529   Standard_Real f,l;
530   TopoDS_Edge E1 = TopoDS::Edge(Ein); 
531   BRep_Tool::Range(E1,f,l);
532   Eou = Ein.EmptyCopied();
533   TopoDS_Edge E2 = TopoDS::Edge(Eou); 
534   myBuilder.Range(E2,f,l);
535 }
536
537
538 //=======================================================================
539 //function : GetOrientedEdgeVertices
540 //purpose  : 
541 //=======================================================================
542
543 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
544 (TopoDS_Edge& E,
545  TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
546  Standard_Real& Parmin, Standard_Real& Parmax) const
547 {
548   if ( E.Orientation() == TopAbs_FORWARD) 
549     TopExp::Vertices(E,Vmin,Vmax);
550   else
551     TopExp::Vertices(E,Vmax,Vmin);
552   if ( !Vmin.IsNull() && !Vmax.IsNull()) {  
553     Parmin = BRep_Tool::Parameter(Vmin,E);
554     Parmax = BRep_Tool::Parameter(Vmax,E);
555   }
556 }
557
558 //=======================================================================
559 //function : UpdateEdgeCurveTol
560 //purpose  : 
561 //=======================================================================
562
563 void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
564 //(const TopoDS_Face& F1,const TopoDS_Face& F2,
565 (const TopoDS_Face& ,const TopoDS_Face& ,
566  TopoDS_Edge& E, const Handle(Geom_Curve)& C3Dnew,
567 // const Standard_Real tol3d,
568  const Standard_Real ,
569 // const Standard_Real tol2d1,
570  const Standard_Real ,
571 // const Standard_Real tol2d2,
572  const Standard_Real ,
573  Standard_Real& newtol,
574  Standard_Real& newparmin,
575  Standard_Real& newparmax) const
576
577 {
578   if (C3Dnew.IsNull()) return;
579   BRep_Builder BB;
580
581   // newtol = max des tolerances atteintes en 3d
582 // JMB le 06 Juillet 1999
583 // les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade, 
584 // elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
585 // 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
586 // d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
587 // plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la topologie
588 // a coder des tolerances enormes dans les pieces resultats rendant celles-ci inexpoitables.
589 // De plus on essayait de rafiner la tolerance en appelant les UResolution sur les surfaces support.
590 // sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et peut amener a des valeurs
591 // abberantes.
592 // On decide donc de laisser la tolerance de l'edge telle qu'elle est afin d'avoir un comportement similaire
593 // a 2.0. Jusqu'a present on a constate que des problemes avec la methode de calcul d'erreur des approx.
594
595
596   newtol = 1.E-7;
597 //  Standard_Real r1,r2;
598 //  r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
599 //  r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
600 //  newtol=tol3d;
601 //  if (r1>newtol) newtol=r1;
602 //  if (r2>newtol) newtol=r2;
603 //#ifdef DEB
604 //  if (TopOpeBRepDS_GettraceDSNC()) cout<<"newtol = "<<newtol<<endl;
605 //#endif
606
607 //  newtol *= 1.5;
608
609   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
610   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
611   
612   Standard_Real tolmin=BRep_Tool::Tolerance(Vmin);
613   if(newtol>tolmin) tolmin=newtol;
614   Standard_Real tolmax=BRep_Tool::Tolerance(Vmax);
615   if(newtol>tolmax) tolmax=newtol;
616
617
618 //  newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
619 //  newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
620
621  // +merge 04-07-97
622   Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
623   if(GTC.IsNull()) {
624     Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
625     if(GBSC.IsNull()) {
626       newparmin = parmin;
627       newparmax = parmax;
628     } else {
629       newparmin=C3Dnew->FirstParameter();
630       newparmax=C3Dnew->LastParameter();
631     } 
632   } else {
633     newparmin=C3Dnew->FirstParameter();
634     newparmax=C3Dnew->LastParameter();
635   } // +merge 04-07-97
636
637   if (Vmin.Orientation() == TopAbs_FORWARD) { 
638     BB.UpdateVertex(Vmin,newparmin,E,tolmin);
639     BB.UpdateVertex(Vmax,newparmax,E,tolmax);
640   }
641   else {
642     BB.UpdateVertex(Vmin,newparmax,E,tolmin);
643     BB.UpdateVertex(Vmax,newparmin,E,tolmax);
644   }
645   
646 //  DSBT.Curve3D(E,C3Dnew,newtol);  // -merge 04-07-97
647   Curve3D(E,C3Dnew,newtol);
648   
649   // projection des vertex INTERNAL de E pour parametrage
650   // sur la nouvelle courbe C3Dnew de l'arete E
651   TopExp_Explorer exi(E,TopAbs_VERTEX);
652   for (;exi.More(); exi.Next() ) {
653     const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
654     if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
655     gp_Pnt P = BRep_Tool::Pnt(vi);
656     Standard_Real tolvi=TopOpeBRepTool_ShapeTool::Tolerance(vi);
657     GeomAPI_ProjectPointOnCurve dm(P,C3Dnew,newparmin,newparmax);
658     Standard_Boolean dmdone = dm.Extrema().IsDone();
659     if ( dmdone ) {
660       if ( dm.NbPoints() ) {
661         Standard_Real newpar = dm.LowerDistanceParameter();
662         BB.UpdateVertex(vi,newpar,E,tolvi);
663       }
664     }
665   } // INTERNAL vertex
666 }
667
668 //=======================================================================
669 //function : ApproxCurves
670 //purpose  : 
671 //=======================================================================
672
673 void  TopOpeBRepDS_BuildTool::ApproxCurves
674 (const TopOpeBRepDS_Curve& C,
675  TopoDS_Edge& E,
676  Standard_Integer& inewC,
677  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
678 {
679   TopOpeBRepDS_Curve newC1;
680   inewC = HDS->MakeCurve(C,newC1);
681   TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
682
683 #ifdef DEB
684 //  Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
685   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
686 #endif
687   
688   // C1 curves have been approximated by BSplines of degree 1 :
689   // compute new geometry on curves.
690
691   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
692   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
693   
694   const Handle(Geom_Curve)& C3D = C.Curve();
695   const Handle(Geom2d_Curve)& PC1 = C.Curve1();
696   const Handle(Geom2d_Curve)& PC2 = C.Curve2();
697
698   // Vmin,Vmax = bounding vertices of edge <E>
699   // and their parameters parmin,parmax .
700
701   TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
702   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
703
704 #ifdef DEB
705   if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
706   if (tBUTO) DUMPCURVES(C3D,C);
707 #endif
708   
709   Handle(Geom_Curve)   C3Dnew;
710   Handle(Geom2d_Curve) PC1new;
711   Handle(Geom2d_Curve) PC2new;
712   Standard_Real tolreached3d,tolreached2d;
713   
714   Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
715                          C3D,PC1,PC2,F1,F2,
716                          C3Dnew,PC1new,PC2new,
717                          tolreached3d,tolreached2d);
718
719   Standard_Real newtol,newparmin,newparmax;
720   // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
721   if (!approxMade) {
722 #ifdef DEB
723     cout<<"TopOpeBRepDS_BuildTool::ApproxCurves : approx failed, leave curves of degree 1"
724       <<endl;
725 #endif
726     newtol = BRep_Tool::Tolerance(E);
727     newparmin = parmin;
728     newparmax = parmax;
729     C3Dnew = C3D;
730     PC1new = PC1;
731     PC2new = PC2;
732   }
733   else {
734     UpdateEdgeCurveTol
735       (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
736        newtol,newparmin,newparmax);
737   }
738
739   if (!C3Dnew.IsNull()) {
740     newC.DefineCurve(C3Dnew,newtol,Standard_False);
741     newC.SetRange(newparmin,newparmax);
742   }
743
744   if (!PC1new.IsNull()) newC.Curve1(PC1new);
745   if (!PC2new.IsNull()) newC.Curve2(PC2new);
746 }
747
748
749 //=======================================================================
750 //function : ComputePCurves
751 //purpose  : 
752 //=======================================================================
753 Standard_Boolean FUN_getUV
754 (const Handle(Geom_Surface) surf,
755  const Handle(Geom_Curve) C3D,
756  const Standard_Real par3d,
757  Standard_Real& u0,
758  Standard_Real& v0)
759 {
760   gp_Pnt P3d; C3D->D0(par3d,P3d);
761   GeomAPI_ProjectPointOnSurf pons(P3d,surf);
762   if (pons.NbPoints() < 1) return Standard_False;
763   pons.LowerDistanceParameters(u0,v0);
764   return Standard_True;
765 }
766
767 Standard_Boolean FUN_reversePC
768 (Handle(Geom2d_Curve) PCnew,
769  const TopoDS_Face& F,
770  const gp_Pnt& P3DC3D,
771  const Standard_Real par2d,
772  const Standard_Real tol)
773 {
774   gp_Pnt2d P2D; PCnew->D0(par2d,P2D);
775   BRepAdaptor_Surface BAS(F,Standard_False);
776   gp_Pnt P3D = BAS.Value(P2D.X(),P2D.Y());
777   Standard_Boolean PCreversed = Standard_False;
778   Standard_Boolean sam = P3D.IsEqual(P3DC3D,tol);
779   PCreversed = !sam;
780
781 #ifdef DEB
782 #ifdef DRAW
783   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
784   if (tBUTO) {FUN_draw(P3DC3D); FUN_draw(P3D);}
785 #endif
786 #endif
787
788   if ( PCreversed ) {
789     Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
790     if (!PC.IsNull()) {
791       Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
792       gp_Dir2d d = L->Direction();
793       d.Reverse();
794       L->SetDirection(d);
795     }
796   }
797   return PCreversed;
798 }
799 Standard_Boolean FUN_makeUisoLineOnSphe
800 (const TopoDS_Face& F, // with geometry the spherical surface
801  const Handle(Geom_Curve) C3D, 
802  Handle(Geom2d_Curve) PCnew,
803  const Standard_Real tol3d)
804 {
805   // p3df,p3dl : C3d first and last parameters
806   Standard_Real p3df = C3D->FirstParameter();
807   Standard_Real p3dl = C3D->LastParameter();
808
809   // u0,v0 : C3d(par3d) UV parameters
810   Standard_Real deltainf = 0.243234, deltasup = 0.543345;
811   Standard_Real par3dinf = (1-deltainf)*p3df + deltainf*p3dl;
812   Standard_Real par3dsup = (1-deltasup)*p3df + deltasup*p3dl;
813   Standard_Real uinf,vinf,usup,vsup;
814   Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
815   if (!FUN_getUV(surf,C3D,par3dinf,uinf,vinf)) return Standard_False;
816   if (!FUN_getUV(surf,C3D,par3dsup,usup,vsup)) return Standard_False;
817   Standard_Real tol = Precision::Parametric(tol3d);
818   if (Abs(uinf-usup) > tol) return Standard_False;
819 #ifdef DEB
820 //  Standard_Real deltav = vsup-vinf;
821 #endif
822
823   Standard_Boolean isvgrowing = (vsup - vinf > -tol);
824   gp_Dir2d vdir;
825   if (isvgrowing) vdir = gp_Dir2d(0,1);
826   else            vdir = gp_Dir2d(0,-1);
827   
828   gp_Pnt2d origin(uinf,vinf);
829   origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
830   Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
831   if (!PC.IsNull()) {  
832     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC); 
833     L->SetLin2d(gp_Lin2d(origin,vdir));
834 #ifdef DEB
835 #ifdef DRAW
836   Standard_Boolean trc = TopOpeBRepDS_GettraceBUTO();
837     if (trc) {
838       FUN_draw(gp_Pnt2d(uinf,vinf));
839       FUN_draw(gp_Pnt2d(usup,vsup));
840       FUN_draw(L,p3dl-p3df);
841     }
842 #endif
843 #endif
844   } // (!PC.IsNull())
845   
846   return Standard_True;
847 }
848
849 void TopOpeBRepDS_BuildTool::ComputePCurves
850 (const TopOpeBRepDS_Curve& C,
851  TopoDS_Edge& E,
852  TopOpeBRepDS_Curve& newC,
853  const Standard_Boolean comppc1,
854  const Standard_Boolean comppc2,
855  const Standard_Boolean compc3d) const
856 {
857 #ifdef DEB
858 //  Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
859   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
860   Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
861 #endif
862   
863   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
864   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
865   
866   const Handle(Geom_Curve)& C3D = C.Curve();
867 #ifdef DEB
868 //  const Handle(Geom2d_Curve)& PC1 = C.Curve1();
869 //  const Handle(Geom2d_Curve)& PC2 = C.Curve2();
870 #endif
871
872   // get bounding vertices Vmin,Vmax supported by the new edge <E>
873   // and their corresponding parameters parmin,parmax .
874
875   TopoDS_Vertex Vmin,Vmax;Standard_Real parmin,parmax;
876   GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
877
878 #ifdef DEB
879   if (tBUTO) cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
880   if (tBUTO) DUMPCURVES(C3D,C);
881 #endif
882
883   Handle(Geom2d_Curve) PC1new;
884   Handle(Geom2d_Curve) PC2new;
885   
886   if(C3D.IsNull()) {
887     Standard_Real tolreached2d1, tolreached2d2, r1, r2, tol=0;
888     if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3D,tolreached2d1);
889     if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3D,tolreached2d2);
890     
891     r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
892     r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
893     tol = Max(tol,r1);
894     tol = Max(tol,r2);
895     newC.Tolerance(tol);
896     
897     if (!PC1new.IsNull()) newC.Curve1(PC1new);
898     if (!PC2new.IsNull()) newC.Curve2(PC2new);
899
900     return;
901   }
902   
903   Handle(Geom_Curve) C3Dnew = C3D;
904   
905   if ( C3D->IsPeriodic() ) {
906     // ellipse on cone : periodize parmin,parmax
907     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
908     Standard_Real f,l;
909     if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
910     else {                                      f = parmax; l = parmin; }
911     parmin = f; parmax = l;
912     ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
913     if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
914     
915 #ifdef DEB
916     if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
917     if (tBUTO||tTRPE) cout<<"                   --> parmin,parmax "<<parmin<<","<<parmax<<endl;
918 #endif
919   }
920   
921   Standard_Real tolreached3d = C.Tolerance();
922   Standard_Real tolreached2d1 = C.Tolerance();
923   Standard_Real tolreached2d2 = C.Tolerance();
924   
925   if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
926   if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
927   
928   Standard_Real newtol,newparmin,newparmax;
929   UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
930                      newtol,newparmin,newparmax);
931   
932     // xpu : suite merge : 07-07-97
933     // xpu : 17-06-97
934     // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
935     //       est une isos de la sphere
936     // NYI : enlever FUN_reversePC
937     Standard_Boolean UisoLineOnSphe1 = Standard_False;
938     UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
939     if (UisoLineOnSphe1) ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
940
941     Standard_Boolean UisoLineOnSphe2 = Standard_False;
942     UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
943     if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
944     // xpu : 17-06-97
945     // xpu : suite merge : 07-07-97
946
947   if (!C3Dnew.IsNull()) {
948     newC.Curve(C3Dnew,newtol);
949     newC.SetRange(newparmin, newparmax);
950   }
951   if (!PC1new.IsNull()) newC.Curve1(PC1new);
952   if (!PC2new.IsNull()) newC.Curve2(PC2new);
953   
954 #ifdef DEB
955   if (tBUTO) DUMPCURVES(C3Dnew,newC);
956 #endif
957 }
958
959 //=======================================================================
960 //function : PutPCurves
961 //purpose  : 
962 //=======================================================================
963
964 void  TopOpeBRepDS_BuildTool::PutPCurves
965 (const TopOpeBRepDS_Curve& newC,
966  TopoDS_Edge& E,
967  const Standard_Boolean comppc1,
968  const Standard_Boolean comppc2) const
969 {
970
971   TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
972   Handle(Geom2d_Curve) PC1 = newC.Curve1();
973   if (!PC1.IsNull() && comppc1) {
974     PCurve(F1,E,PC1);
975   }
976   
977   TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
978   Handle(Geom2d_Curve) PC2 = newC.Curve2();
979   if (!PC2.IsNull() && comppc2) {
980     PCurve(F2,E,PC2);
981   }
982   
983 }
984
985 //=======================================================================
986 //function : RecomputeCurves
987 //purpose  : 
988 //=======================================================================
989
990 void  TopOpeBRepDS_BuildTool::RecomputeCurves
991 (const TopOpeBRepDS_Curve& C,
992 // const TopoDS_Edge& oldE,
993  const TopoDS_Edge& ,
994  TopoDS_Edge& E,
995  Standard_Integer& inewC,
996  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
997 {
998   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
999   const Standard_Boolean compc3d = GT.CompC3D();
1000   const Standard_Boolean comppc1 = GT.CompPC1();
1001   const Standard_Boolean comppc2 = GT.CompPC2();
1002   const Standard_Boolean comppc = comppc1 || comppc2;
1003   const Standard_Boolean iswalk = C.IsWalk();
1004   const Standard_Boolean approx = Approximation();
1005   
1006   const Handle(Geom_Curve)& C3D = C.Curve();
1007   if (comppc1 && C.Shape1().IsNull()) Standard_ProgramError::Raise
1008     ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1009   if (comppc2 && C.Shape2().IsNull()) Standard_ProgramError::Raise
1010     ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1011   TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(E,Vmin,Vmax);
1012   if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1013     ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1014   if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1015     ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1016   
1017   if (iswalk && approx) {
1018     if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1019       ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1020     ApproxCurves(C, E, inewC, HDS);
1021     TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1022     PutPCurves(newC, E, comppc1, comppc2);
1023   }
1024 //  else if (iswalk && interpol) {
1025 //    InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
1026 //    TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1027 //    PutPCurves(newC, E, comppc1, comppc2);
1028 //  }
1029
1030   else {
1031     if (comppc) {
1032       TopOpeBRepDS_Curve newC1;
1033       inewC = HDS->MakeCurve(C,newC1);
1034       TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
1035       if(iswalk && !approx) {
1036         if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1037           ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1038         newC.Curve1(C.Curve1());
1039         newC.Curve2(C.Curve2());
1040       }
1041       else
1042         ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);  
1043       PutPCurves(newC, E, comppc1, comppc2);
1044     }
1045   }
1046 }
1047
1048 //=======================================================================
1049 //function : CopyFace
1050 //purpose  : 
1051 //=======================================================================
1052
1053 void  TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin, 
1054                                        TopoDS_Shape& Fou)const 
1055 {
1056   Fou = Fin.EmptyCopied();
1057 }
1058
1059
1060 //=======================================================================
1061 //function : AddEdgeVertex
1062 //purpose  : 
1063 //=======================================================================
1064
1065 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein, 
1066                                             TopoDS_Shape& Eou, 
1067                                             const TopoDS_Shape& V)const 
1068 {
1069   myBuilder.Add(Eou,V);
1070   TopoDS_Edge e1 = TopoDS::Edge(Ein);
1071   TopoDS_Edge e2 = TopoDS::Edge(Eou);
1072   TopoDS_Vertex v1 = TopoDS::Vertex(V);
1073   myBuilder.Transfert(e1,e2,v1,v1);
1074 }
1075
1076
1077 //=======================================================================
1078 //function : AddEdgeVertex
1079 //purpose  : 
1080 //=======================================================================
1081
1082 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E, 
1083                                             const TopoDS_Shape& V)const 
1084 {
1085   myBuilder.Add(E,V);
1086 }
1087
1088
1089 //=======================================================================
1090 //function : AddWireEdge
1091 //purpose  : 
1092 //=======================================================================
1093
1094 void  TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W, 
1095                                           const TopoDS_Shape& E)const 
1096 {
1097   myBuilder.Add(W,E);
1098 }
1099
1100
1101 //=======================================================================
1102 //function : AddFaceWire
1103 //purpose  : 
1104 //=======================================================================
1105
1106 void  TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F, 
1107                                           const TopoDS_Shape& W)const 
1108 {
1109   myBuilder.Add(F,W);
1110 }
1111
1112
1113 //=======================================================================
1114 //function : AddShellFace
1115 //purpose  : 
1116 //=======================================================================
1117
1118 void  TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh, 
1119                                            const TopoDS_Shape& F)const 
1120 {
1121   myBuilder.Add(Sh,F);
1122 }
1123
1124
1125 //=======================================================================
1126 //function : AddSolidShell
1127 //purpose  : 
1128 //=======================================================================
1129
1130 void  TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S, 
1131                                             const TopoDS_Shape& Sh)const 
1132 {
1133   myBuilder.Add(S,Sh);
1134 }
1135
1136
1137 //=======================================================================
1138 //function : Parameter
1139 //purpose  : 
1140 //=======================================================================
1141
1142 void  TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E, 
1143                                         const TopoDS_Shape& V, 
1144                                         const Standard_Real P)const 
1145 {
1146   const TopoDS_Edge&   e = TopoDS::Edge(E);
1147   const TopoDS_Vertex& v = TopoDS::Vertex(V);
1148   Standard_Real p = P;
1149
1150   // 13/07/95 : 
1151   TopLoc_Location loc; Standard_Real f,l;
1152   Handle(Geom_Curve) C = BRep_Tool::Curve(e,loc,f,l);
1153   if ( !C.IsNull() && C->IsPeriodic()) {
1154     Standard_Real per = C->Period();
1155 #ifdef DEB
1156     TopAbs_Orientation oV;
1157 #else
1158     TopAbs_Orientation oV=TopAbs_FORWARD;
1159 #endif
1160     TopExp_Explorer exV(e,TopAbs_VERTEX);
1161     for (; exV.More(); exV.Next()) {
1162       const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
1163       if ( vofe.IsSame(v) ) {
1164         oV = vofe.Orientation();
1165         break;
1166       }
1167     }
1168     if ( exV.More() ) {
1169       if ( oV == TopAbs_REVERSED ) {
1170         if ( p < f ) {
1171           Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
1172 #ifdef DEB
1173           if (TopOpeBRepDS_GettraceBUTO() ) {
1174             cout<<"BuildTool Parameter : "<<p<<" --> "<<pp<<endl;
1175           }
1176 #endif
1177           p = pp;
1178         }
1179       }
1180     }
1181   }
1182
1183   myBuilder.UpdateVertex(v,p,e,
1184                          0);   // NYI : Tol on new vertex ?? 
1185 }
1186
1187 //=======================================================================
1188 //function : Range
1189 //purpose  : 
1190 //=======================================================================
1191
1192 void  TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E, 
1193                                     const Standard_Real first,
1194                                     const Standard_Real last)const 
1195 {
1196   myBuilder.Range(TopoDS::Edge(E),first,last);
1197 }
1198
1199
1200 //=======================================================================
1201 //function : UpdateEdge
1202 //purpose  : 
1203 //=======================================================================
1204
1205 void  TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
1206                                          TopoDS_Shape& Eou)const
1207 {
1208   TopLoc_Location loc;
1209   Standard_Real f1,l1;
1210   Standard_Real f2,l2;
1211   Handle(Geom_Curve) Cin = BRep_Tool::Curve(TopoDS::Edge(Ein),loc,f1,l1);
1212   Handle(Geom_Curve) Cou = BRep_Tool::Curve(TopoDS::Edge(Eou),loc,f2,l2);
1213   if (Cin.IsNull() || Cou.IsNull()) return;
1214   
1215   if ( Cou->IsPeriodic() ) {
1216     Standard_Real f2n = f2, l2n = l2;
1217     if ( l2n <= f2n ) {
1218       ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1219       Range(Eou,f2n,l2n);
1220 #ifdef DEB
1221       if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1222         cout<<endl;
1223         cout<<"UpdateEdge f1,l1   "<<f1<<" "<<l1<<endl;
1224         cout<<"UpdateEdge f2,l2   "<<f2<<" "<<l2<<" "<<endl;
1225         cout<<"UpdateEdge f2n,l2n "<<f2n<<" "<<l2n<<endl;
1226         TopExp_Explorer ex;
1227         for (ex.Init(Eou,TopAbs_VERTEX); ex.More(); ex.Next()) {
1228           TopoDS_Vertex v = TopoDS::Vertex(ex.Current());
1229           Standard_Real par = BRep_Tool::Parameter(v,TopoDS::Edge(Eou));
1230           TopAbs_Orientation o = v.Orientation();
1231           cout<<"BuildTool vertex ";TopAbs::Print(o,cout); cout<<" "<<par<<endl;
1232         }
1233       }
1234 #endif
1235     }
1236   }
1237 }
1238
1239 //=======================================================================
1240 //function : Project
1241 //purpose  : project a vertex on a curve
1242 //=======================================================================
1243
1244 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1245                                 const TopoDS_Vertex& V,
1246                                 Standard_Real& p)
1247 {
1248   gp_Pnt P = BRep_Tool::Pnt(V);
1249   Standard_Real tol = BRep_Tool::Tolerance(V);
1250   GeomAdaptor_Curve GAC(C);
1251   Extrema_ExtPC extrema(P,GAC);
1252   if (extrema.IsDone()) {
1253     Standard_Integer i,n = extrema.NbExt();
1254     for (i = 1; i <= n; i++) {
1255       if (extrema.IsMin(i)) {
1256         Extrema_POnCurv EPOC = extrema.Point(i);
1257         if (P.Distance(EPOC.Value()) <= tol) {
1258           p = EPOC.Parameter();
1259           return Standard_True;
1260         }
1261       }
1262     }
1263   }
1264   return Standard_False;
1265 }
1266
1267
1268 //=======================================================================
1269 //function : Parameter
1270 //purpose  : 
1271 //=======================================================================
1272
1273 void  TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1274                                         TopoDS_Shape& E,
1275                                         TopoDS_Shape& V)const 
1276 {
1277   Standard_Real newparam;
1278   Project(C.Curve(),TopoDS::Vertex(V),newparam);
1279   Parameter(E,V,newparam);
1280 }
1281
1282
1283 //=======================================================================
1284 //function : Curve3D
1285 //purpose  : 
1286 //=======================================================================
1287
1288 void  TopOpeBRepDS_BuildTool::Curve3D
1289 (TopoDS_Shape& E, 
1290  const Handle(Geom_Curve)& C,
1291  const Standard_Real Tol)const 
1292 {
1293   myBuilder.UpdateEdge(TopoDS::Edge(E),
1294                        C,
1295                        Tol);
1296 }
1297
1298
1299 //=======================================================================
1300 //function : TranslateOnPeriodic
1301 //purpose  : 
1302 //=======================================================================
1303
1304 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1305   (TopoDS_Shape& F,
1306    TopoDS_Shape& E,
1307    Handle(Geom2d_Curve)& PC) const
1308 {
1309   // get range C3Df,C3Dl of 3d curve C3D of E
1310   TopLoc_Location L; 
1311   Standard_Real C3Df,C3Dl;
1312 //  Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
1313   Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl); // 13-07-97: xpu
1314  
1315   Standard_Real first = C3Df, last = C3Dl;
1316   if (C3D->IsPeriodic()) {
1317     if ( last < first ) last += Abs(first - last);
1318   }
1319
1320   // jyl-xpu : 13-06-97 : 
1321   // if <PC> is U isoline on sphere, a special parametrization
1322   // is to provide, we compute <PC> (which is a line) bounds 
1323   // with C3D bounds.
1324   Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1325   Standard_Boolean newv = Standard_True;
1326
1327   Standard_Real du,dv;
1328
1329   gp_Pnt2d ptest;
1330   Standard_Real t =(first+last)*.5;
1331   PC->D0(t,ptest);
1332   Standard_Real u1 = ptest.X(), u2 = u1;
1333   Standard_Real v1 = ptest.Y(), v2 = v1;
1334
1335   if (newv) {
1336     if (UisoLineOnSphe) {
1337       Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl);
1338       GeomAdaptor_Curve GC(c3d); gp_Pnt p3dtest = GC.Value(t);
1339       Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(F));
1340       GeomAPI_ProjectPointOnSurf pons(p3dtest,surf);
1341       if (!(pons.NbPoints() < 1))
1342         pons.LowerDistanceParameters(u2,v2);
1343     } else TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1344   }
1345   if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1346   du = u2 - u1, dv = v2 - v1;    
1347
1348   if ( du != 0. || dv != 0.) {
1349 #ifdef DEB
1350     if (TopOpeBRepDS_GettraceBUTO() || TopOpeBRepDS_GettraceTRPE()) {
1351       cout<<endl;
1352       cout<<"TranslateOnPeriodic :  Curve range "<<C3Df<<" "<<C3Dl<<endl;
1353       Standard_Real PCf,PCl;
1354       BRep_Tool::Range(TopoDS::Edge(E),TopoDS::Face(F),PCf,PCl);
1355       cout<<"TranslateOnPeriodic : PCurve range "<<PCf<<" "<<PCl<<endl;
1356       cout<<"TranslateOnPeriodic :  translation "<<du<<" "<<dv<<endl;
1357     }
1358 #endif
1359     // translate curve PC of du,dv
1360     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(PC->Copy());
1361     PCT->Translate(gp_Vec2d(du,dv));
1362     PC = PCT;
1363   }
1364 }
1365
1366
1367 // RLE - IAB 16 june 94
1368 // should be provided by the BRep_Builder
1369
1370 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1371                                                TopoDS_Edge& E,
1372                                                const TopoDS_Face& F,
1373                                                const TopAbs_Orientation O,
1374                                                const Handle(Geom2d_Curve)& C)
1375 {
1376   // check if there is already a pcurve on non planar faces
1377   Standard_Real f,l;
1378   Handle(Geom2d_Curve) OC;
1379   TopLoc_Location SL;
1380   Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1381   if (GP.IsNull())
1382     OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1383
1384   if (OC.IsNull()) 
1385     B.UpdateEdge(E,C,F,Precision::Confusion());
1386   else {
1387     Standard_Boolean degen = BRep_Tool::Degenerated(E);
1388     if(!degen){
1389       if (O == TopAbs_REVERSED) 
1390         B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1391       else 
1392         B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1393     }
1394   }
1395 }
1396
1397 #ifdef DEB
1398 //------------------------------------------------------------------------
1399 static void DUMPPCURVE(const TopoDS_Edge& EE, 
1400                        const TopoDS_Face& FF,
1401                        const Handle(Geom2d_Curve)& PC)
1402 //------------------------------------------------------------------------
1403 {
1404   TopLoc_Location L; Standard_Real Cf,Cl;
1405   Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1406   if (C->IsPeriodic()) {
1407     cout<<endl;
1408       cout<<"DUMPPCURVE  : ";cout<<" face "; ::PrintSurface(FF,cout); cout<<endl;
1409       cout<<"PCurve type : ";TopOpeBRepDS_Dumper::PrintType(PC,cout); cout<<endl;
1410     gp_Pnt oC; 
1411     if (::GetOrigin(C,oC)) 
1412       cout<<"(E)Curve origin : "<<oC.X()<<" "<<oC.Y()<<" "<<oC.Z()<<endl;
1413       cout<<"(E)Curve range  : Cf,Cl = "<<Cf<<" "<<Cl<<endl;
1414     
1415     Standard_Real PCf,PCl;
1416     PCf = PC->FirstParameter(); PCl = PC->LastParameter();
1417     gp_Pnt2d oPC; 
1418     if (::GetOrigin(PC,oPC))
1419       cout<<"(PC)PCurve origin : "<<oPC.X()<<" "<<oPC.Y()<<endl;
1420       cout<<"(PC)PCurve range  : PCf,PCl = "<<PCf<<" "<<PCl<<endl;
1421   }
1422 }
1423 #endif
1424
1425 //=======================================================================
1426 //function : PCurve
1427 //purpose  : 
1428 //=======================================================================
1429
1430 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F, 
1431                                      TopoDS_Shape& E, 
1432                                      const Handle(Geom2d_Curve)& PC)const 
1433 {
1434   if ( ! PC.IsNull() ) {
1435     TopoDS_Face FF = TopoDS::Face(F);
1436     TopoDS_Edge EE = TopoDS::Edge(E);
1437     Handle(Geom2d_Curve) PCT = PC;
1438
1439 #ifdef DEB
1440 #ifdef DRAW
1441     Standard_Boolean trc = Standard_False;
1442     if (trc) FUN_draw(FF);
1443     if (trc) FUN_draw(EE);
1444     if (trc) FUN_draw(PC,0.);
1445 #endif
1446     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1447 #endif
1448     
1449     // pour iab, ajout de Translate
1450     Standard_Boolean tran = myTranslate;
1451 #ifdef DEB
1452     if ( TopOpeBRepDS_GettraceSANTRAN()) {
1453       tran = Standard_False; 
1454       cout<<"SANS translation de pcurve"<<endl; 
1455     }
1456 #endif
1457
1458     // xpu : 13-06-97 : 
1459     // recompute twice the pcurve boundaries if OverWrite
1460     // if the pcurve <PC> is U isoline on sphere -> to avoid.
1461     Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1462     Standard_Boolean overwrite = UisoLineOnSphe? Standard_False:myOverWrite;
1463     // xpu : 13-06-97
1464
1465     if (tran)      
1466       TranslateOnPeriodic(F,E,PCT);  
1467
1468     if (overwrite) 
1469       myBuilder.UpdateEdge(EE,PCT,FF,0);
1470     else           
1471       TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1472
1473     // parametrage sur la nouvelle courbe 2d
1474     TopExp_Explorer exi(E,TopAbs_VERTEX);
1475     for (;exi.More(); exi.Next() ) {
1476       const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
1477       if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
1478       Standard_Real tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
1479       // NYI tester l'existence d'au moins
1480       // NYI un parametrage de vi sur EE (en 3d ou en 2d) 
1481       // NYI --> a faire dans BRep_Tool
1482       Standard_Real newpar = BRep_Tool::Parameter(vi,EE);
1483       myBuilder.UpdateVertex(vi,newpar,EE,FF,tolvi);
1484     } // INTERNAL vertex
1485     
1486 #ifdef DEB
1487     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1488 #endif
1489   }
1490 }
1491
1492 //=======================================================================
1493 //function : PCurve
1494 //purpose  : 
1495 //=======================================================================
1496
1497 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F, 
1498                                      TopoDS_Shape& E, 
1499                                      const TopOpeBRepDS_Curve& CDS,
1500                                      const Handle(Geom2d_Curve)& PC)const
1501 {
1502   if ( ! PC.IsNull() ) {
1503     TopoDS_Face FF = TopoDS::Face(F);
1504     TopoDS_Edge EE = TopoDS::Edge(E);
1505
1506     Handle(Geom2d_Curve) PCT = PC;
1507     Standard_Real    CDSmin,CDSmax;
1508     Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1509
1510     
1511     TopLoc_Location L; Standard_Real Cf,Cl;
1512     Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1513
1514 #ifdef DEB
1515     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1516 #endif
1517       
1518     if (!C.IsNull()){
1519       Standard_Boolean deca = (Abs(Cf - CDSmin) > Precision::PConfusion());
1520       Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast(PCT);
1521       Standard_Boolean isline2d = !line2d.IsNull();
1522       Standard_Boolean tran=(rangedef && deca && C->IsPeriodic() && isline2d);
1523       if (tran) {
1524         TopLoc_Location Loc;
1525         const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
1526         Standard_Boolean isUperio = Surf->IsUPeriodic();
1527         Standard_Boolean isVperio = Surf->IsVPeriodic();
1528         gp_Dir2d dir2d = line2d->Direction();
1529         Standard_Real delta;
1530         if (isUperio && dir2d.IsParallel(gp::DX2d(),Precision::Angular())) {
1531           delta = (CDSmin - Cf) * dir2d.X();
1532           PCT->Translate(gp_Vec2d(delta,0.));
1533         }
1534         else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1535           delta = (CDSmin - Cf) * dir2d.Y();
1536           PCT->Translate(gp_Vec2d(0.,delta));
1537         }
1538       }
1539     }
1540     
1541     TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1542     
1543 #ifdef DEB
1544     if (TopOpeBRepDS_GettraceTRPE()) DUMPPCURVE(EE,FF,PCT);
1545 #endif
1546   }
1547 }
1548
1549
1550 //=======================================================================
1551 //function : Orientation
1552 //purpose  : 
1553 //=======================================================================
1554
1555 void  TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S, 
1556                                           const TopAbs_Orientation O)const 
1557 {
1558   S.Orientation(O);
1559 }
1560
1561
1562 //=======================================================================
1563 //function : Orientation
1564 //purpose  : 
1565 //=======================================================================
1566
1567 TopAbs_Orientation  TopOpeBRepDS_BuildTool::Orientation
1568   (const TopoDS_Shape& S) const
1569 {
1570   return S.Orientation();
1571 }
1572
1573 //=======================================================================
1574 //function : Closed
1575 //purpose  : 
1576 //=======================================================================
1577
1578 void  TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S, 
1579                                      const Standard_Boolean B)const 
1580 {
1581   S.Closed(B);
1582 }
1583
1584
1585 //=======================================================================
1586 //function : Approximation
1587 //purpose  : 
1588 //=======================================================================
1589
1590 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1591 {
1592   return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1593 }
1594
1595 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1596 {
1597   BRep_Builder BB;
1598   TopLoc_Location L;
1599   Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1600   BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1601 }
1602
1603 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1604                                            const TopoDS_Shape& newF) const
1605 {
1606   BRep_Builder BB;
1607   Standard_Real f,l;
1608   const Handle(Geom2d_Curve)& PC = BRep_Tool::CurveOnSurface(TopoDS::Edge(E),TopoDS::Face(oldF),f,l);
1609   Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
1610   BB.UpdateEdge(TopoDS::Edge(E),PC,TopoDS::Face(newF),tol);
1611 }
1612
1613
1614 /* // - merge 04-07-97
1615 //=======================================================================
1616 //function : RecomputeCurve
1617 //purpose  : 
1618 //=======================================================================
1619
1620 void  TopOpeBRepDS_BuildTool::RecomputeCurve
1621 (const TopOpeBRepDS_Curve& C1,
1622  TopoDS_Shape& E,
1623  TopOpeBRepDS_Curve& C2 ) const
1624 {
1625   // - C1 curves have been approximated by BSplines of degree 1 :
1626   // or
1627   // - C1.Curve() is non projectable on at least one of the original
1628   // intersecting faces.
1629
1630   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1631   Standard_Boolean compc3d = GT.CompC3D();
1632   Standard_Boolean comppc1 = GT.CompPC1();
1633   Standard_Boolean comppc2 = GT.CompPC2();
1634   
1635   const Handle(Geom_Curve)& C3D = C1.Curve();
1636   if (compc3d && C3D.IsNull()) Standard_ProgramError::Raise
1637     ("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1638   if (comppc1 && C2.Shape1().IsNull()) Standard_ProgramError::Raise
1639     ("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1640   if (comppc2 && C2.Shape2().IsNull()) Standard_ProgramError::Raise
1641     ("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1642   TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
1643   if ( Vmin.IsNull() ) Standard_ProgramError::Raise
1644     ("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1645   if ( Vmax.IsNull() ) Standard_ProgramError::Raise
1646     ("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1647
1648   Standard_Boolean kbspl1 = Standard_False;
1649   Handle(Geom_BSplineCurve) BS = Handle(Geom_BSplineCurve)::DownCast(C3D);
1650   if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
1651   if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
1652   else        RecomputeCurveOnCone(C1,E,C2);
1653 }
1654
1655 //=======================================================================
1656 //function : RecomputeBSpline1Curve
1657 //purpose  : 
1658 //=======================================================================
1659
1660 void  TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1661 (const TopOpeBRepDS_Curve& C1,
1662  TopoDS_Shape& EE,
1663  TopOpeBRepDS_Curve& C2) const
1664 {
1665 #ifdef DEB
1666   Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1667   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1668 #endif
1669   
1670   // C1 curves have been approximated by BSplines of degree 1 :
1671   // compute new geometry on curves.
1672
1673   TopoDS_Edge& E = TopoDS::Edge(EE);
1674
1675   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1676   TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1677   Standard_Boolean compc3d =            GT.CompC3D();
1678   Standard_Boolean comppc1 =            GT.CompPC1();
1679   Standard_Boolean comppc2 =            GT.CompPC2();
1680
1681   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1682   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1683   
1684   const Handle(Geom_Curve)&   C3D = C1.Curve();
1685   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1686   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1687
1688   // Vmin,Vmax = bounding vertices of edge <E>
1689   // and their parameters parmin,parmax .
1690
1691   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1692   ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1693
1694 #ifdef DEB
1695   if (tBUTO) cout<<"Recompute1 min,max = "<<parmin<<","<<parmax<<endl;
1696   if (tBUTO) DUMPCURVES(C3D,C1);
1697 #endif
1698   
1699   Handle(Geom_Curve)   C3Dnew;
1700   Handle(Geom2d_Curve) PC1new;
1701   Handle(Geom2d_Curve) PC2new;
1702   Standard_Real tolreached3d,tolreached2d;
1703
1704   if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1705     if ( compc3d ) {
1706       C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1707       (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1708     }
1709     if ( comppc1 && (!PC1.IsNull()) ) {
1710       PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1711       (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1712     }
1713     if ( comppc2 && (!PC2.IsNull()) ) {
1714       PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1715       (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1716     }
1717   }
1718
1719   else if ( typec3d == TopOpeBRepTool_APPROX ) {
1720     if (!comppc1 || !comppc2) Standard_NotImplemented::Raise("DSBuildToolAPPROX");
1721     myCurveTool.MakeCurves(parmin,parmax,
1722                            C3D,PC1,PC2,F1,F2,
1723                            C3Dnew,PC1new,PC2new,
1724                            tolreached3d,tolreached2d);
1725   }
1726
1727   else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1728     Standard_NotImplemented::Raise("DSBuildToolINTERPOL");
1729   }
1730
1731   Standard_Real newtol,newparmin,newparmax;
1732   ::FUN_updateEDGECURVETOL
1733     (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1734      newtol,newparmin,newparmax);
1735   
1736   if (!C3Dnew.IsNull()) {
1737     C2.DefineCurve(C3Dnew,newtol,Standard_False);
1738     C2.SetRange(newparmin,newparmax);
1739   }
1740   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1741   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1742 }
1743
1744
1745 //=======================================================================
1746 //function : RecomputeCurveOnCone
1747 //purpose  : 
1748 //=======================================================================
1749
1750 void  TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1751   (const TopOpeBRepDS_Curve& C1,
1752    TopoDS_Shape&             EE,
1753    TopOpeBRepDS_Curve&       C2 ) const
1754 {
1755 #ifdef DEB
1756   Standard_Boolean tDSNC = TopOpeBRepDS_GettraceDSNC();
1757   Standard_Boolean tBUTO = TopOpeBRepDS_GettraceBUTO();
1758   Standard_Boolean tTRPE = TopOpeBRepDS_GettraceTRPE();
1759 #endif
1760   
1761   // C1 Pcurves have not been computed because C1 Curve is not projectable
1762   // on one at least of the intersecting faces giving C1 Curve.
1763   // (see TopOpeBRepTool_CurveTool::IsProjectable())
1764
1765   TopoDS_Edge& E = TopoDS::Edge(EE);
1766   
1767   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1768   TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1769   Standard_Boolean compc3d =            GT.CompC3D();
1770   Standard_Boolean comppc1 =            GT.CompPC1();
1771   Standard_Boolean comppc2 =            GT.CompPC2();
1772   
1773   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1774   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1775   
1776   const Handle(Geom_Curve)&   C3D = C1.Curve();
1777   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1778   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1779
1780   // get bounding vertices Vmin,Vmax supported by the new edge <E>
1781   // and their corresponding parameters parmin,parmax .
1782
1783   TopoDS_Vertex Vmin,Vmax; Standard_Real parmin,parmax;
1784   ::GetOrientedEdgeVertices(E,Vmin,Vmax,parmin,parmax);
1785
1786 #ifdef DEB
1787   if (tBUTO) {cout<<"Recompute2 min,max = "<<parmin<<","<<parmax<<endl;
1788               DUMPCURVES(C3D,C1);}
1789 #endif
1790
1791   if ( C3D->IsPeriodic() ) {
1792     // ellipse on cone : periodize parmin,parmax
1793     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1794     Standard_Real f,l;
1795     if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
1796     else {                                      f = parmax; l = parmin; }
1797     parmin = f; parmax = l;
1798     ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
1799 #ifdef DEB
1800     if (tBUTO||tTRPE) cout<<"Recompute2 : parmin,parmax "<<f<<","<<l<<endl;
1801     if (tBUTO||tTRPE) cout<<"                   --> parmin,parmax "<<parmin<<","<<parmax<<endl;
1802 #endif
1803   }
1804   
1805   Handle(Geom_TrimmedCurve) C3Dnew;
1806   Handle(Geom2d_Curve) PC1new;
1807   Handle(Geom2d_Curve) PC2new;
1808   Standard_Real tolreached3d = C1.Tolerance();
1809   Standard_Real tolreached2d1 = C1.Tolerance();
1810   Standard_Real tolreached2d2 = C1.Tolerance();
1811   if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
1812   if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
1813   if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
1814
1815 #ifdef DRAW
1816   if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1817 #endif
1818
1819   Standard_Real newtol,newparmin,newparmax;
1820   FUN_updateEDGECURVETOL
1821   (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1822    newtol,newparmin,newparmax);
1823
1824 //   jyl : 16-06-97
1825 //  Standard_Real fac = 0.3798123578771;
1826 //  Standard_Real tol = newtol;
1827 //  Standard_Real par3d = (1-fac)*newparmin + (fac)*newparmax;
1828 //  Standard_Real par2d = par3d - newparmin;
1829 //
1830 //  gp_Pnt P3DC3D;       C3D->D0(par3d,P3DC3D);
1831 //
1832 //  Standard_Boolean UisoLineOnSphe1 = Standard_False;
1833 //  UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1834 //  if (UisoLineOnSphe1) {
1835 //    Standard_Real isrev1 = 
1836 //      ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
1837 //    
1838 //#ifdef DEB
1839 //    if (tBUTO && isrev1) cout<<"on retourne PC1"<<endl;
1840 //#endif
1841 //
1842 //  }
1843 //
1844 //  Standard_Boolean UisoLineOnSphe2 = Standard_False;
1845 //  UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1846 //  if (UisoLineOnSphe2) {
1847 //    Standard_Real isrev2 = 
1848 //     ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
1849 //
1850 //#ifdef DEB
1851 //    if (tBUTO && isrev2) cout<<"on retourne PC2"<<endl;
1852 //#endif
1853 //  }
1854
1855   // xpu : 17-06-97
1856   // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
1857   //       est une isos de la sphere
1858   // NYI : enlever FUN_reversePC
1859   Standard_Boolean UisoLineOnSphe1 = Standard_False;
1860   UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1861   if (UisoLineOnSphe1) {
1862     ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
1863   }
1864   Standard_Boolean UisoLineOnSphe2 = Standard_False;
1865   UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1866   if (UisoLineOnSphe2) {
1867     ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1868   } // xpu : 17-06-97
1869
1870   if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1871   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1872   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1873   
1874 #ifdef DEB
1875   if (tBUTO) DUMPCURVES(C3Dnew,C2);
1876 #endif
1877 }*/ // - merge 04-07-97
1878
1879