1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 #include <TopOpeBRepDS_BuildTool.hxx>
18 
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <ElCLib.hxx>
22 #include <Extrema_ExtPC.hxx>
23 #include <Extrema_POnCurv.hxx>
24 #include <Geom2d_BezierCurve.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom2d_Conic.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Ellipse.hxx>
30 #include <Geom2d_Hyperbola.hxx>
31 #include <Geom2d_Line.hxx>
32 #include <Geom2d_OffsetCurve.hxx>
33 #include <Geom2d_Parabola.hxx>
34 #include <Geom2d_TrimmedCurve.hxx>
35 #include <Geom_BezierCurve.hxx>
36 #include <Geom_BSplineCurve.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_Conic.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Ellipse.hxx>
41 #include <Geom_Hyperbola.hxx>
42 #include <Geom_Line.hxx>
43 #include <Geom_OffsetCurve.hxx>
44 #include <Geom_Parabola.hxx>
45 #include <Geom_Plane.hxx>
46 #include <Geom_SphericalSurface.hxx>
47 #include <Geom_Surface.hxx>
48 #include <Geom_TrimmedCurve.hxx>
49 #include <GeomAdaptor_Curve.hxx>
50 #include <GeomAPI_ProjectPointOnCurve.hxx>
51 #include <GeomAPI_ProjectPointOnSurf.hxx>
52 #include <gp.hxx>
53 #include <gp_Pnt.hxx>
54 #include <gp_Pnt2d.hxx>
55 #include <gp_Vec2d.hxx>
56 #include <Precision.hxx>
57 #include <Standard_NotImplemented.hxx>
58 #include <Standard_ProgramError.hxx>
59 #include <TCollection_AsciiString.hxx>
60 #include <TopAbs.hxx>
61 #include <TopExp.hxx>
62 #include <TopExp_Explorer.hxx>
63 #include <TopLoc_Location.hxx>
64 #include <TopoDS.hxx>
65 #include <TopoDS_Edge.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Shape.hxx>
68 #include <TopoDS_Vertex.hxx>
69 #include <TopOpeBRepDS_Curve.hxx>
70 #include <TopOpeBRepDS_DataStructure.hxx>
71 #include <TopOpeBRepDS_Dumper.hxx>
72 #include <TopOpeBRepDS_HDataStructure.hxx>
73 #include <TopOpeBRepDS_Point.hxx>
74 #include <TopOpeBRepDS_Surface.hxx>
75 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
76 #include <TopOpeBRepTool_GeomTool.hxx>
77 #include <TopOpeBRepTool_OutCurveType.hxx>
78 #include <TopOpeBRepTool_ShapeTool.hxx>
79 
80 // includes especially needed by the static Project function
81 #ifdef DRAW
82 #include <TopOpeBRepDS_DRAW.hxx>
83 #include <Geom2d_Curve.hxx>
84 #endif
85 
86 Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
87 
FUN_UisoLineOnSphe(const TopoDS_Shape & F,const Handle (Geom2d_Curve)& PC)88 Standard_Boolean FUN_UisoLineOnSphe
89 (const TopoDS_Shape& F,
90  const Handle(Geom2d_Curve)& PC)
91 {
92   if (PC.IsNull()) return Standard_False;
93 
94   Handle(Geom_Surface) SSS = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
95   Handle(Geom2d_Curve) LLL = ::BASISCURVE2D(PC);
96   Handle(Standard_Type) TS = SSS->DynamicType();
97   Handle(Standard_Type) T2 = LLL->DynamicType();
98   Standard_Boolean issphere = (TS == STANDARD_TYPE(Geom_SphericalSurface));
99   Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
100   Standard_Boolean isisoU = Standard_False;
101   if (issphere && isline2d) {
102     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
103     const gp_Dir2d& d = L->Direction();
104     isisoU = (Abs(d.X()) < Precision::Parametric(Precision::Confusion()));
105   }
106   return isisoU;
107 }
108 
109 //=======================================================================
110 //function : TopOpeBRepDS_BuildTool
111 //purpose  :
112 //=======================================================================
113 
TopOpeBRepDS_BuildTool()114 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
115 myCurveTool(TopOpeBRepTool_APPROX),
116 myOverWrite(Standard_True),
117 myTranslate(Standard_True)
118 {
119 }
120 
121 //=======================================================================
122 //function : TopOpeBRepDS_BuildTool
123 //purpose  :
124 //=======================================================================
125 
TopOpeBRepDS_BuildTool(const TopOpeBRepTool_OutCurveType O)126 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
127   (const TopOpeBRepTool_OutCurveType O) :
128 myCurveTool(O),
129 myOverWrite(Standard_True),
130 myTranslate(Standard_True)
131 {
132 }
133 
134 //=======================================================================
135 //function : TopOpeBRepDS_BuildTool
136 //purpose  :
137 //=======================================================================
138 
TopOpeBRepDS_BuildTool(const TopOpeBRepTool_GeomTool & GT)139 TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
140   (const TopOpeBRepTool_GeomTool& GT) :
141 myCurveTool(GT),
142 myOverWrite(Standard_True),
143 myTranslate(Standard_True)
144 {
145 }
146 
OverWrite() const147 Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
148 {
149   return myOverWrite;
150 }
151 
OverWrite(const Standard_Boolean O)152 void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
153 {
154   myOverWrite = O;
155 }
156 
Translate() const157 Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
158 {
159   return myTranslate;
160 }
161 
Translate(const Standard_Boolean T)162 void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
163 {
164   myTranslate = T;
165 }
166 
167 //=======================================================================
168 //function : GetGeomTool
169 //purpose  :
170 //=======================================================================
171 
GetGeomTool() const172 const TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::GetGeomTool() const
173 {
174   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
175   return GT;
176 }
177 
178 //=======================================================================
179 //function : ChangeGeomTool
180 //purpose  :
181 //=======================================================================
182 
ChangeGeomTool()183 TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
184 {
185   TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
186   return GT;
187 }
188 
189 //=======================================================================
190 //function : MakeVertex
191 //purpose  :
192 //=======================================================================
193 
MakeVertex(TopoDS_Shape & V,const TopOpeBRepDS_Point & P) const194 void  TopOpeBRepDS_BuildTool::MakeVertex(TopoDS_Shape& V,
195 					 const TopOpeBRepDS_Point& P)const
196 {
197   myBuilder.MakeVertex(TopoDS::Vertex(V),P.Point(),P.Tolerance());
198 }
199 
200 //=======================================================================
201 //function : MakeEdge
202 //purpose  :
203 //=======================================================================
204 
MakeEdge(TopoDS_Shape & E,const TopOpeBRepDS_Curve & C) const205 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E,
206 				       const TopOpeBRepDS_Curve& C)const
207 {
208   // Gestion des courbes nulles pour carreaux pointus
209   // RLE 28-6-94
210 
211   if (C.Curve().IsNull()) {
212     myBuilder.MakeEdge(TopoDS::Edge(E));
213     myBuilder.Degenerated(TopoDS::Edge(E),Standard_True);
214     return;
215   }
216 
217   const Handle(Geom_Curve)& GC = C.Curve();
218   myBuilder.MakeEdge(TopoDS::Edge(E),GC,C.Tolerance());
219 
220   Standard_Boolean addorigin = Standard_False;
221   Standard_Boolean setrange  = Standard_False;
222 
223   if (addorigin) {
224     if ( GC->IsClosed() ) {
225       // in case of a closed curve, insert in E a vertex located at the origin
226       // of the curve C.
227       TopoDS_Vertex V;
228       Standard_Real first = GC->FirstParameter();
229       gp_Pnt P = GC->Value(first);
230       myBuilder.MakeVertex(V,P,C.Tolerance());
231       myBuilder.Add(E,V);
232       V.Reverse();
233       myBuilder.Add(E,V);
234 
235       // If the curve is a degree 1 bspline set the range to 1 .. NbPoles
236       Handle(Geom_BSplineCurve) BSC = Handle(Geom_BSplineCurve)::DownCast(GC);
237       if (!BSC.IsNull()) {
238 	if (BSC->Degree() == 1) {
239 	  myBuilder.Range(TopoDS::Edge(E),1,BSC->NbPoles());
240 	}
241       }
242     }
243   }
244 
245   if (setrange) {
246     Standard_Real first,last;
247     Standard_Boolean rangedef = C.Range(first,last);
248     if (rangedef) {
249       Range(E,first,last);
250     }
251   }
252 }
253 
254 //=======================================================================
255 //function : MakeEdge
256 //purpose  :
257 //=======================================================================
258 
MakeEdge(TopoDS_Shape & E,const TopOpeBRepDS_Curve & C,const TopOpeBRepDS_DataStructure & BDS) const259 void  TopOpeBRepDS_BuildTool::MakeEdge
260 (TopoDS_Shape& E,
261  const TopOpeBRepDS_Curve& C,
262  const TopOpeBRepDS_DataStructure& BDS) const
263 {
264   // Gestion des courbes nulles pour carreaux pointus
265   // RLE 28-6-94
266 
267   TopoDS_Edge& EE = TopoDS::Edge(E);
268 
269   if (C.Curve().IsNull()) {
270     myBuilder.MakeEdge(EE);
271     myBuilder.Degenerated(EE,Standard_True);
272 
273     // Creation d'une arete avec PCurve connectee a la BDS Curve
274     // JYL 22-09-94
275     Handle(TopOpeBRepDS_Interference) I = C.GetSCI1();
276     Handle(TopOpeBRepDS_SurfaceCurveInterference) SCI;
277     SCI=Handle(TopOpeBRepDS_SurfaceCurveInterference)::DownCast(I);
278     Standard_Integer iS = SCI->Support();
279     const TopOpeBRepDS_Surface& DSS = BDS.Surface(iS);
280     const Handle(Geom_Surface)& GS  = DSS.Surface();
281     const Handle(Geom2d_Curve)& PC  = SCI->PCurve();
282     myBuilder.UpdateEdge(EE,PC,GS,TopLoc_Location(),DSS.Tolerance());
283     return;
284   }
285   else {
286     const Handle(Geom_Curve)& GC = C.Curve();
287     myBuilder.MakeEdge(EE,GC,C.Tolerance());
288   }
289 
290 }
291 
292 //=======================================================================
293 //function : MakeEdge
294 //purpose  :
295 //=======================================================================
296 
MakeEdge(TopoDS_Shape & E,const Handle (Geom_Curve)& C,const Standard_Real Tol) const297 void  TopOpeBRepDS_BuildTool::MakeEdge
298 (TopoDS_Shape& E,
299  const Handle(Geom_Curve)& C,
300  const Standard_Real Tol)const
301 {
302   myBuilder.MakeEdge(TopoDS::Edge(E),C,Tol);
303 }
304 
305 
306 //=======================================================================
307 //function : MakeEdge
308 //purpose  :
309 //=======================================================================
310 
MakeEdge(TopoDS_Shape & E) const311 void  TopOpeBRepDS_BuildTool::MakeEdge(TopoDS_Shape& E) const
312 {
313   myBuilder.MakeEdge(TopoDS::Edge(E));
314 }
315 
316 
317 //=======================================================================
318 //function : MakeWire
319 //purpose  :
320 //=======================================================================
321 
MakeWire(TopoDS_Shape & W) const322 void  TopOpeBRepDS_BuildTool::MakeWire(TopoDS_Shape& W)const
323 {
324   myBuilder.MakeWire(TopoDS::Wire(W));
325 }
326 
327 
328 //=======================================================================
329 //function : MakeFace
330 //purpose  :
331 //=======================================================================
332 
MakeFace(TopoDS_Shape & F,const TopOpeBRepDS_Surface & S) const333 void  TopOpeBRepDS_BuildTool::MakeFace(TopoDS_Shape& F,
334 				       const TopOpeBRepDS_Surface& S)const
335 {
336   myBuilder.MakeFace(TopoDS::Face(F),S.Surface(),S.Tolerance());
337 }
338 
339 
340 //=======================================================================
341 //function : MakeShell
342 //purpose  :
343 //=======================================================================
344 
MakeShell(TopoDS_Shape & Sh) const345 void  TopOpeBRepDS_BuildTool::MakeShell(TopoDS_Shape& Sh)const
346 {
347   myBuilder.MakeShell(TopoDS::Shell(Sh));
348 }
349 
350 
351 //=======================================================================
352 //function : MakeSolid
353 //purpose  :
354 //=======================================================================
355 
MakeSolid(TopoDS_Shape & S) const356 void  TopOpeBRepDS_BuildTool::MakeSolid(TopoDS_Shape& S)const
357 {
358   myBuilder.MakeSolid(TopoDS::Solid(S));
359 }
360 
361 
362 //=======================================================================
363 //function : CopyEdge
364 //purpose  :
365 //=======================================================================
366 
CopyEdge(const TopoDS_Shape & Ein,TopoDS_Shape & Eou) const367 void  TopOpeBRepDS_BuildTool::CopyEdge(const TopoDS_Shape& Ein,
368 				       TopoDS_Shape& Eou)const
369 {
370 
371   // Splendide evolution de BRep_Curve3D::BRep_Curve3D(Geom_Curve,Location)
372   // apres modification de la primitive Sphere pour parametrisation de
373   // l'arete meridienne en -pi/2,+pi/2.
374   // Ein est l'arete de couture complete d'une sphere complete
375   // BRep_Tool::Range(Ein) --> -pi/2,+pi/2
376   // BRep_Tool::Range(Ein.EmptyCopied()) --> 0,2pi
377   // NYI reflexion sur la notion de Range d'une arete et de la geometrie
378   // NYI sous jacente dans le cas ou, par construction, les vertex d'une
379   // NYI arete on des valeurs de parametre HORS des bornes [first,last] de la
380   // NYI courbe 3D support de l'arete (cas de l'arete de couture d'une sphere)
381   // On redefinit desormais le range de l'arete Eou, a la place de se
382   // contenter du simplissime Eou = Ein.EmptyCopied();
383   // merci les amis : correction bug PRO2586
384 
385   Standard_Real f,l;
386   TopoDS_Edge E1 = TopoDS::Edge(Ein);
387   BRep_Tool::Range(E1,f,l);
388   Eou = Ein.EmptyCopied();
389   TopoDS_Edge E2 = TopoDS::Edge(Eou);
390   myBuilder.Range(E2,f,l);
391 }
392 
393 
394 //=======================================================================
395 //function : GetOrientedEdgeVertices
396 //purpose  :
397 //=======================================================================
398 
GetOrientedEdgeVertices(TopoDS_Edge & E,TopoDS_Vertex & Vmin,TopoDS_Vertex & Vmax,Standard_Real & Parmin,Standard_Real & Parmax) const399 void TopOpeBRepDS_BuildTool::GetOrientedEdgeVertices
400 (TopoDS_Edge& E,
401  TopoDS_Vertex& Vmin, TopoDS_Vertex& Vmax,
402  Standard_Real& Parmin, Standard_Real& Parmax) const
403 {
404   if ( E.Orientation() == TopAbs_FORWARD)
405     TopExp::Vertices(E,Vmin,Vmax);
406   else
407     TopExp::Vertices(E,Vmax,Vmin);
408   if ( !Vmin.IsNull() && !Vmax.IsNull()) {
409     Parmin = BRep_Tool::Parameter(Vmin,E);
410     Parmax = BRep_Tool::Parameter(Vmax,E);
411   }
412 }
413 
414 //=======================================================================
415 //function : UpdateEdgeCurveTol
416 //purpose  :
417 //=======================================================================
418 
UpdateEdgeCurveTol(const TopoDS_Face &,const TopoDS_Face &,TopoDS_Edge & E,const Handle (Geom_Curve)& C3Dnew,const Standard_Real,const Standard_Real,const Standard_Real,Standard_Real & newtol,Standard_Real & newparmin,Standard_Real & newparmax) const419 void TopOpeBRepDS_BuildTool::UpdateEdgeCurveTol
420 //(const TopoDS_Face& F1,const TopoDS_Face& F2,
421 (const TopoDS_Face& ,const TopoDS_Face& ,
422  TopoDS_Edge& E, const Handle(Geom_Curve)& C3Dnew,
423 // const Standard_Real tol3d,
424  const Standard_Real ,
425 // const Standard_Real tol2d1,
426  const Standard_Real ,
427 // const Standard_Real tol2d2,
428  const Standard_Real ,
429  Standard_Real& newtol,
430  Standard_Real& newparmin,
431  Standard_Real& newparmax) const
432 
433 {
434   if (C3Dnew.IsNull()) return;
435   BRep_Builder BB;
436 
437   // newtol = max des tolerances atteintes en 3d
438 // JMB le 06 Juillet 1999
439 // les valeurs tol3d et tol2d1,tol2d2 proviennent des approx. Dans la version 2.0 de CasCade,
440 // elles n'etaient pas calculees et on renvoyait systematiquement les valeurs initiales (a savoir)
441 // 1.E-7. Dans la version 2.1 de CasCade, ces valeurs sont desormais calculees selon un calcul
442 // d'erreur dans les Approx. Malheureusement, il apparait que ce calcul d'erreur renvoit dans la
443 // plupart des cas de tres grosses valeurs (parfois de l'ordre de 1.E-1). Ce qui amenait la topologie
444 // a coder des tolerances enormes dans les pieces resultats rendant celles-ci inexpoitables.
445 // De plus on essayait de rafiner la tolerance en appelant les UResolution sur les surfaces support.
446 // sur des surfaces tres particulieres, ce UREsolution n'a plus aucun sens et peut amener a des valeurs
447 // abberantes.
448 // On decide donc de laisser la tolerance de l'edge telle qu'elle est afin d'avoir un comportement similaire
449 // a 2.0. Jusqu'a present on a constate que des problemes avec la methode de calcul d'erreur des approx.
450 
451 
452   newtol = 1.E-7;
453 //  Standard_Real r1,r2;
454 //  r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tol2d1);
455 //  r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tol2d2);
456 //  newtol=tol3d;
457 //  if (r1>newtol) newtol=r1;
458 //  if (r2>newtol) newtol=r2;
459 
460 //  newtol *= 1.5;
461 
462   TopoDS_Vertex Vmin, Vmax;
463   Standard_Real parmin = 0.0, parmax = 0.0;
464   GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
465 
466   Standard_Real tolmin=BRep_Tool::Tolerance(Vmin);
467   if(newtol>tolmin) tolmin=newtol;
468   Standard_Real tolmax=BRep_Tool::Tolerance(Vmax);
469   if(newtol>tolmax) tolmax=newtol;
470 
471 
472 //  newparmin=C3Dnew->FirstParameter(); // -merge 04-07-97
473 //  newparmax=C3Dnew->LastParameter(); // -merge 04-07-97
474 
475  // +merge 04-07-97
476   Handle(Geom_TrimmedCurve) GTC = Handle(Geom_TrimmedCurve)::DownCast(C3Dnew);
477   if(GTC.IsNull()) {
478     Handle(Geom_BSplineCurve) GBSC = Handle(Geom_BSplineCurve)::DownCast(C3Dnew);
479     if(GBSC.IsNull()) {
480       newparmin = parmin;
481       newparmax = parmax;
482     } else {
483       newparmin=C3Dnew->FirstParameter();
484       newparmax=C3Dnew->LastParameter();
485     }
486   } else {
487     newparmin=C3Dnew->FirstParameter();
488     newparmax=C3Dnew->LastParameter();
489   } // +merge 04-07-97
490 
491   if (Vmin.Orientation() == TopAbs_FORWARD) {
492     BB.UpdateVertex(Vmin,newparmin,E,tolmin);
493     BB.UpdateVertex(Vmax,newparmax,E,tolmax);
494   }
495   else {
496     BB.UpdateVertex(Vmin,newparmax,E,tolmin);
497     BB.UpdateVertex(Vmax,newparmin,E,tolmax);
498   }
499 
500 //  DSBT.Curve3D(E,C3Dnew,newtol);  // -merge 04-07-97
501   Curve3D(E,C3Dnew,newtol);
502 
503   // projection des vertex INTERNAL de E pour parametrage
504   // sur la nouvelle courbe C3Dnew de l'arete E
505   TopExp_Explorer exi(E,TopAbs_VERTEX);
506   for (;exi.More(); exi.Next() ) {
507     const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
508     if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
509     gp_Pnt P = BRep_Tool::Pnt(vi);
510     Standard_Real tolvi=TopOpeBRepTool_ShapeTool::Tolerance(vi);
511     GeomAPI_ProjectPointOnCurve dm(P,C3Dnew,newparmin,newparmax);
512     Standard_Boolean dmdone = dm.Extrema().IsDone();
513     if ( dmdone ) {
514       if ( dm.NbPoints() ) {
515 	Standard_Real newpar = dm.LowerDistanceParameter();
516 	BB.UpdateVertex(vi,newpar,E,tolvi);
517       }
518     }
519   } // INTERNAL vertex
520 }
521 
522 //=======================================================================
523 //function : ApproxCurves
524 //purpose  :
525 //=======================================================================
526 
ApproxCurves(const TopOpeBRepDS_Curve & C,TopoDS_Edge & E,Standard_Integer & inewC,const Handle (TopOpeBRepDS_HDataStructure)& HDS) const527 void  TopOpeBRepDS_BuildTool::ApproxCurves
528 (const TopOpeBRepDS_Curve& C,
529  TopoDS_Edge& E,
530  Standard_Integer& inewC,
531  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
532 {
533   TopOpeBRepDS_Curve newC1;
534   inewC = HDS->MakeCurve(C,newC1);
535   TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
536 
537   // C1 curves have been approximated by BSplines of degree 1 :
538   // compute new geometry on curves.
539 
540   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
541   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
542 
543   const Handle(Geom_Curve)& C3D = C.Curve();
544   const Handle(Geom2d_Curve)& PC1 = C.Curve1();
545   const Handle(Geom2d_Curve)& PC2 = C.Curve2();
546 
547   // Vmin,Vmax = bounding vertices of edge <E>
548   // and their parameters parmin,parmax .
549 
550   TopoDS_Vertex Vmin, Vmax;
551   Standard_Real parmin = 0.0, parmax = 0.0;
552   GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
553 
554   Handle(Geom_Curve)   C3Dnew;
555   Handle(Geom2d_Curve) PC1new;
556   Handle(Geom2d_Curve) PC2new;
557   Standard_Real tolreached3d = 0.0, tolreached2d = 0.0;
558   Standard_Boolean approxMade = myCurveTool.MakeCurves(parmin,parmax,
559 			 C3D,PC1,PC2,F1,F2,
560 			 C3Dnew,PC1new,PC2new,
561 			 tolreached3d,tolreached2d);
562 
563   Standard_Real newtol = 0.0, newparmin = 0.0, newparmax = 0.0;
564   // MSV Nov 12, 2001: if approx failed than leave old curves of degree 1
565   if (!approxMade) {
566     newtol = BRep_Tool::Tolerance(E);
567     newparmin = parmin;
568     newparmax = parmax;
569     C3Dnew = C3D;
570     PC1new = PC1;
571     PC2new = PC2;
572   }
573   else {
574     UpdateEdgeCurveTol
575       (F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
576        newtol,newparmin,newparmax);
577   }
578 
579   if (!C3Dnew.IsNull()) {
580     newC.DefineCurve(C3Dnew,newtol,Standard_False);
581     newC.SetRange(newparmin,newparmax);
582   }
583 
584   if (!PC1new.IsNull()) newC.Curve1(PC1new);
585   if (!PC2new.IsNull()) newC.Curve2(PC2new);
586 }
587 
588 
589 //=======================================================================
590 //function : ComputePCurves
591 //purpose  :
592 //=======================================================================
FUN_getUV(const Handle (Geom_Surface)surf,const Handle (Geom_Curve)C3D,const Standard_Real par3d,Standard_Real & u0,Standard_Real & v0)593 Standard_Boolean FUN_getUV
594 (const Handle(Geom_Surface) surf,
595  const Handle(Geom_Curve) C3D,
596  const Standard_Real par3d,
597  Standard_Real& u0,
598  Standard_Real& v0)
599 {
600   gp_Pnt P3d; C3D->D0(par3d,P3d);
601   GeomAPI_ProjectPointOnSurf pons(P3d,surf);
602   if (pons.NbPoints() < 1) return Standard_False;
603   pons.LowerDistanceParameters(u0,v0);
604   return Standard_True;
605 }
606 
FUN_reversePC(Handle (Geom2d_Curve)PCnew,const TopoDS_Face & F,const gp_Pnt & P3DC3D,const Standard_Real par2d,const Standard_Real tol)607 Standard_Boolean FUN_reversePC
608 (Handle(Geom2d_Curve) PCnew,
609  const TopoDS_Face& F,
610  const gp_Pnt& P3DC3D,
611  const Standard_Real par2d,
612  const Standard_Real tol)
613 {
614   gp_Pnt2d P2D; PCnew->D0(par2d,P2D);
615   BRepAdaptor_Surface BAS(F,Standard_False);
616   gp_Pnt P3D = BAS.Value(P2D.X(),P2D.Y());
617   Standard_Boolean PCreversed = Standard_False;
618   Standard_Boolean sam = P3D.IsEqual(P3DC3D,tol);
619   PCreversed = !sam;
620 
621   if ( PCreversed ) {
622     Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
623     if (!PC.IsNull()) {
624       Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
625       gp_Dir2d d = L->Direction();
626       d.Reverse();
627       L->SetDirection(d);
628     }
629   }
630   return PCreversed;
631 }
FUN_makeUisoLineOnSphe(const TopoDS_Face & F,const Handle (Geom_Curve)C3D,Handle (Geom2d_Curve)PCnew,const Standard_Real tol3d)632 Standard_Boolean FUN_makeUisoLineOnSphe
633 (const TopoDS_Face& F, // with geometry the spherical surface
634  const Handle(Geom_Curve) C3D,
635  Handle(Geom2d_Curve) PCnew,
636  const Standard_Real tol3d)
637 {
638   // p3df,p3dl : C3d first and last parameters
639   Standard_Real p3df = C3D->FirstParameter();
640   Standard_Real p3dl = C3D->LastParameter();
641 
642   // u0,v0 : C3d(par3d) UV parameters
643   Standard_Real deltainf = 0.243234, deltasup = 0.543345;
644   Standard_Real par3dinf = (1-deltainf)*p3df + deltainf*p3dl;
645   Standard_Real par3dsup = (1-deltasup)*p3df + deltasup*p3dl;
646   Standard_Real uinf,vinf,usup,vsup;
647   Handle(Geom_Surface) surf = BRep_Tool::Surface(F);
648   if (!FUN_getUV(surf,C3D,par3dinf,uinf,vinf)) return Standard_False;
649   if (!FUN_getUV(surf,C3D,par3dsup,usup,vsup)) return Standard_False;
650   Standard_Real tol = Precision::Parametric(tol3d);
651   if (Abs(uinf-usup) > tol) return Standard_False;
652 
653   Standard_Boolean isvgrowing = (vsup - vinf > -tol);
654   gp_Dir2d vdir;
655   if (isvgrowing) vdir = gp_Dir2d(0,1);
656   else            vdir = gp_Dir2d(0,-1);
657 
658   gp_Pnt2d origin(uinf,vinf);
659   origin.Translate(gp_Vec2d(vdir).Scaled(p3df-par3dinf));
660   Handle(Geom2d_Curve) PC = ::BASISCURVE2D(PCnew);
661   if (!PC.IsNull()) {
662     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(PC);
663     L->SetLin2d(gp_Lin2d(origin,vdir));
664   } // (!PC.IsNull())
665 
666   return Standard_True;
667 }
668 
ComputePCurves(const TopOpeBRepDS_Curve & C,TopoDS_Edge & E,TopOpeBRepDS_Curve & newC,const Standard_Boolean comppc1,const Standard_Boolean comppc2,const Standard_Boolean compc3d) const669 void TopOpeBRepDS_BuildTool::ComputePCurves
670 (const TopOpeBRepDS_Curve& C,
671  TopoDS_Edge& E,
672  TopOpeBRepDS_Curve& newC,
673  const Standard_Boolean comppc1,
674  const Standard_Boolean comppc2,
675  const Standard_Boolean compc3d) const
676 {
677   const TopoDS_Face& F1 = TopoDS::Face(newC.Shape1());
678   const TopoDS_Face& F2 = TopoDS::Face(newC.Shape2());
679 
680   const Handle(Geom_Curve)& C3D = C.Curve();
681 
682   // get bounding vertices Vmin,Vmax supported by the new edge <E>
683   // and their corresponding parameters parmin,parmax .
684   TopoDS_Vertex Vmin, Vmax;
685   Standard_Real parmin = 0.0, parmax = 0.0;
686   GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
687 
688   Handle(Geom2d_Curve) PC1new, PC2new;
689   if(C3D.IsNull())
690   {
691     Standard_Real tolreached2d1 = Precision::Confusion(), tolreached2d2 = Precision::Confusion(), tol=Precision::Confusion();
692     if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3D,tolreached2d1);
693     if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3D,tolreached2d2);
694 
695     Standard_Real r1 = TopOpeBRepTool_ShapeTool::Resolution3d(F1,tolreached2d1);
696     Standard_Real r2 = TopOpeBRepTool_ShapeTool::Resolution3d(F2,tolreached2d2);
697     tol = Max(tol,r1);
698     tol = Max(tol,r2);
699     newC.Tolerance(tol);
700 
701     if (!PC1new.IsNull()) newC.Curve1(PC1new);
702     if (!PC2new.IsNull()) newC.Curve2(PC2new);
703 
704     return;
705   }
706 
707   Handle(Geom_Curve) C3Dnew = C3D;
708 
709   if ( C3D->IsPeriodic() ) {
710     // ellipse on cone : periodize parmin,parmax
711     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
712     Standard_Real f,l;
713     if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
714     else {                                      f = parmax; l = parmin; }
715     parmin = f; parmax = l;
716     ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
717     if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
718 
719   }
720 
721   Standard_Real tolreached3d = C.Tolerance();
722   Standard_Real tolreached2d1 = C.Tolerance();
723   Standard_Real tolreached2d2 = C.Tolerance();
724 
725   if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
726   if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
727 
728   Standard_Real newtol,newparmin,newparmax;
729   UpdateEdgeCurveTol(F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
730 		     newtol,newparmin,newparmax);
731 
732     // xpu : suite merge : 07-07-97
733     // xpu : 17-06-97
734     // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
735     //       est une isos de la sphere
736     // NYI : enlever FUN_reversePC
737     Standard_Boolean UisoLineOnSphe1 = Standard_False;
738     UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
739     if (UisoLineOnSphe1) ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
740 
741     Standard_Boolean UisoLineOnSphe2 = Standard_False;
742     UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
743     if (UisoLineOnSphe2) ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
744     // xpu : 17-06-97
745     // xpu : suite merge : 07-07-97
746 
747   if (!C3Dnew.IsNull()) {
748     newC.Curve(C3Dnew,newtol);
749     newC.SetRange(newparmin, newparmax);
750   }
751   if (!PC1new.IsNull()) newC.Curve1(PC1new);
752   if (!PC2new.IsNull()) newC.Curve2(PC2new);
753 }
754 
755 //=======================================================================
756 //function : PutPCurves
757 //purpose  :
758 //=======================================================================
759 
PutPCurves(const TopOpeBRepDS_Curve & newC,TopoDS_Edge & E,const Standard_Boolean comppc1,const Standard_Boolean comppc2) const760 void  TopOpeBRepDS_BuildTool::PutPCurves
761 (const TopOpeBRepDS_Curve& newC,
762  TopoDS_Edge& E,
763  const Standard_Boolean comppc1,
764  const Standard_Boolean comppc2) const
765 {
766 
767   TopoDS_Face& F1 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape1())));
768   Handle(Geom2d_Curve) PC1 = newC.Curve1();
769   if (!PC1.IsNull() && comppc1) {
770     PCurve(F1,E,PC1);
771   }
772 
773   TopoDS_Face& F2 = *((TopoDS_Face*)(void*)&(TopoDS::Face(newC.Shape2())));
774   Handle(Geom2d_Curve) PC2 = newC.Curve2();
775   if (!PC2.IsNull() && comppc2) {
776     PCurve(F2,E,PC2);
777   }
778 
779 }
780 
781 //=======================================================================
782 //function : RecomputeCurves
783 //purpose  :
784 //=======================================================================
785 
RecomputeCurves(const TopOpeBRepDS_Curve & C,const TopoDS_Edge &,TopoDS_Edge & E,Standard_Integer & inewC,const Handle (TopOpeBRepDS_HDataStructure)& HDS) const786 void  TopOpeBRepDS_BuildTool::RecomputeCurves
787 (const TopOpeBRepDS_Curve& C,
788 // const TopoDS_Edge& oldE,
789  const TopoDS_Edge& ,
790  TopoDS_Edge& E,
791  Standard_Integer& inewC,
792  const Handle(TopOpeBRepDS_HDataStructure)& HDS) const
793 {
794   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
795   const Standard_Boolean compc3d = GT.CompC3D();
796   const Standard_Boolean comppc1 = GT.CompPC1();
797   const Standard_Boolean comppc2 = GT.CompPC2();
798   const Standard_Boolean comppc = comppc1 || comppc2;
799   const Standard_Boolean iswalk = C.IsWalk();
800   const Standard_Boolean approx = Approximation();
801 
802   const Handle(Geom_Curve)& C3D = C.Curve();
803   if (comppc1 && C.Shape1().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
804   if (comppc2 && C.Shape2().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
805   TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(E,Vmin,Vmax);
806   if ( Vmin.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
807   if ( Vmax.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
808 
809   if (iswalk && approx) {
810     if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
811     ApproxCurves(C, E, inewC, HDS);
812     TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
813     PutPCurves(newC, E, comppc1, comppc2);
814   }
815 //  else if (iswalk && interpol) {
816 //    InterpolCurves(C, E, inewC, comppc1, comppc2, HDS);
817 //    TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
818 //    PutPCurves(newC, E, comppc1, comppc2);
819 //  }
820 
821   else {
822     if (comppc) {
823       TopOpeBRepDS_Curve newC1;
824       inewC = HDS->MakeCurve(C,newC1);
825       TopOpeBRepDS_Curve& newC = HDS->ChangeCurve(inewC);
826       if(iswalk && !approx) {
827 	if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
828 	newC.Curve1(C.Curve1());
829 	newC.Curve2(C.Curve2());
830       }
831       else
832 	ComputePCurves(C, E, newC, comppc1, comppc2, compc3d);
833       PutPCurves(newC, E, comppc1, comppc2);
834     }
835   }
836 }
837 
838 //=======================================================================
839 //function : CopyFace
840 //purpose  :
841 //=======================================================================
842 
CopyFace(const TopoDS_Shape & Fin,TopoDS_Shape & Fou) const843 void  TopOpeBRepDS_BuildTool::CopyFace(const TopoDS_Shape& Fin,
844 				       TopoDS_Shape& Fou)const
845 {
846   Fou = Fin.EmptyCopied();
847 }
848 
849 
850 //=======================================================================
851 //function : AddEdgeVertex
852 //purpose  :
853 //=======================================================================
854 
AddEdgeVertex(const TopoDS_Shape & Ein,TopoDS_Shape & Eou,const TopoDS_Shape & V) const855 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(const TopoDS_Shape& Ein,
856 					    TopoDS_Shape& Eou,
857 					    const TopoDS_Shape& V)const
858 {
859   myBuilder.Add(Eou,V);
860   TopoDS_Edge e1 = TopoDS::Edge(Ein);
861   TopoDS_Edge e2 = TopoDS::Edge(Eou);
862   TopoDS_Vertex v1 = TopoDS::Vertex(V);
863   myBuilder.Transfert(e1,e2,v1,v1);
864 }
865 
866 
867 //=======================================================================
868 //function : AddEdgeVertex
869 //purpose  :
870 //=======================================================================
871 
AddEdgeVertex(TopoDS_Shape & E,const TopoDS_Shape & V) const872 void  TopOpeBRepDS_BuildTool::AddEdgeVertex(TopoDS_Shape& E,
873 					    const TopoDS_Shape& V)const
874 {
875   myBuilder.Add(E,V);
876 }
877 
878 
879 //=======================================================================
880 //function : AddWireEdge
881 //purpose  :
882 //=======================================================================
883 
AddWireEdge(TopoDS_Shape & W,const TopoDS_Shape & E) const884 void  TopOpeBRepDS_BuildTool::AddWireEdge(TopoDS_Shape& W,
885 					  const TopoDS_Shape& E)const
886 {
887   myBuilder.Add(W,E);
888 }
889 
890 
891 //=======================================================================
892 //function : AddFaceWire
893 //purpose  :
894 //=======================================================================
895 
AddFaceWire(TopoDS_Shape & F,const TopoDS_Shape & W) const896 void  TopOpeBRepDS_BuildTool::AddFaceWire(TopoDS_Shape& F,
897 					  const TopoDS_Shape& W)const
898 {
899   myBuilder.Add(F,W);
900 }
901 
902 
903 //=======================================================================
904 //function : AddShellFace
905 //purpose  :
906 //=======================================================================
907 
AddShellFace(TopoDS_Shape & Sh,const TopoDS_Shape & F) const908 void  TopOpeBRepDS_BuildTool::AddShellFace(TopoDS_Shape& Sh,
909 					   const TopoDS_Shape& F)const
910 {
911   myBuilder.Add(Sh,F);
912 }
913 
914 
915 //=======================================================================
916 //function : AddSolidShell
917 //purpose  :
918 //=======================================================================
919 
AddSolidShell(TopoDS_Shape & S,const TopoDS_Shape & Sh) const920 void  TopOpeBRepDS_BuildTool::AddSolidShell(TopoDS_Shape& S,
921 					    const TopoDS_Shape& Sh)const
922 {
923   myBuilder.Add(S,Sh);
924 }
925 
926 
927 //=======================================================================
928 //function : Parameter
929 //purpose  :
930 //=======================================================================
931 
Parameter(const TopoDS_Shape & E,const TopoDS_Shape & V,const Standard_Real P) const932 void  TopOpeBRepDS_BuildTool::Parameter(const TopoDS_Shape& E,
933 					const TopoDS_Shape& V,
934 					const Standard_Real P)const
935 {
936   const TopoDS_Edge&   e = TopoDS::Edge(E);
937   const TopoDS_Vertex& v = TopoDS::Vertex(V);
938   Standard_Real p = P;
939 
940   // 13/07/95 :
941   TopLoc_Location loc; Standard_Real f,l;
942   Handle(Geom_Curve) C = BRep_Tool::Curve(e,loc,f,l);
943   if ( !C.IsNull() && C->IsPeriodic()) {
944     Standard_Real per = C->Period();
945 
946     TopAbs_Orientation oV=TopAbs_FORWARD;
947 
948     TopExp_Explorer exV(e,TopAbs_VERTEX);
949     for (; exV.More(); exV.Next()) {
950       const TopoDS_Vertex& vofe = TopoDS::Vertex(exV.Current());
951       if ( vofe.IsSame(v) ) {
952 	oV = vofe.Orientation();
953 	break;
954       }
955     }
956     if ( exV.More() ) {
957       if ( oV == TopAbs_REVERSED ) {
958 	if ( p < f ) {
959 	  Standard_Real pp = ElCLib::InPeriod(p,f,f+per);
960 	  p = pp;
961 	}
962       }
963     }
964   }
965 
966   myBuilder.UpdateVertex(v,p,e,
967 			 0);   // NYI : Tol on new vertex ??
968 }
969 
970 //=======================================================================
971 //function : Range
972 //purpose  :
973 //=======================================================================
974 
Range(const TopoDS_Shape & E,const Standard_Real first,const Standard_Real last) const975 void  TopOpeBRepDS_BuildTool::Range(const TopoDS_Shape& E,
976 				    const Standard_Real first,
977 				    const Standard_Real last)const
978 {
979   myBuilder.Range(TopoDS::Edge(E),first,last);
980 }
981 
982 
983 //=======================================================================
984 //function : UpdateEdge
985 //purpose  :
986 //=======================================================================
987 
UpdateEdge(const TopoDS_Shape & Ein,TopoDS_Shape & Eou) const988 void  TopOpeBRepDS_BuildTool::UpdateEdge(const TopoDS_Shape& Ein,
989 					 TopoDS_Shape& Eou)const
990 {
991   TopLoc_Location loc;
992   Standard_Real f1,l1;
993   Standard_Real f2,l2;
994   Handle(Geom_Curve) Cin = BRep_Tool::Curve(TopoDS::Edge(Ein),loc,f1,l1);
995   Handle(Geom_Curve) Cou = BRep_Tool::Curve(TopoDS::Edge(Eou),loc,f2,l2);
996   if (Cin.IsNull() || Cou.IsNull()) return;
997 
998   if ( Cou->IsPeriodic() ) {
999     Standard_Real f2n = f2, l2n = l2;
1000     if ( l2n <= f2n ) {
1001       ElCLib::AdjustPeriodic(f1,l1,Precision::PConfusion(),f2n,l2n);
1002       Range(Eou,f2n,l2n);
1003     }
1004   }
1005 }
1006 
1007 //=======================================================================
1008 //function : Project
1009 //purpose  : project a vertex on a curve
1010 //=======================================================================
1011 
Project(const Handle (Geom_Curve)& C,const TopoDS_Vertex & V,Standard_Real & p)1012 static Standard_Boolean Project(const Handle(Geom_Curve)& C,
1013 				const TopoDS_Vertex& V,
1014 				Standard_Real& p)
1015 {
1016   gp_Pnt P = BRep_Tool::Pnt(V);
1017   Standard_Real tol = BRep_Tool::Tolerance(V);
1018   GeomAdaptor_Curve GAC(C);
1019   Extrema_ExtPC extrema(P,GAC);
1020   if (extrema.IsDone()) {
1021     Standard_Integer i,n = extrema.NbExt();
1022     for (i = 1; i <= n; i++) {
1023       if (extrema.IsMin(i)) {
1024 	Extrema_POnCurv EPOC = extrema.Point(i);
1025 	if (P.Distance(EPOC.Value()) <= tol) {
1026 	  p = EPOC.Parameter();
1027 	  return Standard_True;
1028 	}
1029       }
1030     }
1031   }
1032   return Standard_False;
1033 }
1034 
1035 
1036 //=======================================================================
1037 //function : Parameter
1038 //purpose  :
1039 //=======================================================================
1040 
Parameter(const TopOpeBRepDS_Curve & C,TopoDS_Shape & E,TopoDS_Shape & V) const1041 void  TopOpeBRepDS_BuildTool::Parameter(const TopOpeBRepDS_Curve& C,
1042 					TopoDS_Shape& E,
1043 					TopoDS_Shape& V)const
1044 {
1045   Standard_Real newparam;
1046   Project(C.Curve(),TopoDS::Vertex(V),newparam);
1047   Parameter(E,V,newparam);
1048 }
1049 
1050 
1051 //=======================================================================
1052 //function : Curve3D
1053 //purpose  :
1054 //=======================================================================
1055 
Curve3D(TopoDS_Shape & E,const Handle (Geom_Curve)& C,const Standard_Real Tol) const1056 void  TopOpeBRepDS_BuildTool::Curve3D
1057 (TopoDS_Shape& E,
1058  const Handle(Geom_Curve)& C,
1059  const Standard_Real Tol)const
1060 {
1061   myBuilder.UpdateEdge(TopoDS::Edge(E),
1062 		       C,
1063 		       Tol);
1064 }
1065 
1066 
1067 //=======================================================================
1068 //function : TranslateOnPeriodic
1069 //purpose  :
1070 //=======================================================================
1071 
TranslateOnPeriodic(TopoDS_Shape & F,TopoDS_Shape & E,Handle (Geom2d_Curve)& PC) const1072 void TopOpeBRepDS_BuildTool::TranslateOnPeriodic
1073   (TopoDS_Shape& F,
1074    TopoDS_Shape& E,
1075    Handle(Geom2d_Curve)& PC) const
1076 {
1077   // get range C3Df,C3Dl of 3d curve C3D of E
1078   TopLoc_Location L;
1079   Standard_Real C3Df,C3Dl;
1080 //  Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),L,C3Df,C3Dl);
1081   Handle(Geom_Curve) C3D = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl); // 13-07-97: xpu
1082 
1083   Standard_Real first = C3Df, last = C3Dl;
1084   if (C3D->IsPeriodic()) {
1085     if ( last < first ) last += Abs(first - last);
1086   }
1087 
1088   // jyl-xpu : 13-06-97 :
1089   // if <PC> is U isoline on sphere, a special parametrization
1090   // is to provide, we compute <PC> (which is a line) bounds
1091   // with C3D bounds.
1092   Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1093   Standard_Boolean newv = Standard_True;
1094 
1095   Standard_Real du,dv;
1096 
1097   gp_Pnt2d ptest;
1098   Standard_Real t =(first+last)*.5;
1099   PC->D0(t,ptest);
1100   Standard_Real u1 = ptest.X(), u2 = u1;
1101   Standard_Real v1 = ptest.Y(), v2 = v1;
1102 
1103   if (newv) {
1104     if (UisoLineOnSphe) {
1105       Handle(Geom_Curve) c3d = BRep_Tool::Curve(TopoDS::Edge(E),C3Df,C3Dl);
1106       GeomAdaptor_Curve GC(c3d); gp_Pnt p3dtest = GC.Value(t);
1107       Handle(Geom_Surface) surf = BRep_Tool::Surface(TopoDS::Face(F));
1108       GeomAPI_ProjectPointOnSurf pons(p3dtest,surf);
1109       if (!(pons.NbPoints() < 1))
1110 	pons.LowerDistanceParameters(u2,v2);
1111     } else TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1112   }
1113   if (!newv) TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(F,u2,v2);
1114   du = u2 - u1, dv = v2 - v1;
1115 
1116   if ( du != 0. || dv != 0.) {
1117     // translate curve PC of du,dv
1118     Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(PC->Copy());
1119     PCT->Translate(gp_Vec2d(du,dv));
1120     PC = PCT;
1121   }
1122 }
1123 
1124 
1125 // RLE - IAB 16 june 94
1126 // should be provided by the BRep_Builder
1127 
TopOpeBRepDS_SetThePCurve(const BRep_Builder & B,TopoDS_Edge & E,const TopoDS_Face & F,const TopAbs_Orientation O,const Handle (Geom2d_Curve)& C)1128 Standard_EXPORT void TopOpeBRepDS_SetThePCurve(const BRep_Builder& B,
1129 					       TopoDS_Edge& E,
1130 					       const TopoDS_Face& F,
1131 					       const TopAbs_Orientation O,
1132 					       const Handle(Geom2d_Curve)& C)
1133 {
1134   // check if there is already a pcurve on non planar faces
1135   Standard_Real f,l;
1136   Handle(Geom2d_Curve) OC;
1137   TopLoc_Location SL;
1138   Handle(Geom_Plane) GP = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F,SL));
1139   if (GP.IsNull())
1140     OC = BRep_Tool::CurveOnSurface(E,F,f,l);
1141 
1142   if (OC.IsNull())
1143     B.UpdateEdge(E,C,F,Precision::Confusion());
1144   else {
1145     Standard_Boolean degen = BRep_Tool::Degenerated(E);
1146     if(!degen){
1147       if (O == TopAbs_REVERSED)
1148 	B.UpdateEdge(E,OC,C,F,Precision::Confusion());
1149       else
1150 	B.UpdateEdge(E,C,OC,F,Precision::Confusion());
1151     }
1152   }
1153 }
1154 
1155 //=======================================================================
1156 //function : PCurve
1157 //purpose  :
1158 //=======================================================================
1159 
PCurve(TopoDS_Shape & F,TopoDS_Shape & E,const Handle (Geom2d_Curve)& PC) const1160 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1161 				     TopoDS_Shape& E,
1162 				     const Handle(Geom2d_Curve)& PC)const
1163 {
1164   if ( ! PC.IsNull() ) {
1165     TopoDS_Face FF = TopoDS::Face(F);
1166     TopoDS_Edge EE = TopoDS::Edge(E);
1167     Handle(Geom2d_Curve) PCT = PC;
1168 
1169     // pour iab, ajout de Translate
1170     Standard_Boolean tran = myTranslate;
1171 
1172     // xpu : 13-06-97 :
1173     // recompute twice the pcurve boundaries if OverWrite
1174     // if the pcurve <PC> is U isoline on sphere -> to avoid.
1175     Standard_Boolean UisoLineOnSphe = FUN_UisoLineOnSphe(F,PC);
1176     Standard_Boolean overwrite = UisoLineOnSphe? Standard_False:myOverWrite;
1177     // xpu : 13-06-97
1178 
1179     if (tran)
1180       TranslateOnPeriodic(F,E,PCT);
1181 
1182     if (overwrite)
1183       myBuilder.UpdateEdge(EE,PCT,FF,0);
1184     else
1185       TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1186 
1187     // parametrage sur la nouvelle courbe 2d
1188     TopExp_Explorer exi(E,TopAbs_VERTEX);
1189     for (;exi.More(); exi.Next() ) {
1190       const TopoDS_Vertex& vi = TopoDS::Vertex(exi.Current());
1191       if ( vi.Orientation() != TopAbs_INTERNAL ) continue;
1192       Standard_Real tolvi = TopOpeBRepTool_ShapeTool::Tolerance(vi);
1193       // NYI tester l'existence d'au moins
1194       // NYI un parametrage de vi sur EE (en 3d ou en 2d)
1195       // NYI --> a faire dans BRep_Tool
1196       Standard_Real newpar = BRep_Tool::Parameter(vi,EE);
1197       myBuilder.UpdateVertex(vi,newpar,EE,FF,tolvi);
1198     } // INTERNAL vertex
1199   }
1200 }
1201 
1202 //=======================================================================
1203 //function : PCurve
1204 //purpose  :
1205 //=======================================================================
1206 
PCurve(TopoDS_Shape & F,TopoDS_Shape & E,const TopOpeBRepDS_Curve & CDS,const Handle (Geom2d_Curve)& PC) const1207 void  TopOpeBRepDS_BuildTool::PCurve(TopoDS_Shape& F,
1208 				     TopoDS_Shape& E,
1209 				     const TopOpeBRepDS_Curve& CDS,
1210 				     const Handle(Geom2d_Curve)& PC)const
1211 {
1212   if ( ! PC.IsNull() ) {
1213     TopoDS_Face FF = TopoDS::Face(F);
1214     TopoDS_Edge EE = TopoDS::Edge(E);
1215 
1216     Handle(Geom2d_Curve) PCT = PC;
1217     Standard_Real    CDSmin,CDSmax;
1218     Standard_Boolean rangedef = CDS.Range(CDSmin,CDSmax);
1219 
1220 
1221     TopLoc_Location L; Standard_Real Cf,Cl;
1222     Handle(Geom_Curve) C = BRep_Tool::Curve(EE,L,Cf,Cl);
1223 
1224     if (!C.IsNull()){
1225       Standard_Boolean deca = (Abs(Cf - CDSmin) > Precision::PConfusion());
1226       Handle(Geom2d_Line) line2d = Handle(Geom2d_Line)::DownCast(PCT);
1227       Standard_Boolean isline2d = !line2d.IsNull();
1228       Standard_Boolean tran=(rangedef && deca && C->IsPeriodic() && isline2d);
1229       if (tran) {
1230 	TopLoc_Location Loc;
1231 	const Handle(Geom_Surface) Surf = BRep_Tool::Surface(FF,Loc);
1232 	Standard_Boolean isUperio = Surf->IsUPeriodic();
1233 	Standard_Boolean isVperio = Surf->IsVPeriodic();
1234 	gp_Dir2d dir2d = line2d->Direction();
1235 	Standard_Real delta;
1236 	if (isUperio && dir2d.IsParallel(gp::DX2d(),Precision::Angular())) {
1237 	  delta = (CDSmin - Cf) * dir2d.X();
1238 	  PCT->Translate(gp_Vec2d(delta,0.));
1239 	}
1240 	else if(isVperio && dir2d.IsParallel(gp::DY2d(),Precision::Angular())){
1241 	  delta = (CDSmin - Cf) * dir2d.Y();
1242 	  PCT->Translate(gp_Vec2d(0.,delta));
1243 	}
1244       }
1245     }
1246 
1247     TopOpeBRepDS_SetThePCurve(myBuilder,EE,FF,E.Orientation(),PCT);
1248   }
1249 }
1250 
1251 
1252 //=======================================================================
1253 //function : Orientation
1254 //purpose  :
1255 //=======================================================================
1256 
Orientation(TopoDS_Shape & S,const TopAbs_Orientation O) const1257 void  TopOpeBRepDS_BuildTool::Orientation(TopoDS_Shape& S,
1258 					  const TopAbs_Orientation O)const
1259 {
1260   S.Orientation(O);
1261 }
1262 
1263 
1264 //=======================================================================
1265 //function : Orientation
1266 //purpose  :
1267 //=======================================================================
1268 
Orientation(const TopoDS_Shape & S) const1269 TopAbs_Orientation  TopOpeBRepDS_BuildTool::Orientation
1270   (const TopoDS_Shape& S) const
1271 {
1272   return S.Orientation();
1273 }
1274 
1275 //=======================================================================
1276 //function : Closed
1277 //purpose  :
1278 //=======================================================================
1279 
Closed(TopoDS_Shape & S,const Standard_Boolean B) const1280 void  TopOpeBRepDS_BuildTool::Closed(TopoDS_Shape& S,
1281 				     const Standard_Boolean B)const
1282 {
1283   S.Closed(B);
1284 }
1285 
1286 
1287 //=======================================================================
1288 //function : Approximation
1289 //purpose  :
1290 //=======================================================================
1291 
Approximation() const1292 Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1293 {
1294   return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1295 }
1296 
UpdateSurface(const TopoDS_Shape & F,const Handle (Geom_Surface)& SU) const1297 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& F,const Handle(Geom_Surface)& SU) const
1298 {
1299   BRep_Builder BB;
1300   TopLoc_Location L;
1301   Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(F));
1302   BB.UpdateFace(TopoDS::Face(F),SU,L,tol);
1303 }
1304 
UpdateSurface(const TopoDS_Shape & E,const TopoDS_Shape & oldF,const TopoDS_Shape & newF) const1305 void TopOpeBRepDS_BuildTool::UpdateSurface(const TopoDS_Shape& E,const TopoDS_Shape& oldF,
1306 					   const TopoDS_Shape& newF) const
1307 {
1308   BRep_Builder BB;
1309   Standard_Real f,l;
1310   const Handle(Geom2d_Curve)& PC = BRep_Tool::CurveOnSurface(TopoDS::Edge(E),TopoDS::Face(oldF),f,l);
1311   Standard_Real tol = BRep_Tool::Tolerance(TopoDS::Face(oldF));
1312   BB.UpdateEdge(TopoDS::Edge(E),PC,TopoDS::Face(newF),tol);
1313 }
1314 
1315 
1316 /* // - merge 04-07-97
1317 //=======================================================================
1318 //function : RecomputeCurve
1319 //purpose  :
1320 //=======================================================================
1321 
1322 void  TopOpeBRepDS_BuildTool::RecomputeCurve
1323 (const TopOpeBRepDS_Curve& C1,
1324  TopoDS_Shape& E,
1325  TopOpeBRepDS_Curve& C2 ) const
1326 {
1327   // - C1 curves have been approximated by BSplines of degree 1 :
1328   // or
1329   // - C1.Curve() is non projectable on at least one of the original
1330   // intersecting faces.
1331 
1332   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1333   Standard_Boolean compc3d = GT.CompC3D();
1334   Standard_Boolean comppc1 = GT.CompPC1();
1335   Standard_Boolean comppc2 = GT.CompPC2();
1336 
1337   const Handle(Geom_Curve)& C3D = C1.Curve();
1338   if (compc3d && C3D.IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 1");
1339   if (comppc1 && C2.Shape1().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 2");
1340   if (comppc2 && C2.Shape2().IsNull()) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 3");
1341   TopoDS_Vertex Vmin,Vmax; TopExp::Vertices(TopoDS::Edge(E),Vmin,Vmax);
1342   if ( Vmin.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 4");
1343   if ( Vmax.IsNull() ) throw Standard_ProgramError("TopOpeBRepDS_BuildTool::RecomputeCurve 5");
1344 
1345   Standard_Boolean kbspl1 = Standard_False;
1346   Handle(Geom_BSplineCurve) BS = Handle(Geom_BSplineCurve)::DownCast(C3D);
1347   if (!BS.IsNull()) kbspl1 = (BS->Degree() == 1);
1348   if (kbspl1) RecomputeBSpline1Curve(C1,E,C2);
1349   else        RecomputeCurveOnCone(C1,E,C2);
1350 }
1351 
1352 //=======================================================================
1353 //function : RecomputeBSpline1Curve
1354 //purpose  :
1355 //=======================================================================
1356 
1357 void  TopOpeBRepDS_BuildTool::RecomputeBSpline1Curve
1358 (const TopOpeBRepDS_Curve& C1,
1359  TopoDS_Shape& EE,
1360  TopOpeBRepDS_Curve& C2) const
1361 {
1362   // C1 curves have been approximated by BSplines of degree 1 :
1363   // compute new geometry on curves.
1364 
1365   TopoDS_Edge& E = TopoDS::Edge(EE);
1366 
1367   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1368   TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1369   Standard_Boolean compc3d =            GT.CompC3D();
1370   Standard_Boolean comppc1 =            GT.CompPC1();
1371   Standard_Boolean comppc2 =            GT.CompPC2();
1372 
1373   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1374   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1375 
1376   const Handle(Geom_Curve)&   C3D = C1.Curve();
1377   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1378   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1379 
1380   // Vmin,Vmax = bounding vertices of edge <E>
1381   // and their parameters parmin,parmax .
1382 
1383   TopoDS_Vertex Vmin, Vmax;
1384   Standard_Real parmin = 0.0, parmax = 0.0;
1385   ::GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
1386 
1387   Handle(Geom_Curve)   C3Dnew;
1388   Handle(Geom2d_Curve) PC1new;
1389   Handle(Geom2d_Curve) PC2new;
1390   Standard_Real tolreached3d,tolreached2d;
1391 
1392   if ( typec3d == TopOpeBRepTool_BSPLINE1 ) {
1393     if ( compc3d ) {
1394       C3Dnew = Handle(Geom_BSplineCurve)::DownCast(C3D->Copy());
1395       (Handle(Geom_BSplineCurve)::DownCast(C3Dnew))->Segment(parmin,parmax);
1396     }
1397     if ( comppc1 && (!PC1.IsNull()) ) {
1398       PC1new = Handle(Geom2d_BSplineCurve)::DownCast(PC1->Copy());
1399       (Handle(Geom2d_BSplineCurve)::DownCast(PC1new))->Segment(parmin,parmax);
1400     }
1401     if ( comppc2 && (!PC2.IsNull()) ) {
1402       PC2new = Handle(Geom2d_BSplineCurve)::DownCast(PC2->Copy());
1403       (Handle(Geom2d_BSplineCurve)::DownCast(PC2new))->Segment(parmin,parmax);
1404     }
1405   }
1406 
1407   else if ( typec3d == TopOpeBRepTool_APPROX ) {
1408     if (!comppc1 || !comppc2) throw Standard_NotImplemented("DSBuildToolAPPROX");
1409     myCurveTool.MakeCurves(parmin,parmax,
1410 			   C3D,PC1,PC2,F1,F2,
1411 			   C3Dnew,PC1new,PC2new,
1412 			   tolreached3d,tolreached2d);
1413   }
1414 
1415   else if ( typec3d == TopOpeBRepTool_INTERPOL ) {
1416     throw Standard_NotImplemented("DSBuildToolINTERPOL");
1417   }
1418 
1419   Standard_Real newtol,newparmin,newparmax;
1420   ::FUN_updateEDGECURVETOL
1421     (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d,tolreached2d,
1422      newtol,newparmin,newparmax);
1423 
1424   if (!C3Dnew.IsNull()) {
1425     C2.DefineCurve(C3Dnew,newtol,Standard_False);
1426     C2.SetRange(newparmin,newparmax);
1427   }
1428   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1429   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1430 }
1431 
1432 
1433 //=======================================================================
1434 //function : RecomputeCurveOnCone
1435 //purpose  :
1436 //=======================================================================
1437 
1438 void  TopOpeBRepDS_BuildTool::RecomputeCurveOnCone
1439   (const TopOpeBRepDS_Curve& C1,
1440    TopoDS_Shape&             EE,
1441    TopOpeBRepDS_Curve&       C2 ) const
1442 {
1443   // C1 Pcurves have not been computed because C1 Curve is not projectable
1444   // on one at least of the intersecting faces giving C1 Curve.
1445   // (see TopOpeBRepTool_CurveTool::IsProjectable())
1446 
1447   TopoDS_Edge& E = TopoDS::Edge(EE);
1448 
1449   const TopOpeBRepTool_GeomTool& GT = myCurveTool.GetGeomTool();
1450   TopOpeBRepTool_OutCurveType typec3d = GT.TypeC3D();
1451   Standard_Boolean compc3d =            GT.CompC3D();
1452   Standard_Boolean comppc1 =            GT.CompPC1();
1453   Standard_Boolean comppc2 =            GT.CompPC2();
1454 
1455   const TopoDS_Face& F1 = TopoDS::Face(C2.Shape1());
1456   const TopoDS_Face& F2 = TopoDS::Face(C2.Shape2());
1457 
1458   const Handle(Geom_Curve)&   C3D = C1.Curve();
1459   const Handle(Geom2d_Curve)& PC1 = C1.Curve1();
1460   const Handle(Geom2d_Curve)& PC2 = C1.Curve2();
1461 
1462   // get bounding vertices Vmin,Vmax supported by the new edge <E>
1463   // and their corresponding parameters parmin,parmax .
1464   TopoDS_Vertex Vmin, Vmax;
1465   Standard_Real parmin = 0.0, parmax = 0.0;
1466   ::GetOrientedEdgeVertices (E, Vmin, Vmax, parmin, parmax);
1467 
1468   if ( C3D->IsPeriodic() ) {
1469     // ellipse on cone : periodize parmin,parmax
1470     Standard_Real period = C3D->LastParameter() - C3D->FirstParameter();
1471     Standard_Real f,l;
1472     if (Vmin.Orientation() == TopAbs_FORWARD) { f = parmin; l = parmax; }
1473     else {                                      f = parmax; l = parmin; }
1474     parmin = f; parmax = l;
1475     ElCLib::AdjustPeriodic(f,f+period,Precision::PConfusion(),parmin,parmax);
1476   }
1477 
1478   Handle(Geom_TrimmedCurve) C3Dnew;
1479   Handle(Geom2d_Curve) PC1new;
1480   Handle(Geom2d_Curve) PC2new;
1481   Standard_Real tolreached3d = C1.Tolerance();
1482   Standard_Real tolreached2d1 = C1.Tolerance();
1483   Standard_Real tolreached2d2 = C1.Tolerance();
1484   if (compc3d) C3Dnew = new Geom_TrimmedCurve(C3D,parmin,parmax);
1485   if (comppc1) PC1new = myCurveTool.MakePCurveOnFace(F1,C3Dnew,tolreached2d1);
1486   if (comppc2) PC2new = myCurveTool.MakePCurveOnFace(F2,C3Dnew,tolreached2d2);
1487 
1488 #ifdef DRAW
1489   if (tBUTO) {FUN_draw(F1); FUN_draw(F2); FUN_draw(E);}
1490 #endif
1491 
1492   Standard_Real newtol,newparmin,newparmax;
1493   FUN_updateEDGECURVETOL
1494   (*this,F1,F2,E,C3Dnew,tolreached3d,tolreached2d1,tolreached2d2,
1495    newtol,newparmin,newparmax);
1496 
1497 //   jyl : 16-06-97
1498 //  Standard_Real fac = 0.3798123578771;
1499 //  Standard_Real tol = newtol;
1500 //  Standard_Real par3d = (1-fac)*newparmin + (fac)*newparmax;
1501 //  Standard_Real par2d = par3d - newparmin;
1502 //
1503 //  gp_Pnt P3DC3D;       C3D->D0(par3d,P3DC3D);
1504 //
1505 //  Standard_Boolean UisoLineOnSphe1 = Standard_False;
1506 //  UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1507 //  if (UisoLineOnSphe1) {
1508 //    Standard_Real isrev1 =
1509 //      ::FUN_reversePC(PC1new,F1,P3DC3D,par2d,tol);
1510 //
1511 //
1512 //  }
1513 //
1514 //  Standard_Boolean UisoLineOnSphe2 = Standard_False;
1515 //  UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1516 //  if (UisoLineOnSphe2) {
1517 //    Standard_Real isrev2 =
1518 //     ::FUN_reversePC(PC2new,F2,P3DC3D,par2d,tol);
1519 //
1520 //  }
1521 
1522   // xpu : 17-06-97
1523   // Rmq : C1.Curve<i>() ne sert plus qu'a determiner si la courbe
1524   //       est une isos de la sphere
1525   // NYI : enlever FUN_reversePC
1526   Standard_Boolean UisoLineOnSphe1 = Standard_False;
1527   UisoLineOnSphe1 = ::FUN_UisoLineOnSphe(F1,PC1new);
1528   if (UisoLineOnSphe1) {
1529     ::FUN_makeUisoLineOnSphe(F1,C3Dnew,PC1new,newtol);
1530   }
1531   Standard_Boolean UisoLineOnSphe2 = Standard_False;
1532   UisoLineOnSphe2 = ::FUN_UisoLineOnSphe(F2,PC2new);
1533   if (UisoLineOnSphe2) {
1534     ::FUN_makeUisoLineOnSphe(F2,C3Dnew,PC2new,newtol);
1535   } // xpu : 17-06-97
1536 
1537   if (!C3Dnew.IsNull()) C2.Curve(C3Dnew,newtol);
1538   if (!PC1new.IsNull()) C2.Curve1(PC1new);
1539   if (!PC2new.IsNull()) C2.Curve2(PC2new);
1540 }*/ // - merge 04-07-97
1541