0028968: Incorrect offset for the faces with singularities
[occt.git] / src / BRepOffset / BRepOffset_MakeSimpleOffset.cxx
CommitLineData
8013367c 1// Created on: 2016-10-13
2// Created by: Alexander MALYSHEV
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2016 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 self.
18#include <BRepOffset_MakeSimpleOffset.hxx>
19
20#include <Adaptor3d_CurveOnSurface.hxx>
21#include <BRep_Builder.hxx>
22#include <BRep_Tool.hxx>
23#include <BRepLib.hxx>
24#include <BRepLib_MakeEdge.hxx>
25#include <BRepLib_MakeFace.hxx>
26#include <BRepTools_Quilt.hxx>
27#include <BRepAdaptor_HCurve2d.hxx>
28#include <BRepAdaptor_HSurface.hxx>
29#include <BRepAdaptor_Surface.hxx>
30#include <BRepOffset_SimpleOffset.hxx>
31#include <BRepTools_Modifier.hxx>
32#include <Geom_TrimmedCurve.hxx>
33#include <Geom2d_Line.hxx>
34#include <GeomFill_Generator.hxx>
35#include <Extrema_LocateExtPC.hxx>
36#include <NCollection_List.hxx>
37#include <ShapeAnalysis_FreeBounds.hxx>
38#include <ShapeFix_Edge.hxx>
39#include <TopExp.hxx>
40#include <TopExp_Explorer.hxx>
41#include <TopoDS_Edge.hxx>
42#include <TopoDS_Face.hxx>
43#include <TopoDS.hxx>
44#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
45#include <TopTools_ListIteratorOfListOfShape.hxx>
46
47
48//=============================================================================
49//function : BRepOffset_MakeSimpleOffset
50//purpose : Constructor
51//=============================================================================
52BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset()
8574e329 53: myOffsetValue(0.),
54 myTolerance(Precision::Confusion()),
55 myIsBuildSolid(Standard_False),
8013367c 56 myMaxAngle(0.0),
57 myError(BRepOffsetSimple_OK),
58 myIsDone(Standard_False)
59{
60 myReShape = new ShapeBuild_ReShape();
61}
62
63//=============================================================================
64//function : BRepOffset_MakeSimpleOffset
65//purpose : Constructor
66//=============================================================================
67BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset(const TopoDS_Shape& theInputShape,
68 const Standard_Real theOffsetValue)
69: myInputShape(theInputShape),
70 myOffsetValue(theOffsetValue),
8574e329 71 myTolerance(Precision::Confusion()),
8013367c 72 myIsBuildSolid(Standard_False),
73 myMaxAngle(0.0),
74 myError(BRepOffsetSimple_OK),
75 myIsDone(Standard_False)
76{
77 myReShape = new ShapeBuild_ReShape();
78}
79
80//=============================================================================
81//function : Initialize
82//purpose :
83//=============================================================================
84void BRepOffset_MakeSimpleOffset::Initialize(const TopoDS_Shape& theInputShape,
85 const Standard_Real theOffsetValue)
86{
87 myInputShape = theInputShape;
88 myOffsetValue = theOffsetValue;
89 Clear();
90}
91
92//=============================================================================
93//function : GetErrorMessage
94//purpose :
95//=============================================================================
96TCollection_AsciiString BRepOffset_MakeSimpleOffset::GetErrorMessage() const
97{
98 TCollection_AsciiString anError = "";
99
100 if (myError == BRepOffsetSimple_NullInputShape)
101 {
102 anError = "Null input shape";
103 return anError;
104 }
105 else if (myError == BRepOffsetSimple_ErrorOffsetComputation)
106 {
107 anError = "Error during offset construction";
108 return anError;
109 }
110 else if (myError == BRepOffsetSimple_ErrorWallFaceComputation)
111 {
112 anError = "Error during building wall face";
113 return anError;
114 }
115 else if (myError == BRepOffsetSimple_ErrorInvalidNbShells)
116 {
117 anError = "Result contains two or more shells";
118 return anError;
119 }
120 else if (myError == BRepOffsetSimple_ErrorNonClosedShell)
121 {
122 anError = "Result shell is not closed";
123 return anError;
124 }
125
126 return anError;
127}
128
129//=============================================================================
130//function : Clear
131//purpose :
132//=============================================================================
133void BRepOffset_MakeSimpleOffset::Clear()
134{
135 myIsDone = Standard_False;
136 myError = BRepOffsetSimple_OK;
137 myMaxAngle = 0.0;
138 myMapVE.Clear();
139 myReShape->Clear(); // Clear possible stored modifications.
140}
141
142//=============================================================================
143//function : GetSafeOffset
144//purpose :
145//=============================================================================
146Standard_Real BRepOffset_MakeSimpleOffset::GetSafeOffset(const Standard_Real theExpectedToler)
147{
148 if (myInputShape.IsNull())
149 return 0.0; // Input shape is null.
150
151 // Compute max angle in faces junctions.
152 if (myMaxAngle == 0.0) // Non-initialized.
153 ComputeMaxAngle();
154
155 Standard_Real aMaxTol = 0.0;
156 aMaxTol = BRep_Tool::MaxTolerance(myInputShape, TopAbs_VERTEX);
157
158 const Standard_Real anExpOffset = Max((theExpectedToler - aMaxTol) / (2.0 * myMaxAngle),
159 0.0); // Minimal distance can't be lower than 0.0.
160 return anExpOffset;
161}
162
163//=============================================================================
164//function : Perform
165//purpose :
166//=============================================================================
167void BRepOffset_MakeSimpleOffset::Perform()
168{
169 // Clear result of previous computations.
170 Clear();
171
172 // Check shape existence.
173 if (myInputShape.IsNull())
174 {
175 myError = BRepOffsetSimple_NullInputShape;
176 return;
177 }
178
179 if (myMaxAngle == 0.0) // Non-initialized.
180 ComputeMaxAngle();
181
182 myBuilder.Init(myInputShape);
8574e329 183 Handle(BRepOffset_SimpleOffset) aMapper = new BRepOffset_SimpleOffset(myInputShape, myOffsetValue, myTolerance);
8013367c 184 myBuilder.Perform(aMapper);
185
186 if (!myBuilder.IsDone())
187 {
188 myError = BRepOffsetSimple_ErrorOffsetComputation;
189 return;
190 }
191
192 myResShape = myBuilder.ModifiedShape(myInputShape);
193
194 // Fix degeneracy. Degenerated edge should be mapped to the degenerated.
195 BRep_Builder aBB;
196 TopExp_Explorer anExpSE(myInputShape, TopAbs_EDGE);
197 for(; anExpSE.More(); anExpSE.Next())
198 {
199 const TopoDS_Edge & aCurrEdge = TopoDS::Edge(anExpSE.Current());
200
201 if (!BRep_Tool::Degenerated(aCurrEdge))
202 continue;
203
204 const TopoDS_Edge & anEdge = TopoDS::Edge(myBuilder.ModifiedShape(aCurrEdge));
205 aBB.Degenerated(anEdge, Standard_True);
206 }
207
208 // Restore walls for solid.
209 if (myIsBuildSolid && !BuildMissingWalls())
210 return;
211
212 myIsDone = Standard_True;
213}
214
215//=============================================================================
216//function : tgtfaces
217//purpose : check the angle at the border between two squares.
218// Two shares should have a shared front edge.
219//=============================================================================
220static void tgtfaces(const TopoDS_Edge& Ed,
221 const TopoDS_Face& F1,
222 const TopoDS_Face& F2,
223 const Standard_Boolean couture,
224 Standard_Real& theResAngle)
225{
226 // Check that pcurves exist on both faces of edge.
227 Standard_Real aFirst,aLast;
228 Handle(Geom2d_Curve) aCurve;
229 aCurve = BRep_Tool::CurveOnSurface(Ed,F1,aFirst,aLast);
230 if(aCurve.IsNull())
231 return;
232 aCurve = BRep_Tool::CurveOnSurface(Ed,F2,aFirst,aLast);
233 if(aCurve.IsNull())
234 return;
235
236 Standard_Real u;
237 TopoDS_Edge E = Ed;
238 BRepAdaptor_Surface aBAS1(F1,Standard_False);
239 BRepAdaptor_Surface aBAS2(F2,Standard_False);
240
241 Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface (aBAS1);
242 Handle(BRepAdaptor_HSurface) HS2;
243 if(couture) HS2 = HS1;
244 else HS2 = new BRepAdaptor_HSurface(aBAS2);
245 //case when edge lies on the one face
246
247 E.Orientation(TopAbs_FORWARD);
248 BRepAdaptor_Curve2d C2d1(E, F1);
249 if(couture) E.Orientation(TopAbs_REVERSED);
250 BRepAdaptor_Curve2d C2d2(E,F2);
251
252 Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED);
253 Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED);
254 Standard_Real f,l,eps;
255 BRep_Tool::Range(E,f,l);
256 Extrema_LocateExtPC ext;
257
258 eps = (l - f) / 100.0;
259 f += eps; // to avoid calculations on
260 l -= eps; // points of pointed squares.
261 gp_Pnt2d p;
262 gp_Pnt pp1,pp2;//,PP;
263 gp_Vec du1, dv1;
264 gp_Vec du2, dv2;
265 gp_Vec d1,d2;
266 Standard_Real norm;
267
268 const Standard_Integer NBPNT = 23;
269 for(Standard_Integer i = 0; i <= NBPNT; i++)
270 {
271 // First suppose that this is sameParameter
272 u = f + (l - f) * i / NBPNT;
273
274 // take derivatives of surfaces at the same u, and compute normals
275 C2d1.D0(u,p);
276 HS1->D1 (p.X(), p.Y(), pp1, du1, dv1);
277 d1 = (du1.Crossed(dv1));
278 norm = d1.Magnitude();
279 if (norm > 1.e-12) d1 /= norm;
280 else continue; // skip degenerated point
281 if(rev1) d1.Reverse();
282
283 C2d2.D0(u,p);
284 HS2->D1 (p.X(), p.Y(), pp2, du2, dv2);
285 d2 = (du2.Crossed(dv2));
286 norm = d2.Magnitude();
287 if (norm > 1.e-12) d2 /= norm;
288 else continue; // skip degenerated point
289 if(rev2) d2.Reverse();
290
291 // Compute angle.
292 Standard_Real aCurrentAng = d1.Angle(d2);
293
294 theResAngle = Max(theResAngle, aCurrentAng);
295 }
296}
297
298//=============================================================================
299// function : ComputeMaxAngleOnShape
300// purpose : Code the regularities on all edges of the shape, boundary of
301// two faces that do not have it.
302//=============================================================================
303static void ComputeMaxAngleOnShape(const TopoDS_Shape& S,
304 Standard_Real& theResAngle)
305{
306 TopTools_IndexedDataMapOfShapeListOfShape M;
307 TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,M);
308 TopTools_ListIteratorOfListOfShape It;
309 TopExp_Explorer Ex;
310 TopoDS_Face F1,F2;
311 Standard_Boolean found, couture;
312 for(Standard_Integer i = 1; i <= M.Extent(); i++)
313 {
314 TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
315 found = Standard_False; couture = Standard_False;
316 F1.Nullify();
317 for(It.Initialize(M.FindFromIndex(i));It.More() && !found;It.Next())
318 {
319 if(F1.IsNull()) { F1 = TopoDS::Face(It.Value()); }
320 else
321 {
322 if(!F1.IsSame(TopoDS::Face(It.Value())))
323 {
324 found = Standard_True;
325 F2 = TopoDS::Face(It.Value());
326 }
327 }
328 }
329 if (!found && !F1.IsNull()){//is it a sewing edge?
330 TopAbs_Orientation orE = E.Orientation();
331 TopoDS_Edge curE;
332 for(Ex.Init(F1,TopAbs_EDGE);Ex.More() && !found;Ex.Next()){
333 curE= TopoDS::Edge(Ex.Current());
334 if(E.IsSame(curE) && orE != curE.Orientation())
335 {
336 found = Standard_True;
337 couture = Standard_True;
338 F2 = F1;
339 }
340 }
341 }
342 if(found)
343 {
344 if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0)
345 {
346 try
347 {
348 tgtfaces(E, F1, F2, couture, theResAngle);
349 }
350 catch(Standard_Failure)
351 {
352 }
353 }
354 }
355 }
356}
357
358//=============================================================================
359//function : ComputeMaxAngle
360//purpose : Computes max angle in faces junction
361//=============================================================================
362void BRepOffset_MakeSimpleOffset::ComputeMaxAngle()
363{
364 ComputeMaxAngleOnShape(myInputShape, myMaxAngle);
365}
366
367//=============================================================================
368//function : BuildMissingWalls
369//purpose : Builds walls to the result solid.
370//=============================================================================
371Standard_Boolean BRepOffset_MakeSimpleOffset::BuildMissingWalls()
372{
373 // Internal list of new faces.
374 TopoDS_Compound aNewFaces;
375 BRep_Builder aBB;
376 aBB.MakeCompound(aNewFaces);
377
378 // Compute outer bounds of original shape.
379 ShapeAnalysis_FreeBounds aFB(myInputShape);
380 const TopoDS_Compound& aFreeWires = aFB.GetClosedWires();
381
382 // Build linear faces on each edge and its image.
383 TopExp_Explorer anExpCW(aFreeWires,TopAbs_WIRE);
384 for(; anExpCW.More() ; anExpCW.Next())
385 {
386 const TopoDS_Wire& aCurWire = TopoDS::Wire(anExpCW.Current());
387
388 // Iterate over outer edges in outer wires.
389 TopExp_Explorer anExpWE(aCurWire, TopAbs_EDGE);
390 for(; anExpWE.More() ; anExpWE.Next())
391 {
392 const TopoDS_Edge& aCurEdge = TopoDS::Edge(anExpWE.Current());
393
394 TopoDS_Face aNewFace = BuildWallFace(aCurEdge);
395
396 if (aNewFace.IsNull())
397 {
398 myError = BRepOffsetSimple_ErrorWallFaceComputation;
399 return Standard_False;
400 }
401
402 aBB.Add(aNewFaces, aNewFace);
403 }
404 }
405
406 // Update edges from wall faces.
407 ShapeFix_Edge aSFE;
408 aSFE.SetContext(myReShape);
409 TopExp_Explorer anExpCE(aNewFaces, TopAbs_EDGE);
410 for ( ; anExpCE.More() ; anExpCE.Next())
411 {
412 // Fix same parameter and same range flags.
413 const TopoDS_Edge& aCurrEdge = TopoDS::Edge(anExpCE.Current());
414 aSFE.FixSameParameter(aCurrEdge);
415 }
416
417 // Update result to be compound.
418 TopoDS_Compound aResCompound;
419 aBB.MakeCompound(aResCompound);
420
421 // Add old faces the result.
422 TopExp_Explorer anExpSF(myInputShape, TopAbs_FACE);
423 for ( ; anExpSF.More() ; anExpSF.Next())
424 aBB.Add(aResCompound, anExpSF.Current());
425
426 // Add new faces the result.
427 anExpSF.Init(myResShape, TopAbs_FACE);
428 for ( ; anExpSF.More() ; anExpSF.Next())
429 aBB.Add(aResCompound, anExpSF.Current());
430
431 // Add wall faces to the result.
432 TopExp_Explorer anExpCF(aNewFaces, TopAbs_FACE);
433 for ( ; anExpCF.More() ; anExpCF.Next())
434 {
435 const TopoDS_Face& aF = TopoDS::Face(anExpCF.Current());
436 aBB.Add(aResCompound, aF);
437 }
438
439 // Apply stored modifications.
440 aResCompound = TopoDS::Compound(myReShape->Apply(aResCompound));
441
442 // Create result shell.
443 BRepTools_Quilt aQuilt;
444 aQuilt.Add(aResCompound);
445 TopoDS_Shape aShells = aQuilt.Shells();
446
447 TopExp_Explorer anExpSSh(aShells, TopAbs_SHELL);
448 TopoDS_Shell aResShell;
449 for ( ; anExpSSh.More() ; anExpSSh.Next() )
450 {
451 if (!aResShell.IsNull())
452 {
453 // Shell is not null -> explorer contains two or more shells.
454 myError = BRepOffsetSimple_ErrorInvalidNbShells;
455 return Standard_False;
456 }
457 aResShell = TopoDS::Shell(anExpSSh.Current());
458 }
459
460 if (!BRep_Tool::IsClosed(aResShell))
461 {
462 myError = BRepOffsetSimple_ErrorNonClosedShell;
463 return Standard_False;
464 }
465
466 // Create result solid.
467 TopoDS_Solid aResSolid;
468 aBB.MakeSolid(aResSolid);
469 aBB.Add(aResSolid, aResShell);
470 myResShape = aResSolid;
471
472 return Standard_True;
473}
474
475//=============================================================================
476//function : BuildWallFace
477//purpose :
478//=============================================================================
479TopoDS_Face BRepOffset_MakeSimpleOffset::BuildWallFace(const TopoDS_Edge& theOrigEdge)
480{
481 TopoDS_Face aResFace;
482
483 // Get offset edge. offset edge is revered to create correct wire.
484 TopoDS_Edge aNewEdge = TopoDS::Edge(myBuilder.ModifiedShape(theOrigEdge));
485 aNewEdge.Orientation(TopAbs_REVERSED);
486
487 TopoDS_Vertex aNewV1, aNewV2;
488 TopExp::Vertices(aNewEdge, aNewV1, aNewV2);
489
490 // Wire contour is:
491 // theOrigEdge (forcible forward) -> wall1 -> aNewEdge (forcible reversed) -> wall2
492 // Firstly it is necessary to create copy of original shape with forward direction.
493 // This simplifies walls creation.
494 TopoDS_Edge anOrigCopy = theOrigEdge;
495 anOrigCopy.Orientation(TopAbs_FORWARD);
496 TopoDS_Vertex aV1, aV2;
497 TopExp::Vertices(anOrigCopy, aV1, aV2);
498
499 // To simplify work with map.
500 TopoDS_Vertex aForwardV1 = TopoDS::Vertex(aV1.Oriented(TopAbs_FORWARD));
501 TopoDS_Vertex aForwardV2 = TopoDS::Vertex(aV2.Oriented(TopAbs_FORWARD));
502
503 // Check existence of edges in stored map: Edge1
504 TopoDS_Edge aWall1;
505 if (myMapVE.IsBound(aForwardV2))
506 {
507 // Edge exists - get it from map.
508 aWall1 = myMapVE(aForwardV2);
509 }
510 else
511 {
512 // Edge does not exist - create it and add to the map.
513 BRepLib_MakeEdge aME1(TopoDS::Vertex(aV2.Oriented(TopAbs_FORWARD)),
514 TopoDS::Vertex(aNewV2.Oriented(TopAbs_REVERSED)));
515 if (!aME1.IsDone())
516 return aResFace;
517 aWall1 = aME1.Edge();
518
519 myMapVE.Bind(aForwardV2, aWall1);
520 }
521
522 // Check existence of edges in stored map: Edge2
523 TopoDS_Edge aWall2;
524 if (myMapVE.IsBound(aForwardV1))
525 {
526 // Edge exists - get it from map.
527 aWall2 = TopoDS::Edge(myMapVE(aForwardV1).Oriented(TopAbs_REVERSED));
528 }
529 else
530 {
531 // Edge does not exist - create it and add to the map.
532 BRepLib_MakeEdge aME2(TopoDS::Vertex(aV1.Oriented(TopAbs_FORWARD)),
533 TopoDS::Vertex(aNewV1.Oriented(TopAbs_REVERSED)));
534 if (!aME2.IsDone())
535 return aResFace;
536 aWall2 = aME2.Edge();
537
538 myMapVE.Bind(aForwardV1, aWall2);
539
540 // Orient it in reversed direction.
541 aWall2.Orientation(TopAbs_REVERSED);
542 }
543
544 BRep_Builder aBB;
545
546 TopoDS_Wire aWire;
547 aBB.MakeWire(aWire);
548 aBB.Add(aWire, anOrigCopy);
549 aBB.Add(aWire, aWall1);
550 aBB.Add(aWire, aNewEdge);
551 aBB.Add(aWire, aWall2);
552
553 // Build 3d curves on wire
554 BRepLib::BuildCurves3d( aWire );
555
556 // Try to build using simple planar approach.
557 TopoDS_Face aF;
558 try
559 {
560 // Call of face maker is wrapped by try/catch since it generates exceptions sometimes.
561 BRepLib_MakeFace aFM(aWire, Standard_True);
562 if (aFM.IsDone())
563 aF = aFM.Face();
564 }
565 catch(Standard_Failure)
566 {
567 }
568
569 if (aF.IsNull()) // Exception in face maker or result is not computed.
570 {
571 // Build using thrusections.
572 Standard_Boolean ToReverse = Standard_False;
573 Standard_Real fpar, lpar, fparOE, lparOE;
574 Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(theOrigEdge, fpar, lpar);
575 Handle(Geom_TrimmedCurve) TrEdgeCurve = new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
576 Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(aNewEdge, fparOE, lparOE);
577 Handle(Geom_TrimmedCurve) TrOffsetCurve = new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
578
579 GeomFill_Generator ThrusecGenerator;
580 ThrusecGenerator.AddCurve( TrEdgeCurve );
581 ThrusecGenerator.AddCurve( TrOffsetCurve );
582 ThrusecGenerator.Perform( Precision::PConfusion() );
583 Handle(Geom_Surface) theSurf = ThrusecGenerator.Surface();
584 //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
585 Standard_Real Uf, Ul, Vf, Vl;
586 theSurf->Bounds(Uf, Ul, Vf, Vl);
587 TopLoc_Location Loc;
588 Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
589 EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
590 aBB.UpdateEdge(theOrigEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
591 OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
592 aBB.UpdateEdge(aNewEdge, OELine2d, theSurf, Loc, Precision::Confusion());
593 Standard_Real UonV1 = (ToReverse)? Ul : Uf;
594 Standard_Real UonV2 = (ToReverse)? Uf : Ul;
595 aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
596 aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
597 if (aWall1.IsSame(aWall2))
598 {
599 aBB.UpdateEdge(aWall1, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
600 Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
601 aBB.UpdateEdge(aWall1, BSplC34, Precision::Confusion());
602 aBB.Range(aWall1, Vf, Vl);
603 }
604 else
605 {
606 aBB.SameParameter(aWall1, Standard_False);
607 aBB.SameRange(aWall1, Standard_False);
608 aBB.SameParameter(aWall2, Standard_False);
609 aBB.SameRange(aWall2, Standard_False);
610 aBB.UpdateEdge(aWall1, aLine2d, theSurf, Loc, Precision::Confusion());
611 aBB.Range(aWall1, theSurf, Loc, Vf, Vl);
612 aBB.UpdateEdge(aWall2, aLine2d2, theSurf, Loc, Precision::Confusion());
613 aBB.Range(aWall2, theSurf, Loc, Vf, Vl);
614 Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
615 aBB.UpdateEdge(aWall1, BSplC3, Precision::Confusion());
616 aBB.Range(aWall1, Vf, Vl, Standard_True); //only for 3d curve
617 Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
618 aBB.UpdateEdge(aWall2, BSplC4, Precision::Confusion());
619 aBB.Range(aWall2, Vf, Vl, Standard_True); //only for 3d curve
620 }
621
622 aF = BRepLib_MakeFace(theSurf, aWire);
623
624 }
625
626 return aF;
627}
628
629//=============================================================================
630//function : Generated
631//purpose :
632//=============================================================================
633const TopoDS_Shape BRepOffset_MakeSimpleOffset::Generated(const TopoDS_Shape& theShape) const
634{
635 // Shape generated by modification.
636 TopoDS_Shape aRes;
637 aRes = myBuilder.ModifiedShape(theShape);
638
639 if (aRes.IsNull())
640 return aRes;
641
642 // Shape modifications obtained in scope of shape healing.
643 aRes = myReShape->Apply(aRes);
644
645 return aRes;
646}
647
648//=============================================================================
649//function : Modified
650//purpose :
651//=============================================================================
652const TopoDS_Shape BRepOffset_MakeSimpleOffset::Modified(const TopoDS_Shape& theShape) const
653{
654 TopoDS_Shape aRes, anEmptyShape;
655
656 // Get modification status and new shape.
657 Standard_Integer aModStatus = myReShape->Status(theShape, aRes);
658
659 if (aModStatus == 0)
660 return anEmptyShape; // No modifications are applied to the shape or its sub-shapes.
661
662 return aRes;
663}
664