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