Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ShapeBuild / ShapeBuild_Edge.cxx
CommitLineData
7fd59977 1//#4 szv S4163: optimizing
2// pdn 20.04.99 S4181 Moving algorithm for transforming pcurves from IGES processor
3// abv 05.05.99 S4137: adding methods for copying ranges, reassigning pcurves etc.
4#include <ShapeBuild_Edge.ixx>
5#include <Standard_ErrorHandler.hxx>
6#include <Standard_Failure.hxx>
7
8#include <TopoDS.hxx>
9#include <TopoDS_Iterator.hxx>
10#include <TopExp.hxx>
11#include <BRep_Builder.hxx>
12#include <BRep_Tool.hxx>
13#include <BRep_TEdge.hxx>
14#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
15#include <BRep_GCurve.hxx>
16#include <BRepLib.hxx>
17#include <BRepBuilderAPI_MakeEdge.hxx>
18
19#include <gp_Pnt.hxx>
20#include <gp_Lin2d.hxx>
21#include <gp_GTrsf2d.hxx>
22#include <gp_Pln.hxx>
23#include <ElCLib.hxx>
24#include <Precision.hxx>
25
26#include <Geom2d_TrimmedCurve.hxx>
27#include <Geom2d_Line.hxx>
28#include <Geom2d_BSplineCurve.hxx>
29#include <Geom2d_Conic.hxx>
30#include <Geom2dConvert.hxx>
31#include <Geom2dConvert_ApproxCurve.hxx>
32#include <GeomAPI.hxx>
33#include <Geom2d_BezierCurve.hxx>
34#include <Geom2d_TrimmedCurve.hxx>
35#include <BRep_Curve3D.hxx>
36#include <BRep_CurveOnSurface.hxx>
37#include <Geom2d_OffsetCurve.hxx>
38#include <Geom_TrimmedCurve.hxx>
39#include <Geom_OffsetCurve.hxx>
40#include <TopTools_SequenceOfShape.hxx>
41
42//=======================================================================
43//function : CopyReplaceVertices
44//purpose :
45//=======================================================================
46
47TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge,
48 const TopoDS_Vertex& V1,
49 const TopoDS_Vertex& V2) const
50{
51 TopTools_SequenceOfShape aNMVertices;
52 TopoDS_Vertex newV1 = V1, newV2 = V2;
53 if ( newV1.IsNull() || newV2.IsNull() ) {
54 for ( TopoDS_Iterator it(edge); it.More(); it.Next() ) {
55 TopoDS_Vertex V = TopoDS::Vertex ( it.Value() );
56 if ( V.Orientation() == TopAbs_FORWARD ) {
57 if ( newV1.IsNull() ) newV1 = V;
58 }
59 else if ( V.Orientation() == TopAbs_REVERSED ) {
60 if ( newV2.IsNull() ) newV2 = V;
61 }
62 else if(V1.IsNull() && V2.IsNull())
63 aNMVertices.Append(V);
64 }
65 }
66 newV1.Orientation ( TopAbs_FORWARD );
67 newV2.Orientation ( TopAbs_REVERSED );
68
69 //szv#4:S4163:12Mar99 SGI warns
70 TopoDS_Shape sh = edge.EmptyCopied();
71 TopoDS_Edge E = TopoDS::Edge( sh );
72
73 BRep_Builder B;
74 if ( ! newV1.IsNull() ) B.Add ( E, newV1 );
75 if ( ! newV2.IsNull() ) B.Add ( E, newV2 );
76
77 //addition of the internal or external vertices to edge
78 Standard_Integer i =1;
79 for( ; i <= aNMVertices.Length(); i++)
80 B.Add ( E,TopoDS::Vertex(aNMVertices.Value(i)));
81
82 //S4054, rln 17.11.98 annie_surf.igs entity D77, 3D and pcurve have different
83 //ranges, after B.Range all the ranges become as 3D
84 CopyRanges ( E, edge );
85/*
86 for (BRep_ListIteratorOfListOfCurveRepresentation itcr
87 ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
88 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
89 if ( GC.IsNull() ) continue;
90 Standard_Real first, last;
91 GC->Range ( first, last );
92 if ( GC->IsCurve3D() )
93 B.Range ( E, first, last );
94 else if ( GC->IsCurveOnSurface() )
95 B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1
96 }
97*/
98 return E;
99}
100
101//=======================================================================
102//function : CopyRanges
103//purpose :
104//=======================================================================
105
106// Added, cause invoke ShapeAnalysis leads to cyclic dependancy.
107static Standard_Real AdjustByPeriod(const Standard_Real Val,
108 const Standard_Real ToVal,
109 const Standard_Real Period)
110{
111 Standard_Real diff = Val - ToVal;
112 Standard_Real D = Abs ( diff );
113 Standard_Real P = Abs ( Period );
114 if ( D <= 0.5 * P ) return 0.;
115 if ( P < 1e-100 ) return diff;
116 return ( diff >0 ? -P : P ) * (Standard_Integer)( D / P + 0.5 );
117}
118
119static Standard_Boolean IsPeriodic(const Handle(Geom_Curve)& theCurve)
120{
121 // 15.11.2002 PTV OCC966
122 // remove regressions in DE tests (diva, divb, divc, toe3) in KAS:dev
123 // ask IsPeriodic on BasisCurve
124 Handle(Geom_Curve) aTmpCurve = theCurve;
125 while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) ||
126 (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) {
127 if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve)))
128 aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
129 if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
130 aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
131 }
132 return aTmpCurve->IsPeriodic();
133}
134
135Standard_Boolean IsPeriodic(const Handle(Geom2d_Curve)& theCurve)
136{
137 // 15.11.2002 PTV OCC966
138 // remove regressions in DE tests (diva, divb, divc, toe3) in KAS:dev
139 // ask IsPeriodic on BasisCurve
140 Handle(Geom2d_Curve) aTmpCurve = theCurve;
141 while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) ||
142 (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) {
143 if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)))
144 aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve();
145 if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
146 aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve();
147 }
148 return aTmpCurve->IsPeriodic();
149}
150
151void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge,
152 const TopoDS_Edge& fromedge,
153 const Standard_Real alpha,
154 const Standard_Real beta) const
155{
156/* BRep_Builder B;
157 for (BRep_ListIteratorOfListOfCurveRepresentation itcr
158 ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
159 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
160 if ( GC.IsNull() ) continue;
161 Standard_Real first, last;
162 GC->Range ( first, last );
163 if ( GC->IsCurve3D() )
164 B.Range ( toedge, first, last );
165 else if ( GC->IsCurveOnSurface() )
166 B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last);
167 }
168*/
169 for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr
170 ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) {
171 Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
172 if ( fromGC.IsNull() ) continue;
173 Standard_Boolean isC3d = fromGC->IsCurve3D();
174 if(isC3d) {
175 if(fromGC->Curve3D().IsNull()) continue; }
176 else {
177 if(fromGC->PCurve().IsNull()) continue; }
178
179 if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated
180
181 Handle(Geom_Surface) surface;
182 TopLoc_Location L;
183 if ( ! isC3d ) {
184 surface = fromGC->Surface();
185 L = fromGC->Location();
186 }
187
188 BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
189 Handle(BRep_GCurve) toGC;
190 for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
191 toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
192 if ( toGC.IsNull() ) continue;
193 if ( isC3d ) {
194 if ( ! toGC->IsCurve3D() ) continue;
195 }
196 else if ( ! toGC->IsCurveOnSurface() ||
197 surface != toGC->Surface() || L != toGC->Location() ) continue;
198 Standard_Real first = fromGC->First();
199 Standard_Real last = fromGC->Last();
200 Standard_Real len = last - first;
201 Standard_Real newF = first+alpha*len;
202 Standard_Real newL = first+beta*len;
203
204 // PTV: 22.03.2002 fix for edge range.
205 // file test-m020306-v2.step Shell #665 (Faces #40110. #40239).
206 Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.;
207 Standard_Boolean doCheck = Standard_False;
208 if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) {
209 Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D();
210 // 15.11.2002 PTV OCC966
211 if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) {
212 aPeriod = aCrv3d->Period();
213 aCrvF = aCrv3d->FirstParameter();
214 aCrvL = aCrv3d->LastParameter();
215 doCheck = Standard_True;
216 }
217 }
218 else if (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) {
219 Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve();
220 // 15.11.2002 PTV OCC966
221 if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) {
222 aPeriod = aCrv2d->Period();
223 aCrvF = aCrv2d->FirstParameter();
224 aCrvL = aCrv2d->LastParameter();
225 doCheck = Standard_True;
226 }
227 }
228 if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) {
229 Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod);
230 newF += aShift;
231 newL += aShift;
232 BRep_Builder().SameRange(toedge,Standard_False);
233 BRep_Builder().SameParameter(toedge,Standard_False);
234 }
235
236 toGC->SetRange ( newF, newL );
237 break;
238 }
239 }
240}
241
242//=======================================================================
243//function : SetRange3d
244//purpose :
245//=======================================================================
246
247void ShapeBuild_Edge::SetRange3d (const TopoDS_Edge& edge,
248 const Standard_Real first,
249 const Standard_Real last) const
250{
251
252 for (BRep_ListIteratorOfListOfCurveRepresentation itcr
253 ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
254 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
255 if ( GC.IsNull() || !GC->IsCurve3D() ) continue;
256 GC->SetRange ( first, last );
257 break;
258 }
259}
260
261//=======================================================================
262//function : CopyPCurves
263//purpose :
264//=======================================================================
265
266void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge& fromedge) const
267{
268 TopLoc_Location fromLoc = fromedge.Location();
269 TopLoc_Location toLoc = toedge.Location();
270 for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr
271 ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) {
272 Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
273 if ( fromGC.IsNull() ) continue;
274 if ( fromGC->IsCurveOnSurface() ) {
275 Handle(Geom_Surface) surface = fromGC->Surface();
276 TopLoc_Location L = fromGC->Location();
277 Standard_Boolean found = Standard_False;
278 BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves();
279 Handle(BRep_GCurve) toGC;
280 for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) {
281 toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
282 if ( toGC.IsNull() || !toGC->IsCurveOnSurface() ||
283 surface != toGC->Surface() || L != toGC->Location() ) continue;
284 found = Standard_True;
285 break;
286 }
287 if (!found) {
288 toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy());
289 tolist.Append (toGC);
290 }
291 Handle(Geom2d_Curve) pcurve = fromGC->PCurve();
292 toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
293
294 //bug OCC209 invalid location of pcurve in the edge after copying
295 TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc);
296 toGC->Location(newLoc);
297 if ( fromGC->IsCurveOnClosedSurface() ) {
298 pcurve = fromGC->PCurve2();
299 toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy()));
300 }
301 }
302 }
303}
304//=======================================================================
305//function : Copy
306//purpose :
307//=======================================================================
308
309TopoDS_Edge ShapeBuild_Edge::Copy (const TopoDS_Edge &edge,
310 const Standard_Boolean sharepcurves) const
311{
312 TopoDS_Vertex dummy1, dummy2;
313 TopoDS_Edge newedge = CopyReplaceVertices ( edge, dummy1, dummy2 );
314 if ( ! sharepcurves ) CopyPCurves ( newedge, edge );
315 return newedge;
316}
317
318//=======================================================================
319//function : RemovePCurve
320//purpose :
321//=======================================================================
322
323void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
324 const TopoDS_Face& face) const
325{
326 BRep_Builder B;
327 Handle(Geom2d_Curve) c2dNull;
328//:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge );
329 if ( BRep_Tool::IsClosed ( edge, face ) )
330 B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol
331 else B.UpdateEdge ( edge, c2dNull, face, 0. ); //:S4136: tol
332}
333
334//=======================================================================
335//function : RemovePCurve
336//purpose :
337//=======================================================================
338
339void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
340 const Handle(Geom_Surface)& surf) const
341{
342 RemovePCurve ( edge, surf, TopLoc_Location() );
343}
344
345//=======================================================================
346//function : RemovePCurve
347//purpose :
348//=======================================================================
349
350void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge,
351 const Handle(Geom_Surface)& surf,
352 const TopLoc_Location &loc) const
353{
354 BRep_Builder B;
355 Handle(Geom2d_Curve) c2dNull;
356//:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge );
357 if ( BRep_Tool::IsClosed ( edge, surf, loc ) )
358 B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol
359 else B.UpdateEdge ( edge, c2dNull, surf, loc, 0. ); //:S4136: tol
360}
361
362//=======================================================================
363//function : ReplacePCurve
364//purpose :
365//=======================================================================
366
367void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge,
368 const Handle(Geom2d_Curve)& pcurve,
369 const TopoDS_Face& face) const
370{
371 BRep_Builder B;
372 Standard_Real f,l;
373 TopoDS_Shape dummy = edge.Reversed();
374 TopoDS_Edge edgerev = TopoDS::Edge(dummy);
375 // reverse face to take second pcurve for seams like SA_Edge::PCurve() does
376 TopoDS_Face F = TopoDS::Face(face.Oriented ( TopAbs_FORWARD ) );
377 Handle(Geom2d_Curve) pcurve0 = BRep_Tool::CurveOnSurface(edge,F,f,l);
378 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edgerev,F,f,l);
379 // Add pcurve to edge (either as single, or as seam)
380 if ( c2d.IsNull() || c2d == pcurve0 ) { // non-seam
381 B.UpdateEdge(edge,pcurve,face,0);
382 }
383 else { // seam
384 if(edge.Orientation()==TopAbs_FORWARD)
385 B.UpdateEdge(edge,pcurve,c2d,face,0);
386 else
387 B.UpdateEdge(edge,c2d,pcurve,face,0);
388 }
389 B.Range ( edge, face, f, l );
390}
391
392//=======================================================================
393//function : ReassignPCurve
394//purpose :
395//=======================================================================
396
397// Count exact number of pcurves STORED in edge for face
398// This makes difference for faces based on plane surfaces where pcurves can be
399// not stored but returned by BRep_Tools::CurveOnSurface
400static Standard_Integer CountPCurves (const TopoDS_Edge &edge,
401 const TopoDS_Face &face)
402{
403 TopLoc_Location L;
404 Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L );
405 TopLoc_Location l = L.Predivided(edge.Location());
406
407 for (BRep_ListIteratorOfListOfCurveRepresentation itcr
408 ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) {
409 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
410 if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) )
411 return ( GC->IsCurveOnClosedSurface() ? 2 : 1 );
412 }
413 return 0;
414}
415
416Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge,
417 const TopoDS_Face& old,
418 const TopoDS_Face& sub) const
419{
420 Standard_Integer npcurves = CountPCurves ( edge, old );
421 //if ( npcurves <1 ) return Standard_False; //gka
422
423 Standard_Real f, l;
424 Handle(Geom2d_Curve) pc;
425 pc = BRep_Tool::CurveOnSurface ( edge, old, f, l );
426 if ( pc.IsNull() ) return Standard_False;
427 else if( npcurves == 0) npcurves =1; //gka
428
429
430 BRep_Builder B;
431
432 // if the pcurve was only one, remove; else leave second one
433 if ( npcurves >1 ) {
434 //smh#8 Porting AIX
435 TopoDS_Shape tmpshape = edge.Reversed();
436 TopoDS_Edge erev = TopoDS::Edge (tmpshape);
437 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface ( erev, old, f, l );
438 B.UpdateEdge ( edge, pc2, old, 0. );
439 B.Range ( edge, old, f, l );
440 }
441 else RemovePCurve ( edge, old );
442
443 // if edge does not have yet pcurves on sub, just add; else add as first
444 Standard_Integer npcs = CountPCurves ( edge, sub );
445 if ( npcs <1 ) B.UpdateEdge ( edge, pc, sub, 0. );
446 else {
447//smh#8 Porting AIX
448 TopoDS_Shape tmpshape = edge.Reversed();
449 TopoDS_Edge erev = TopoDS::Edge (tmpshape);
450 Standard_Real cf, cl;
451 Handle(Geom2d_Curve) pcs = BRep_Tool::CurveOnSurface ( erev, sub, cf, cl );
452 if ( edge.Orientation() == TopAbs_REVERSED ) // because B.UpdateEdge does not check edge orientation
453 B.UpdateEdge ( edge, pcs, pc, sub, 0. );
454 else B.UpdateEdge ( edge, pc, pcs, sub, 0. );
455 }
456
457 B.Range ( edge, sub, f, l );
458
459 return Standard_True;
460}
461
462//=======================================================================
463//function : TransformPCurve
464//purpose :
465//=======================================================================
466
467Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)& pcurve,
468 const gp_Trsf2d& trans,
469 const Standard_Real uFact,
470 Standard_Real& aFirst,
471 Standard_Real& aLast) const
472{
473 Handle(Geom2d_Curve) result = Handle(Geom2d_Curve)::DownCast(pcurve->Copy());
474 if(trans.Form()!=gp_Identity) {
475 result->Transform (trans);
476 aFirst = result->TransformedParameter(aFirst,trans);
477 aLast = result->TransformedParameter(aLast, trans);
478 }
479 if(uFact==1.)
480 return result;
481
482 if (result->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
483 Handle(Geom2d_TrimmedCurve) thecurve = Handle(Geom2d_TrimmedCurve)::DownCast(result);
484 result = thecurve->BasisCurve();
485 }
486
487 gp_GTrsf2d tMatu;
488 tMatu.SetAffinity(gp::OY2d(), uFact);
489 gp_XY pXY;
490
491 if (result->IsKind(STANDARD_TYPE(Geom2d_Line))) {
492 Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(result);
493 gp_Pnt2d Pf, Pl;
494 aLine2d->D0(aFirst,Pf);
495 pXY = Pf.XY();
496 tMatu.Transforms(pXY);
497 Pf.SetXY(pXY);
498 aLine2d->D0(aLast, Pl);
499 pXY = Pl.XY();
500 tMatu.Transforms(pXY);
501 Pl.SetXY(pXY);
502 gp_Lin2d line2d(Pf, gp_Dir2d(gp_Vec2d(Pf,Pl)));
503 aFirst = ElCLib::Parameter(line2d, Pf);
504 aLast = ElCLib::Parameter(line2d, Pl);
505 Handle(Geom2d_Line) Gline2d = new Geom2d_Line(line2d);
506 return Gline2d;
507 }
508 else if(result->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
509 Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(result);
510 // transform the Poles of the BSplineCurve
511 Standard_Integer nbPol = bezier->NbPoles();
512 gp_Pnt2d Pt1;
513 for (Standard_Integer i = 1; i<=nbPol ; i++) {
514 pXY = bezier->Pole(i).XY();
515 tMatu.Transforms(pXY);
516 Pt1.SetXY(pXY);
517 bezier->SetPole(i, Pt1);
518 }
519 return bezier;
520 } else {
521 Handle(Geom2d_BSplineCurve) aBSpline2d;
522 if(result->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
523 //gp_Pln pln(gp_Pnt(0,0,0),gp_Dir(0,0,1));
524 //Handle(Geom_Curve) curve = GeomAPI::To3d(result,pln);
525 Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(result,aFirst,aLast); //protection agains parabols ets
526 Geom2dConvert_ApproxCurve approx (tcurve, Precision::Approximation(),
527 GeomAbs_C1, 100, 6 );
528 if ( approx.HasResult() )
529 aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve());
530 else
531 aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
532 aFirst = aBSpline2d->FirstParameter();
533 aLast = aBSpline2d->LastParameter();
534 }
535 else if(!result->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
536 aBSpline2d = Geom2dConvert::CurveToBSplineCurve(result,Convert_QuasiAngular);
537 }
538 else
539 aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(result);
540
541 // transform the Poles of the BSplineCurve
542 Standard_Integer nbPol = aBSpline2d->NbPoles();
543 gp_Pnt2d Pt1;
544 for (Standard_Integer i = 1; i<=nbPol ; i++) {
545 pXY = aBSpline2d->Pole(i).XY();
546 tMatu.Transforms(pXY);
547 Pt1.SetXY(pXY);
548 aBSpline2d->SetPole(i, Pt1);
549 }
550 return aBSpline2d;
551 }
552 return result;
553}
554
555//=======================================================================
556//function : RemoveCurve3d
557//purpose :
558//=======================================================================
559
560void ShapeBuild_Edge::RemoveCurve3d (const TopoDS_Edge& edge) const
561{
562 BRep_Builder B;
563 Handle(Geom_Curve) c3dNull;
564//:S4136 Standard_Real tol = BRep_Tool::Tolerance (edge);
565 B.UpdateEdge (edge, c3dNull, 0. ); //:S4136: tol
566}
567
568//=======================================================================
569//function : BuildCurve3d
570//purpose :
571//=======================================================================
572
573Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const
574{
575 try {
576 OCC_CATCH_SIGNALS
577 //#48 rln 10.12.98 S4054 UKI60107-5 entity 365
578 //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07
579 //lets use maximum of tolerance and default parameter 1.e-5
580 //Another solutions: use quite big Tolerance or require C0 curve on C0 surface
581 if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) {
582 //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back
583 //with 2DUse_Forced - pcurve and removed 3D curves have different ranges
584 if (BRep_Tool::SameRange (edge)) {
585 Standard_Real first, last;
586 BRep_Tool::Range (edge, first, last);
587 BRep_Builder().Range (edge, first, last);//explicit setting for all reps
588 }
589 Handle(Geom_Curve) c3d;
590 Standard_Real f,l;
591 c3d = BRep_Tool::Curve(edge,f,l);
592 // 15.11.2002 PTV OCC966
593 if(!IsPeriodic(c3d)) {
594 Standard_Boolean isLess = Standard_False;
595 if(f < c3d->FirstParameter()) {
596 isLess = Standard_True;
597 f = c3d->FirstParameter();
598 }
599 if(l > c3d->LastParameter()) {
600 isLess = Standard_True;
601 l = c3d->LastParameter();
602 }
603 if(isLess) {
604 SetRange3d(edge,f,l);
605 BRep_Builder().SameRange(edge,Standard_False);
606 }
607 }
608
609 return Standard_True;
610 }
611 }
612 catch(Standard_Failure) {
613#ifdef DEB
614 cout << "\nWarning: ShapeBuild_Edge: Exception in BuildCurve3d: ";
615 Standard_Failure::Caught()->Print(cout); cout << endl;
616#endif
617 }
618 return Standard_False;
619}
620
621
622//=======================================================================
623//function : MakeEdge
624//purpose :
625//=======================================================================
626
627 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const
628{
629 MakeEdge (edge,curve, L, curve->FirstParameter(), curve->LastParameter());
630}
631
632//=======================================================================
633//function : MakeEdge
634//purpose :
635//=======================================================================
636
637 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const
638{
639 BRepBuilderAPI_MakeEdge ME (curve, p1, p2);
640 if (!ME.IsDone()) {
641#ifdef DEB
642 cout << "\nWarning: ShapeBuild_Edge::MakeEdge BRepAPI_NotDone";
643#endif
644 return;
645 }
646 TopoDS_Edge E = ME.Edge();
647 if (!L.IsIdentity()) {
648 BRep_Builder B;
649 B.UpdateEdge (E, curve, L, 0.);
650 B.Range (E, p1, p2);
651
652 TopoDS_Vertex V1, V2;
653 TopExp::Vertices (E, V1, V2);
654 gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2);
655 B.UpdateVertex (V1, P1.Transformed (L.Transformation()), 0.);
656 B.UpdateVertex (V2, P2.Transformed (L.Transformation()), 0.);
657 }
658 edge = E;
659 return;
660}
661
662//=======================================================================
663//function : MakeEdge
664//purpose :
665//=======================================================================
666
667 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const
668{
669 MakeEdge (edge, pcurve, face, pcurve->FirstParameter(), pcurve->LastParameter());
670}
671
672//=======================================================================
673//function : MakeEdge
674//purpose :
675//=======================================================================
676
677 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const
678{
679 TopLoc_Location L;
680 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
681 MakeEdge (edge, pcurve, S, L, p1, p2);
682}
683
684//=======================================================================
685//function : MakeEdge
686//purpose :
687//=======================================================================
688
689 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
690 const Handle(Geom_Surface)& S,const TopLoc_Location& L) const
691{
692 MakeEdge(edge, pcurve, S, L, pcurve->FirstParameter(), pcurve->LastParameter());
693}
694
695//=======================================================================
696//function : MakeEdge
697//purpose :
698//=======================================================================
699
700 void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,
701 const Handle(Geom_Surface)& S,const TopLoc_Location& L,
702 const Standard_Real p1,const Standard_Real p2) const
703{
704 BRepBuilderAPI_MakeEdge ME (pcurve, S, p1, p2);
705 if (!ME.IsDone()) {
706#ifdef DEB
707 cout << "\nWarning: ShapeBuild_Edge::MakeEdge BRepAPI_NotDone";
708#endif
709 return;
710 }
711 TopoDS_Edge E = ME.Edge();
712 if (!L.IsIdentity()) {
713 RemovePCurve (E, S);
714 BRep_Builder B;
715 B.UpdateEdge (E, pcurve, S, L, 0.);
716 B.Range (E, S, L, p1, p2);
717
718 TopoDS_Vertex V1, V2;
719 TopExp::Vertices (E, V1, V2);
720 gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2);
721 B.UpdateVertex (V1, P1.Transformed (L.Transformation()), 0.);
722 B.UpdateVertex (V2, P2.Transformed (L.Transformation()), 0.);
723 }
724 edge = E;
725 return;
726}
727