0032437: Coding Rules - eliminate MinGW warning -Wmaybe-uninitialized
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_BuildTool.cxx
... / ...
CommitLineData
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
86Standard_EXPORT Handle(Geom2d_Curve) BASISCURVE2D(const Handle(Geom2d_Curve)& C);
87
88Standard_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
114TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool():
115myCurveTool(TopOpeBRepTool_APPROX),
116myOverWrite(Standard_True),
117myTranslate(Standard_True)
118{
119}
120
121//=======================================================================
122//function : TopOpeBRepDS_BuildTool
123//purpose :
124//=======================================================================
125
126TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
127 (const TopOpeBRepTool_OutCurveType O) :
128myCurveTool(O),
129myOverWrite(Standard_True),
130myTranslate(Standard_True)
131{
132}
133
134//=======================================================================
135//function : TopOpeBRepDS_BuildTool
136//purpose :
137//=======================================================================
138
139TopOpeBRepDS_BuildTool::TopOpeBRepDS_BuildTool
140 (const TopOpeBRepTool_GeomTool& GT) :
141myCurveTool(GT),
142myOverWrite(Standard_True),
143myTranslate(Standard_True)
144{
145}
146
147Standard_Boolean TopOpeBRepDS_BuildTool::OverWrite()const
148{
149 return myOverWrite;
150}
151
152void TopOpeBRepDS_BuildTool::OverWrite(const Standard_Boolean O)
153{
154 myOverWrite = O;
155}
156
157Standard_Boolean TopOpeBRepDS_BuildTool::Translate()const
158{
159 return myTranslate;
160}
161
162void TopOpeBRepDS_BuildTool::Translate(const Standard_Boolean T)
163{
164 myTranslate = T;
165}
166
167//=======================================================================
168//function : GetGeomTool
169//purpose :
170//=======================================================================
171
172const 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
183TopOpeBRepTool_GeomTool& TopOpeBRepDS_BuildTool::ChangeGeomTool()
184{
185 TopOpeBRepTool_GeomTool& GT = myCurveTool.ChangeGeomTool();
186 return GT;
187}
188
189//=======================================================================
190//function : MakeVertex
191//purpose :
192//=======================================================================
193
194void 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
205void 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
259void 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
297void 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
311void 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
322void 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
333void 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
345void 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
356void 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
367void 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
399void 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
419void 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
527void 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//=======================================================================
593Standard_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
607Standard_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}
632Standard_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
669void 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
760void 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
786void 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
843void 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
855void 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
872void 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
884void 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
896void 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
908void 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
920void 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
932void 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
975void 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
988void 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
1012static 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
1041void 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
1056void 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
1072void 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
1128Standard_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
1160void 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
1207void 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
1257void 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
1269TopAbs_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
1280void 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
1292Standard_Boolean TopOpeBRepDS_BuildTool::Approximation() const
1293{
1294 return myCurveTool.GetGeomTool().TypeC3D() != TopOpeBRepTool_BSPLINE1;
1295}
1296
1297void 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
1305void 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
1322void 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
1357void 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
1438void 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