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