diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 44472210ce..bde8a466f5 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1103,3 +1103,28 @@ The following classes have been changed: * The last optional argument *RemoveInvalidFaces* has been removed from the constructor of class *BRepOffset_MakeOffset* and method *Initialize*. * The public method *BOPDS_DS::VerticesOnIn* has been renamed into *SubShapesOnIn* and the new output parameter *theCommonPB* has been added. +@section upgrade_occt720 Upgrade to OCCT 7.2.0 + +@subsection upgrade_occt720_correction_of_Offset_API Corrections in BRepOffset API + +Class *BRepOffsetAPI_MakeOffsetShape*: +* *BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape()* - constructor with parameters has been deleted. +* *BRepOffsetAPI_MakeOffsetShape::PerformByJoin()* - method has been added. This method is old algorithm behaviour. + +The code below shows new calling procedure: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + BRepOffsetAPI_MakeOffsetShape OffsetMaker; + OffsetMaker.PerformByJoin(Shape, OffsetValue, Tolerance); + NewShape = OffsetMaker.Shape(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Class *BRepOffsetAPI_MakeThickSolid*: +* *BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid()* - constructor with parameters has been deleted. +* *BRepOffsetAPI_MakeThickSolid::MakeThickSolidByJoin()* - method has been added. This method is old algorithm behaviour. + +The code below shows new calling procedure: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + BRepOffsetAPI_MakeThickSolid BodyMaker; + BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3); + myBody = BodyMaker.Shape(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/dox/tutorial/tutorial.md b/dox/tutorial/tutorial.md index d13ec101b5..1ce1e895e2 100644 --- a/dox/tutorial/tutorial.md +++ b/dox/tutorial/tutorial.md @@ -484,10 +484,12 @@ The collection for shapes can be found in the *TopTools* package. As *BRepOffset facesToRemove.Append(faceToRemove); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All the necessary data are now available so you can create your hollowed solid by calling the *BRepOffsetAPI_MakeThickSolid* constructor: +All the necessary data are now available so you can create your hollowed solid by calling the *BRepOffsetAPI_MakeThickSolid* MakeThickSolidByJoin method: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} - MyBody = BRepOffsetAPI_MakeThickSolid(myBody, facesToRemove, -myThickness / 50, 1.e-3); + BRepOffsetAPI_MakeThickSolid BodyMaker; + BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3); + myBody = BodyMaker.Shape(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -812,7 +814,9 @@ Complete definition of MakeBottle function (defined in the file src/MakeBottle.c TopTools_ListOfShape facesToRemove; facesToRemove.Append(faceToRemove); - myBody = BRepOffsetAPI_MakeThickSolid(myBody, facesToRemove, -myThickness / 50, 1.e-3); + BRepOffsetAPI_MakeThickSolid BodyMaker; + BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3); + myBody = BodyMaker.Shape(); // Threading : Create Surfaces Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99); Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05); diff --git a/dox/user_guides/modeling_algos/modeling_algos.md b/dox/user_guides/modeling_algos/modeling_algos.md index 86104e9090..09e5971062 100644 --- a/dox/user_guides/modeling_algos/modeling_algos.md +++ b/dox/user_guides/modeling_algos/modeling_algos.md @@ -2100,11 +2100,44 @@ These classes provide the following services: * Creation of tapered shapes using draft angles; * Creation of sweeps. -@subsection occt_modalg_7_1 Shelling +@subsection occt_modalg_7_1 Offset computation + +Offset computation can be performed using *BRepOffsetAPI_MakeOffsetShape*. This class provides API to the two different offset algorithms: + +Offset algorithm based on computation of the analytical continuation. Meaning of the parameters can be found in *BRepOffsetAPI_MakeOffsetShape::PerformByJoin* method description. The list below demonstrates principal scheme of this algorithm: + +* At the first step, the offsets are computed. +* After this, the analytical continuations are computed for each offset. +* Pairwise intersection is computed according to the original topological information (sharing, number of neighbors, etc.). +* The offset shape is assembled. + +The second algorithm is based on the fact that the offset computation for a single face without continuation can always be built. The list below shows simple offset algorithm: +* Each surface is mapped to its geometric offset surface. +* For each edge, pcurves are mapped to the same pcurves on offset surfaces. +* For each edge, 3d curve is constructed by re-approximation of pcurve on the first offset face. +* Position of each vertex in a result shell is computed as average point of all ends of edges sharing that vertex. +* Tolerances are updated according to the resulting geometry. +The possible drawback of the simple algorithm is that it leads, in general case, to tolerance increasing. The tolerances have to grow in order to cover the gaps between the neighbor faces in the output. It should be noted that the actual tolerance growth depends on the offset distance and the quality of joints between the input faces. Anyway the good input shell (smooth connections between adjacent faces) will lead to good result. + +The snippets below show usage examples: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + BRepOffsetAPI_MakeOffsetShape OffsetMaker1; + // Computes offset shape using analytical continuation mechanism. + OffsetMaker1.PerformByJoin(Shape, OffsetValue, Tolerance); + if (OffsetMaker1.IsDone()) + NewShape = OffsetMaker1.Shape(); + + BRepOffsetAPI_MakeOffsetShape OffsetMaker2; + // Computes offset shape using simple algorithm. + OffsetMaker2.PerformBySimple(Shape, OffsetValue); + if (OffsetMaker2.IsDone()) + NewShape = OffsetMaker2.Shape(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@subsection occt_modalg_7_2 Shelling Shelling is used to offset given faces of a solid by a specific value. It rounds or intersects adjacent faces along its edges depending on the convexity of the edge. - -The constructor *BRepOffsetAPI_MakeThickSolid* shelling operator takes the solid, the list of faces to remove and an offset value as input. +The MakeThickSolidByJoin method of the *BRepOffsetAPI_MakeThickSolid* takes the solid, the list of faces to remove and an offset value as input. ~~~~~ TopoDS_Solid SolidInitial = ...; @@ -2119,17 +2152,28 @@ for (Standard_Integer i = 1 ;i <= n; i++) { LCF.Append(SF); } -Result = BRepOffsetAPI_MakeThickSolid (SolidInitial, - LCF, - Of, - Tol); +BRepOffsetAPI_MakeThickSolid SolidMaker; +SolidMaker.MakeThickSolidByJoin(SolidInitial, + LCF, + Of, + Tol); +if (SolidMaker.IsDone()) + Result = SolidMaker.Shape(); ~~~~~ @image html /user_guides/modeling_algos/images/modeling_algos_image042.png "Shelling" @image latex /user_guides/modeling_algos/images/modeling_algos_image042.png "Shelling" +Also it is possible to create solid between shell, offset shell. This functionality can be called using *BRepOffsetAPI_MakeThickSolid::MakeThickSolidBySimple* method. The code below shows usage example: -@subsection occt_modalg_7_2 Draft Angle +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp} + BRepOffsetAPI_MakeThickSolid SolidMaker; + SolidMaker.MakeThickSolidBySimple(Shell, OffsetValue); + if (myDone.IsDone()) + Solid = SolidMaker.Shape(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@subsection occt_modalg_7_3 Draft Angle *BRepOffsetAPI_DraftAngle* class allows modifying a shape by applying draft angles to its planar, cylindrical and conical faces. @@ -2182,7 +2226,7 @@ else { @image html /user_guides/modeling_algos/images/modeling_algos_image043.png "DraftAngle" @image latex /user_guides/modeling_algos/images/modeling_algos_image043.png "DraftAngle" -@subsection occt_modalg_7_3 Pipe Constructor +@subsection occt_modalg_7_4 Pipe Constructor *BRepOffsetAPI_MakePipe* class allows creating a pipe from a Spine, which is a Wire and a Profile which is a Shape. This implementation is limited to spines with smooth transitions, sharp transitions are precessed by *BRepOffsetAPI_MakePipeShell*. To be more precise the continuity must be G1, which means that the tangent must have the same direction, though not necessarily the same magnitude, at neighboring edges. @@ -2197,7 +2241,7 @@ TopoDS_Shape Pipe = BRepOffsetAPI_MakePipe(Spine,Profile); @image html /user_guides/modeling_algos/images/modeling_algos_image044.png "Example of a Pipe" @image latex /user_guides/modeling_algos/images/modeling_algos_image044.png "Example of a Pipe" -@subsection occt_modalg_7_4 Evolved Solid +@subsection occt_modalg_7_5 Evolved Solid *BRepOffsetAPI_MakeEvolved* class allows creating an evolved solid from a Spine (planar face or wire) and a profile (wire). diff --git a/samples/mfc/standard/02_Modeling/src/ModelingDoc.cpp b/samples/mfc/standard/02_Modeling/src/ModelingDoc.cpp index 7db68448ec..a6529e3590 100755 --- a/samples/mfc/standard/02_Modeling/src/ModelingDoc.cpp +++ b/samples/mfc/standard/02_Modeling/src/ModelingDoc.cpp @@ -2558,8 +2558,10 @@ void CModelingDoc::OnThickLocal() Ex.Next(); //this is the front face TopoDS_Shape aFace = Ex.Current(); aList.Append(aFace); - - TopoDS_Shape aThickSolid = BRepOffsetAPI_MakeThickSolid(S1,aList,10,0.01); + + BRepOffsetAPI_MakeThickSolid aSolidMaker; + aSolidMaker.MakeThickSolidByJoin(S1,aList,10,0.01); + TopoDS_Shape aThickSolid = aSolidMaker.Shape(); Handle(AIS_Shape) ais1 = new AIS_Shape(aThickSolid); myAISContext->SetColor(ais1,Quantity_NOC_RED,Standard_False); @@ -2607,7 +2609,9 @@ void CModelingDoc::OnOffsetLocal() Fit(); Sleep(500); - TopoDS_Shape anOffsetShape1 = BRepOffsetAPI_MakeOffsetShape(S1,60,0.01); + BRepOffsetAPI_MakeOffsetShape aShapeMaker1; + aShapeMaker1.PerformByJoin(S1,60,0.01); + TopoDS_Shape anOffsetShape1 = aShapeMaker1.Shape(); Handle(AIS_Shape) ais1 = new AIS_Shape(anOffsetShape1); myAISContext->SetColor(ais1,Quantity_NOC_MATRABLUE,Standard_False); @@ -2627,8 +2631,10 @@ void CModelingDoc::OnOffsetLocal() Fit(); Sleep(500); - TopoDS_Shape anOffsetShape2 = BRepOffsetAPI_MakeOffsetShape(S2,-40,0.01, - BRepOffset_Skin,Standard_False,Standard_False,GeomAbs_Arc); + BRepOffsetAPI_MakeOffsetShape aShapeMaker2; + aShapeMaker2.PerformByJoin(S2,-40,0.01, + BRepOffset_Skin,Standard_False,Standard_False,GeomAbs_Arc); + TopoDS_Shape anOffsetShape2 = aShapeMaker2.Shape(); Handle(AIS_Shape) ais2 = new AIS_Shape(anOffsetShape2); myAISContext->SetColor(ais2,Quantity_NOC_MATRABLUE); diff --git a/samples/qt/Tutorial/src/MakeBottle.cxx b/samples/qt/Tutorial/src/MakeBottle.cxx index d965af3f21..c89b96df84 100755 --- a/samples/qt/Tutorial/src/MakeBottle.cxx +++ b/samples/qt/Tutorial/src/MakeBottle.cxx @@ -140,7 +140,9 @@ MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight, TopTools_ListOfShape facesToRemove; facesToRemove.Append(faceToRemove); - myBody = BRepOffsetAPI_MakeThickSolid(myBody, facesToRemove, -myThickness / 50, 1.e-3); + BRepOffsetAPI_MakeThickSolid aSolidMaker; + aSolidMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3); + myBody = aSolidMaker.Shape(); // Threading : Create Surfaces Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99); Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05); diff --git a/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx b/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx new file mode 100644 index 0000000000..3b89a5a92d --- /dev/null +++ b/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx @@ -0,0 +1,661 @@ +// Created on: 2016-10-13 +// Created by: Alexander MALYSHEV +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Include self. +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//============================================================================= +//function : BRepOffset_MakeSimpleOffset +//purpose : Constructor +//============================================================================= +BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset() +: myIsBuildSolid(Standard_False), + myMaxAngle(0.0), + myError(BRepOffsetSimple_OK), + myIsDone(Standard_False) +{ + myReShape = new ShapeBuild_ReShape(); +} + +//============================================================================= +//function : BRepOffset_MakeSimpleOffset +//purpose : Constructor +//============================================================================= +BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue) +: myInputShape(theInputShape), + myOffsetValue(theOffsetValue), + myIsBuildSolid(Standard_False), + myMaxAngle(0.0), + myError(BRepOffsetSimple_OK), + myIsDone(Standard_False) +{ + myReShape = new ShapeBuild_ReShape(); +} + +//============================================================================= +//function : Initialize +//purpose : +//============================================================================= +void BRepOffset_MakeSimpleOffset::Initialize(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue) +{ + myInputShape = theInputShape; + myOffsetValue = theOffsetValue; + Clear(); +} + +//============================================================================= +//function : GetErrorMessage +//purpose : +//============================================================================= +TCollection_AsciiString BRepOffset_MakeSimpleOffset::GetErrorMessage() const +{ + TCollection_AsciiString anError = ""; + + if (myError == BRepOffsetSimple_NullInputShape) + { + anError = "Null input shape"; + return anError; + } + else if (myError == BRepOffsetSimple_ErrorOffsetComputation) + { + anError = "Error during offset construction"; + return anError; + } + else if (myError == BRepOffsetSimple_ErrorWallFaceComputation) + { + anError = "Error during building wall face"; + return anError; + } + else if (myError == BRepOffsetSimple_ErrorInvalidNbShells) + { + anError = "Result contains two or more shells"; + return anError; + } + else if (myError == BRepOffsetSimple_ErrorNonClosedShell) + { + anError = "Result shell is not closed"; + return anError; + } + + return anError; +} + +//============================================================================= +//function : Clear +//purpose : +//============================================================================= +void BRepOffset_MakeSimpleOffset::Clear() +{ + myIsDone = Standard_False; + myError = BRepOffsetSimple_OK; + myMaxAngle = 0.0; + myMapVE.Clear(); + myReShape->Clear(); // Clear possible stored modifications. +} + +//============================================================================= +//function : GetSafeOffset +//purpose : +//============================================================================= +Standard_Real BRepOffset_MakeSimpleOffset::GetSafeOffset(const Standard_Real theExpectedToler) +{ + if (myInputShape.IsNull()) + return 0.0; // Input shape is null. + + // Compute max angle in faces junctions. + if (myMaxAngle == 0.0) // Non-initialized. + ComputeMaxAngle(); + + Standard_Real aMaxTol = 0.0; + aMaxTol = BRep_Tool::MaxTolerance(myInputShape, TopAbs_VERTEX); + + const Standard_Real anExpOffset = Max((theExpectedToler - aMaxTol) / (2.0 * myMaxAngle), + 0.0); // Minimal distance can't be lower than 0.0. + return anExpOffset; +} + +//============================================================================= +//function : Perform +//purpose : +//============================================================================= +void BRepOffset_MakeSimpleOffset::Perform() +{ + // Clear result of previous computations. + Clear(); + + // Check shape existence. + if (myInputShape.IsNull()) + { + myError = BRepOffsetSimple_NullInputShape; + return; + } + + if (myMaxAngle == 0.0) // Non-initialized. + ComputeMaxAngle(); + + myBuilder.Init(myInputShape); + Handle(BRepOffset_SimpleOffset) aMapper = new BRepOffset_SimpleOffset(myInputShape, myOffsetValue); + myBuilder.Perform(aMapper); + + if (!myBuilder.IsDone()) + { + myError = BRepOffsetSimple_ErrorOffsetComputation; + return; + } + + myResShape = myBuilder.ModifiedShape(myInputShape); + + // Fix degeneracy. Degenerated edge should be mapped to the degenerated. + BRep_Builder aBB; + TopExp_Explorer anExpSE(myInputShape, TopAbs_EDGE); + for(; anExpSE.More(); anExpSE.Next()) + { + const TopoDS_Edge & aCurrEdge = TopoDS::Edge(anExpSE.Current()); + + if (!BRep_Tool::Degenerated(aCurrEdge)) + continue; + + const TopoDS_Edge & anEdge = TopoDS::Edge(myBuilder.ModifiedShape(aCurrEdge)); + aBB.Degenerated(anEdge, Standard_True); + } + + // Restore walls for solid. + if (myIsBuildSolid && !BuildMissingWalls()) + return; + + myIsDone = Standard_True; +} + +//============================================================================= +//function : tgtfaces +//purpose : check the angle at the border between two squares. +// Two shares should have a shared front edge. +//============================================================================= +static void tgtfaces(const TopoDS_Edge& Ed, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Boolean couture, + Standard_Real& theResAngle) +{ + // Check that pcurves exist on both faces of edge. + Standard_Real aFirst,aLast; + Handle(Geom2d_Curve) aCurve; + aCurve = BRep_Tool::CurveOnSurface(Ed,F1,aFirst,aLast); + if(aCurve.IsNull()) + return; + aCurve = BRep_Tool::CurveOnSurface(Ed,F2,aFirst,aLast); + if(aCurve.IsNull()) + return; + + Standard_Real u; + TopoDS_Edge E = Ed; + BRepAdaptor_Surface aBAS1(F1,Standard_False); + BRepAdaptor_Surface aBAS2(F2,Standard_False); + + Handle(BRepAdaptor_HSurface) HS1 = new BRepAdaptor_HSurface (aBAS1); + Handle(BRepAdaptor_HSurface) HS2; + if(couture) HS2 = HS1; + else HS2 = new BRepAdaptor_HSurface(aBAS2); + //case when edge lies on the one face + + E.Orientation(TopAbs_FORWARD); + BRepAdaptor_Curve2d C2d1(E, F1); + if(couture) E.Orientation(TopAbs_REVERSED); + BRepAdaptor_Curve2d C2d2(E,F2); + + Standard_Boolean rev1 = (F1.Orientation() == TopAbs_REVERSED); + Standard_Boolean rev2 = (F2.Orientation() == TopAbs_REVERSED); + Standard_Real f,l,eps; + BRep_Tool::Range(E,f,l); + Extrema_LocateExtPC ext; + + eps = (l - f) / 100.0; + f += eps; // to avoid calculations on + l -= eps; // points of pointed squares. + gp_Pnt2d p; + gp_Pnt pp1,pp2;//,PP; + gp_Vec du1, dv1; + gp_Vec du2, dv2; + gp_Vec d1,d2; + Standard_Real norm; + + const Standard_Integer NBPNT = 23; + for(Standard_Integer i = 0; i <= NBPNT; i++) + { + // First suppose that this is sameParameter + u = f + (l - f) * i / NBPNT; + + // take derivatives of surfaces at the same u, and compute normals + C2d1.D0(u,p); + HS1->D1 (p.X(), p.Y(), pp1, du1, dv1); + d1 = (du1.Crossed(dv1)); + norm = d1.Magnitude(); + if (norm > 1.e-12) d1 /= norm; + else continue; // skip degenerated point + if(rev1) d1.Reverse(); + + C2d2.D0(u,p); + HS2->D1 (p.X(), p.Y(), pp2, du2, dv2); + d2 = (du2.Crossed(dv2)); + norm = d2.Magnitude(); + if (norm > 1.e-12) d2 /= norm; + else continue; // skip degenerated point + if(rev2) d2.Reverse(); + + // Compute angle. + Standard_Real aCurrentAng = d1.Angle(d2); + + theResAngle = Max(theResAngle, aCurrentAng); + } +} + +//============================================================================= +// function : ComputeMaxAngleOnShape +// purpose : Code the regularities on all edges of the shape, boundary of +// two faces that do not have it. +//============================================================================= +static void ComputeMaxAngleOnShape(const TopoDS_Shape& S, + Standard_Real& theResAngle) +{ + TopTools_IndexedDataMapOfShapeListOfShape M; + TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,M); + TopTools_ListIteratorOfListOfShape It; + TopExp_Explorer Ex; + TopoDS_Face F1,F2; + Standard_Boolean found, couture; + for(Standard_Integer i = 1; i <= M.Extent(); i++) + { + TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); + found = Standard_False; couture = Standard_False; + F1.Nullify(); + for(It.Initialize(M.FindFromIndex(i));It.More() && !found;It.Next()) + { + if(F1.IsNull()) { F1 = TopoDS::Face(It.Value()); } + else + { + if(!F1.IsSame(TopoDS::Face(It.Value()))) + { + found = Standard_True; + F2 = TopoDS::Face(It.Value()); + } + } + } + if (!found && !F1.IsNull()){//is it a sewing edge? + TopAbs_Orientation orE = E.Orientation(); + TopoDS_Edge curE; + for(Ex.Init(F1,TopAbs_EDGE);Ex.More() && !found;Ex.Next()){ + curE= TopoDS::Edge(Ex.Current()); + if(E.IsSame(curE) && orE != curE.Orientation()) + { + found = Standard_True; + couture = Standard_True; + F2 = F1; + } + } + } + if(found) + { + if(BRep_Tool::Continuity(E,F1,F2)<=GeomAbs_C0) + { + try + { + tgtfaces(E, F1, F2, couture, theResAngle); + } + catch(Standard_Failure) + { + } + } + } + } +} + +//============================================================================= +//function : ComputeMaxAngle +//purpose : Computes max angle in faces junction +//============================================================================= +void BRepOffset_MakeSimpleOffset::ComputeMaxAngle() +{ + ComputeMaxAngleOnShape(myInputShape, myMaxAngle); +} + +//============================================================================= +//function : BuildMissingWalls +//purpose : Builds walls to the result solid. +//============================================================================= +Standard_Boolean BRepOffset_MakeSimpleOffset::BuildMissingWalls() +{ + // Internal list of new faces. + TopoDS_Compound aNewFaces; + BRep_Builder aBB; + aBB.MakeCompound(aNewFaces); + + // Compute outer bounds of original shape. + ShapeAnalysis_FreeBounds aFB(myInputShape); + const TopoDS_Compound& aFreeWires = aFB.GetClosedWires(); + + // Build linear faces on each edge and its image. + TopExp_Explorer anExpCW(aFreeWires,TopAbs_WIRE); + for(; anExpCW.More() ; anExpCW.Next()) + { + const TopoDS_Wire& aCurWire = TopoDS::Wire(anExpCW.Current()); + + // Iterate over outer edges in outer wires. + TopExp_Explorer anExpWE(aCurWire, TopAbs_EDGE); + for(; anExpWE.More() ; anExpWE.Next()) + { + const TopoDS_Edge& aCurEdge = TopoDS::Edge(anExpWE.Current()); + + TopoDS_Face aNewFace = BuildWallFace(aCurEdge); + + if (aNewFace.IsNull()) + { + myError = BRepOffsetSimple_ErrorWallFaceComputation; + return Standard_False; + } + + aBB.Add(aNewFaces, aNewFace); + } + } + + // Update edges from wall faces. + ShapeFix_Edge aSFE; + aSFE.SetContext(myReShape); + TopExp_Explorer anExpCE(aNewFaces, TopAbs_EDGE); + for ( ; anExpCE.More() ; anExpCE.Next()) + { + // Fix same parameter and same range flags. + const TopoDS_Edge& aCurrEdge = TopoDS::Edge(anExpCE.Current()); + aSFE.FixSameParameter(aCurrEdge); + } + + // Update result to be compound. + TopoDS_Compound aResCompound; + aBB.MakeCompound(aResCompound); + + // Add old faces the result. + TopExp_Explorer anExpSF(myInputShape, TopAbs_FACE); + for ( ; anExpSF.More() ; anExpSF.Next()) + aBB.Add(aResCompound, anExpSF.Current()); + + // Add new faces the result. + anExpSF.Init(myResShape, TopAbs_FACE); + for ( ; anExpSF.More() ; anExpSF.Next()) + aBB.Add(aResCompound, anExpSF.Current()); + + // Add wall faces to the result. + TopExp_Explorer anExpCF(aNewFaces, TopAbs_FACE); + for ( ; anExpCF.More() ; anExpCF.Next()) + { + const TopoDS_Face& aF = TopoDS::Face(anExpCF.Current()); + aBB.Add(aResCompound, aF); + } + + // Apply stored modifications. + aResCompound = TopoDS::Compound(myReShape->Apply(aResCompound)); + + // Create result shell. + BRepTools_Quilt aQuilt; + aQuilt.Add(aResCompound); + TopoDS_Shape aShells = aQuilt.Shells(); + + TopExp_Explorer anExpSSh(aShells, TopAbs_SHELL); + TopoDS_Shell aResShell; + for ( ; anExpSSh.More() ; anExpSSh.Next() ) + { + if (!aResShell.IsNull()) + { + // Shell is not null -> explorer contains two or more shells. + myError = BRepOffsetSimple_ErrorInvalidNbShells; + return Standard_False; + } + aResShell = TopoDS::Shell(anExpSSh.Current()); + } + + if (!BRep_Tool::IsClosed(aResShell)) + { + myError = BRepOffsetSimple_ErrorNonClosedShell; + return Standard_False; + } + + // Create result solid. + TopoDS_Solid aResSolid; + aBB.MakeSolid(aResSolid); + aBB.Add(aResSolid, aResShell); + myResShape = aResSolid; + + return Standard_True; +} + +//============================================================================= +//function : BuildWallFace +//purpose : +//============================================================================= +TopoDS_Face BRepOffset_MakeSimpleOffset::BuildWallFace(const TopoDS_Edge& theOrigEdge) +{ + TopoDS_Face aResFace; + + // Get offset edge. offset edge is revered to create correct wire. + TopoDS_Edge aNewEdge = TopoDS::Edge(myBuilder.ModifiedShape(theOrigEdge)); + aNewEdge.Orientation(TopAbs_REVERSED); + + TopoDS_Vertex aNewV1, aNewV2; + TopExp::Vertices(aNewEdge, aNewV1, aNewV2); + + // Wire contour is: + // theOrigEdge (forcible forward) -> wall1 -> aNewEdge (forcible reversed) -> wall2 + // Firstly it is necessary to create copy of original shape with forward direction. + // This simplifies walls creation. + TopoDS_Edge anOrigCopy = theOrigEdge; + anOrigCopy.Orientation(TopAbs_FORWARD); + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(anOrigCopy, aV1, aV2); + + // To simplify work with map. + TopoDS_Vertex aForwardV1 = TopoDS::Vertex(aV1.Oriented(TopAbs_FORWARD)); + TopoDS_Vertex aForwardV2 = TopoDS::Vertex(aV2.Oriented(TopAbs_FORWARD)); + + // Check existence of edges in stored map: Edge1 + TopoDS_Edge aWall1; + if (myMapVE.IsBound(aForwardV2)) + { + // Edge exists - get it from map. + aWall1 = myMapVE(aForwardV2); + } + else + { + // Edge does not exist - create it and add to the map. + BRepLib_MakeEdge aME1(TopoDS::Vertex(aV2.Oriented(TopAbs_FORWARD)), + TopoDS::Vertex(aNewV2.Oriented(TopAbs_REVERSED))); + if (!aME1.IsDone()) + return aResFace; + aWall1 = aME1.Edge(); + + myMapVE.Bind(aForwardV2, aWall1); + } + + // Check existence of edges in stored map: Edge2 + TopoDS_Edge aWall2; + if (myMapVE.IsBound(aForwardV1)) + { + // Edge exists - get it from map. + aWall2 = TopoDS::Edge(myMapVE(aForwardV1).Oriented(TopAbs_REVERSED)); + } + else + { + // Edge does not exist - create it and add to the map. + BRepLib_MakeEdge aME2(TopoDS::Vertex(aV1.Oriented(TopAbs_FORWARD)), + TopoDS::Vertex(aNewV1.Oriented(TopAbs_REVERSED))); + if (!aME2.IsDone()) + return aResFace; + aWall2 = aME2.Edge(); + + myMapVE.Bind(aForwardV1, aWall2); + + // Orient it in reversed direction. + aWall2.Orientation(TopAbs_REVERSED); + } + + BRep_Builder aBB; + + TopoDS_Wire aWire; + aBB.MakeWire(aWire); + aBB.Add(aWire, anOrigCopy); + aBB.Add(aWire, aWall1); + aBB.Add(aWire, aNewEdge); + aBB.Add(aWire, aWall2); + + // Build 3d curves on wire + BRepLib::BuildCurves3d( aWire ); + + // Try to build using simple planar approach. + TopoDS_Face aF; + try + { + // Call of face maker is wrapped by try/catch since it generates exceptions sometimes. + BRepLib_MakeFace aFM(aWire, Standard_True); + if (aFM.IsDone()) + aF = aFM.Face(); + } + catch(Standard_Failure) + { + } + + if (aF.IsNull()) // Exception in face maker or result is not computed. + { + // Build using thrusections. + Standard_Boolean ToReverse = Standard_False; + Standard_Real fpar, lpar, fparOE, lparOE; + Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(theOrigEdge, fpar, lpar); + Handle(Geom_TrimmedCurve) TrEdgeCurve = new Geom_TrimmedCurve( EdgeCurve, fpar, lpar ); + Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(aNewEdge, fparOE, lparOE); + Handle(Geom_TrimmedCurve) TrOffsetCurve = new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE ); + + GeomFill_Generator ThrusecGenerator; + ThrusecGenerator.AddCurve( TrEdgeCurve ); + ThrusecGenerator.AddCurve( TrOffsetCurve ); + ThrusecGenerator.Perform( Precision::PConfusion() ); + Handle(Geom_Surface) theSurf = ThrusecGenerator.Surface(); + //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir ); + Standard_Real Uf, Ul, Vf, Vl; + theSurf->Bounds(Uf, Ul, Vf, Vl); + TopLoc_Location Loc; + Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2; + EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.)); + aBB.UpdateEdge(theOrigEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion()); + OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.)); + aBB.UpdateEdge(aNewEdge, OELine2d, theSurf, Loc, Precision::Confusion()); + Standard_Real UonV1 = (ToReverse)? Ul : Uf; + Standard_Real UonV2 = (ToReverse)? Uf : Ul; + aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.)); + aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.)); + if (aWall1.IsSame(aWall2)) + { + aBB.UpdateEdge(aWall1, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion()); + Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf ); + aBB.UpdateEdge(aWall1, BSplC34, Precision::Confusion()); + aBB.Range(aWall1, Vf, Vl); + } + else + { + aBB.SameParameter(aWall1, Standard_False); + aBB.SameRange(aWall1, Standard_False); + aBB.SameParameter(aWall2, Standard_False); + aBB.SameRange(aWall2, Standard_False); + aBB.UpdateEdge(aWall1, aLine2d, theSurf, Loc, Precision::Confusion()); + aBB.Range(aWall1, theSurf, Loc, Vf, Vl); + aBB.UpdateEdge(aWall2, aLine2d2, theSurf, Loc, Precision::Confusion()); + aBB.Range(aWall2, theSurf, Loc, Vf, Vl); + Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 ); + aBB.UpdateEdge(aWall1, BSplC3, Precision::Confusion()); + aBB.Range(aWall1, Vf, Vl, Standard_True); //only for 3d curve + Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 ); + aBB.UpdateEdge(aWall2, BSplC4, Precision::Confusion()); + aBB.Range(aWall2, Vf, Vl, Standard_True); //only for 3d curve + } + + aF = BRepLib_MakeFace(theSurf, aWire); + + } + + return aF; +} + +//============================================================================= +//function : Generated +//purpose : +//============================================================================= +const TopoDS_Shape BRepOffset_MakeSimpleOffset::Generated(const TopoDS_Shape& theShape) const +{ + // Shape generated by modification. + TopoDS_Shape aRes; + aRes = myBuilder.ModifiedShape(theShape); + + if (aRes.IsNull()) + return aRes; + + // Shape modifications obtained in scope of shape healing. + aRes = myReShape->Apply(aRes); + + return aRes; +} + +//============================================================================= +//function : Modified +//purpose : +//============================================================================= +const TopoDS_Shape BRepOffset_MakeSimpleOffset::Modified(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape aRes, anEmptyShape; + + // Get modification status and new shape. + Standard_Integer aModStatus = myReShape->Status(theShape, aRes); + + if (aModStatus == 0) + return anEmptyShape; // No modifications are applied to the shape or its sub-shapes. + + return aRes; +} + diff --git a/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx b/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx new file mode 100644 index 0000000000..83d3fc2b8a --- /dev/null +++ b/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx @@ -0,0 +1,168 @@ +// Created on: 2016-10-13 +// Created by: Alexander MALYSHEV +// Copyright (c) 1999-2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepOffset_MakeSimpleOffset_HeaderFile +#define _BRepOffset_MakeSimpleOffset_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +enum BRepOffsetSimple_Status +{ + BRepOffsetSimple_OK, + BRepOffsetSimple_NullInputShape, + BRepOffsetSimple_ErrorOffsetComputation, + BRepOffsetSimple_ErrorWallFaceComputation, + BRepOffsetSimple_ErrorInvalidNbShells, + BRepOffsetSimple_ErrorNonClosedShell +}; + +//! This class represents simple offset algorithm itself. It builds simple offset without intersection. +//! Solid can be created using SetBuildSolidFlag method (set flag to true). By default shell will be constructed. +//! +//! Algorithm: +//! 1. Build source-image maps for vertices, edges and faces.BRepTools_Modification class will be used +//! to store this information. An image of a shared edge can be constructed from the corresponding edge +//! of the first iterated face. +//! 2. Run BRepTools_Modifier to obtain offset shape. +// 3. Ensure topological integrity of the output shape. +//! +//! Limitations: +//! According to the algorithm nature result depends on the smoothness of input data. Smooth (G1-continuity) input shape +//! will lead to the good result. +//! +//! The possible drawback of the simple algorithm is that it leads, in general case, to tolerance increasing. +//! The tolerances have to grow in order to cover the gaps between the neighbor faces in the output. +//! It should be noted that the actual tolerance growth depends on the offset distance and the quality of +//! joints between the input faces. Anyway the good input shell (smooth connections between adjacent faces) +//! will lead to good result. +class BRepOffset_MakeSimpleOffset +{ +public: + + + //! Constructor. Does nothing. + Standard_EXPORT BRepOffset_MakeSimpleOffset(); + + //! Constructor. + Standard_EXPORT BRepOffset_MakeSimpleOffset(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue); + + //! Initialies shape for modifications. + Standard_EXPORT void Initialize(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue); + + //! Computes offset shape. + Standard_EXPORT void Perform(); + + //! Gets error message. + Standard_EXPORT TCollection_AsciiString GetErrorMessage() const; + + //! Gets error code. + BRepOffsetSimple_Status GetError() const { return myError; } + + // Inline methods. + //! Gets solid building flag. + Standard_Boolean GetBuildSolidFlag() const { return myIsBuildSolid; } + + //! Sets solid building flag. + void SetBuildSolidFlag(const Standard_Boolean theBuildFlag) { myIsBuildSolid = theBuildFlag; } + + //! Gets offset value. + Standard_Real GetOffsetValue() const { return myOffsetValue; } + + //! Sets offset value. + void SetOffsetValue(const Standard_Real theOffsetValue) { myOffsetValue = theOffsetValue; } + + //! Gets done state. + Standard_Boolean IsDone() const { return myIsDone; } + + //! Returns result shape. + const TopoDS_Shape& GetResultShape() const { return myResShape; } + + //! Computes max safe offset value for the given tolerance. + Standard_Real GetSafeOffset(const Standard_Real theExpectedToler); + + //! Returnes result shape for the given one (if exists). + Standard_EXPORT const TopoDS_Shape Generated(const TopoDS_Shape& theShape) const; + + //! Returnes modified shape for the given one (if exists). + Standard_EXPORT const TopoDS_Shape Modified(const TopoDS_Shape& theShape) const; + +protected: + + //! Computes max angle in faces junction. + void ComputeMaxAngle(); + + //! Clears previous result. + void Clear(); + +private: + + //! Builds face on specified wall. + TopoDS_Face BuildWallFace(const TopoDS_Edge& theOrigEdge); + + //! Builds missing walls. + Standard_Boolean BuildMissingWalls(); + + // Input data. + + //! Input shape. + TopoDS_Shape myInputShape; + + //! Offset value. + Standard_Real myOffsetValue; + + //! Solid building flag. True means solid construction. + Standard_Boolean myIsBuildSolid; + + // Internal data. + + //! Maximal angle in faces junction. This value helps to estimate result tolerance. + Standard_Real myMaxAngle; + + //! Error message. + BRepOffsetSimple_Status myError; + + //! Done state. + Standard_Boolean myIsDone; + + //! Map of vertex - wall edge. + //! Used to build shared edge between adjacent wall faces. + NCollection_DataMap myMapVE; + + //! Used for histrory support. + BRepTools_Modifier myBuilder; + + //! Used for history support. + Handle(ShapeBuild_ReShape) myReShape; + + // Output data. + + //! Result shape. + TopoDS_Shape myResShape; + +}; + +#endif // _BRepOffset_MakeSimpleOffset_HeaderFile diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.cxx b/src/BRepOffset/BRepOffset_SimpleOffset.cxx new file mode 100644 index 0000000000..a02fcccc60 --- /dev/null +++ b/src/BRepOffset/BRepOffset_SimpleOffset.cxx @@ -0,0 +1,413 @@ +// Created on: 2016-10-14 +// Created by: Alexander MALYSHEV +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +// Include self. +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const Standard_Integer NCONTROL=22; + + +//============================================================================= +//function : BRepOffset_SimpleOffset +//purpose : Constructor +//============================================================================= +BRepOffset_SimpleOffset::BRepOffset_SimpleOffset(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue) +: myOffsetValue(theOffsetValue) +{ + FillOffsetData(theInputShape); +} + +//============================================================================= +//function : NewSurface +//purpose : +//============================================================================= +Standard_Boolean BRepOffset_SimpleOffset::NewSurface(const TopoDS_Face& F, + Handle(Geom_Surface)& S, + TopLoc_Location& L, + Standard_Real& Tol, + Standard_Boolean& RevWires, + Standard_Boolean& RevFace) +{ + if (!myFaceInfo.IsBound(F)) + return Standard_False; + + const NewFaceData& aNFD = myFaceInfo.Find(F); + + S = aNFD.myOffsetS; + L = aNFD.myL; + Tol = aNFD.myTol; + RevWires = aNFD.myRevWires; + RevFace = aNFD.myRevFace; + + return Standard_True; +} + +//============================================================================= +//function : NewCurve +//purpose : +//============================================================================= +Standard_Boolean BRepOffset_SimpleOffset::NewCurve(const TopoDS_Edge& E, + Handle(Geom_Curve)& C, + TopLoc_Location& L, + Standard_Real& Tol) +{ + if (!myEdgeInfo.IsBound(E)) + return Standard_False; + + const NewEdgeData& aNED = myEdgeInfo.Find(E); + + C = aNED.myOffsetC; + L = aNED.myL; + Tol = aNED.myTol; + + return Standard_True; +} + +//============================================================================= +//function : NewPoint +//purpose : +//============================================================================= +Standard_Boolean BRepOffset_SimpleOffset::NewPoint (const TopoDS_Vertex& V, + gp_Pnt& P, + Standard_Real& Tol) +{ + if (!myVertexInfo.IsBound(V)) + return Standard_False; + + const NewVertexData& aNVD = myVertexInfo.Find(V); + + P = aNVD.myP; + Tol = aNVD.myTol; + + return Standard_True; +} + +//============================================================================= +//function : NewCurve2d +//purpose : +//============================================================================= +Standard_Boolean BRepOffset_SimpleOffset::NewCurve2d (const TopoDS_Edge& E, + const TopoDS_Face& F, + const TopoDS_Edge& /*NewE*/, + const TopoDS_Face& /*NewF*/, + Handle(Geom2d_Curve)& C, + Standard_Real& Tol) +{ + // Use original pcurve. + Standard_Real aF, aL; + C = BRep_Tool::CurveOnSurface(E, F, aF, aL); + Tol = BRep_Tool::Tolerance(E); + + if (myEdgeInfo.IsBound(E)) + Tol = myEdgeInfo.Find(E).myTol; + + return Standard_True; +} + +//============================================================================= +//function : NewParameter +//purpose : +//============================================================================= +Standard_Boolean BRepOffset_SimpleOffset::NewParameter (const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& P, + Standard_Real& Tol) +{ + // Use original parameter. + P = BRep_Tool::Parameter(V, E); + Tol = BRep_Tool::Tolerance(V); + + if (myVertexInfo.IsBound(V)) + Tol = myVertexInfo.Find(V).myTol; + + return Standard_True; +} + +//============================================================================= +//function : NewParameter +//purpose : +//============================================================================= +GeomAbs_Shape BRepOffset_SimpleOffset::Continuity (const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const TopoDS_Edge& /*NewE*/, + const TopoDS_Face& /*NewF1*/, + const TopoDS_Face& /*NewF2*/) +{ + // Compute result using original continuity. + return BRep_Tool::Continuity(E, F1, F2); +} + +//============================================================================= +//function : FillOffsetData +//purpose : +//============================================================================= +void BRepOffset_SimpleOffset::FillOffsetData(const TopoDS_Shape& theShape) +{ + // Clears old data. + myFaceInfo.Clear(); + myEdgeInfo.Clear(); + myVertexInfo.Clear(); + + // Faces loop. Compute offset surface for each face. + TopExp_Explorer anExpSF(theShape, TopAbs_FACE); + for(; anExpSF.More(); anExpSF.Next()) + { + const TopoDS_Face& aCurrFace = TopoDS::Face(anExpSF.Current()); + FillFaceData(aCurrFace); + } + + // Iterate over edges to compute 3d curve. + TopTools_IndexedDataMapOfShapeListOfShape aEdgeFaceMap; + TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, aEdgeFaceMap); + for (Standard_Integer anIdx = 1; anIdx <= aEdgeFaceMap.Size(); ++anIdx) + { + const TopoDS_Edge& aCurrEdge = TopoDS::Edge(aEdgeFaceMap.FindKey(anIdx)); + FillEdgeData(aCurrEdge, aEdgeFaceMap, anIdx); + } + + // Iterate over vertices to compute new vertex. + TopTools_IndexedDataMapOfShapeListOfShape aVertexEdgeMap; + TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aVertexEdgeMap); + for (Standard_Integer anIdx = 1; anIdx <= aVertexEdgeMap.Size(); ++anIdx) + { + const TopoDS_Vertex & aCurrVertex = TopoDS::Vertex(aVertexEdgeMap.FindKey(anIdx)); + FillVertexData(aCurrVertex, aVertexEdgeMap, anIdx); + } +} + +//============================================================================= +//function : FillFaceData +//purpose : +//============================================================================= +void BRepOffset_SimpleOffset::FillFaceData(const TopoDS_Face& theFace) +{ + NewFaceData aNFD; + aNFD.myRevWires = Standard_False; + aNFD.myRevFace = Standard_False; + aNFD.myTol = BRep_Tool::Tolerance(theFace); + + // Create offset surface. + + // Any existing transformation is applied to the surface. + // New face will have null transformation. + Handle(Geom_Surface) aS = BRep_Tool::Surface(theFace); + + // Take into account face orientation. + Standard_Real aMult = 1.0; + if (theFace.Orientation() == TopAbs_REVERSED) + aMult = -1.0; + + aNFD.myOffsetS = new Geom_OffsetSurface(aS, aMult * myOffsetValue, Standard_True); + aNFD.myL = TopLoc_Location(); // Null transformation. + + // Save offset surface in map. + myFaceInfo.Bind(theFace, aNFD); +} + +//============================================================================= +//function : FillEdgeData +//purpose : +//============================================================================= +void BRepOffset_SimpleOffset::FillEdgeData(const TopoDS_Edge& theEdge, + const TopTools_IndexedDataMapOfShapeListOfShape& theEdgeFaceMap, + const Standard_Integer theIdx) +{ + const TopTools_ListOfShape& aFacesList = theEdgeFaceMap(theIdx); + + if (aFacesList.Size() == 0) + return; // Free edges are skipped. + + // Get offset surface. + const TopoDS_Face& aCurrFace = TopoDS::Face(aFacesList.First()); + + if (!myFaceInfo.IsBound(aCurrFace)) + return; + + // No need to deal with transformation - it is applied in fill faces data method. + const NewFaceData & aNFD = myFaceInfo.Find(aCurrFace); + Handle(Geom_Surface) anOffsetSurf = aNFD.myOffsetS; + + // Compute offset 3d curve. + Standard_Real aF, aL; + Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theEdge, aCurrFace, aF, aL); + + BRepBuilderAPI_MakeEdge anEdgeMaker(aC2d, anOffsetSurf, aF, aL); + TopoDS_Edge aNewEdge = anEdgeMaker.Edge(); + + // Compute max tolerance. Vertex tolerance usage is taken from existing offset computation algorithm. + // This piece of code significantly influences resulting performance. + Standard_Real aTol = BRep_Tool::MaxTolerance(theEdge, TopAbs_VERTEX); + BRepLib::BuildCurves3d(aNewEdge, aTol); + + NewEdgeData aNED; + aNED.myOffsetC = BRep_Tool::Curve(aNewEdge, aNED.myL, aF, aL); + + // Iterate over adjacent faces for the current edge and compute max deviation. + Standard_Real anEdgeTol = 0.0; + TopTools_ListOfShape::Iterator anIter(aFacesList); + for ( ; !aNED.myOffsetC.IsNull() && anIter.More() ; anIter.Next()) + { + const TopoDS_Face& aCurFace = TopoDS::Face(anIter.Value()); + + if (!myFaceInfo.IsBound(aCurFace)) + continue; + + // Create offset curve on surface. + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(theEdge, aCurFace, aF, aL); + const Handle(Adaptor2d_HCurve2d) aHCurve2d = new Geom2dAdaptor_HCurve(aC2d, aF, aL); + const Handle(Adaptor3d_HSurface) aHSurface = new GeomAdaptor_HSurface(myFaceInfo.Find(aCurFace).myOffsetS); + Adaptor3d_CurveOnSurface aCurveOnSurf(aHCurve2d, aHSurface); + + // Extract 3d-curve (it is not null). + const GeomAdaptor_Curve aCurve3d(aNED.myOffsetC, aF, aL); + + // It is necessary to compute maximal deviation (tolerance). + Standard_Real aMaxTol = 0.0; + ShapeAnalysis_Edge::ComputeDeviation(aCurve3d, aCurveOnSurf, Standard_True, aMaxTol, NCONTROL); + anEdgeTol = Max (anEdgeTol, aMaxTol); + } + aNED.myTol = Max(BRep_Tool::Tolerance(aNewEdge), anEdgeTol); + + // Save computed 3d curve in map. + myEdgeInfo.Bind(theEdge, aNED); +} + +//============================================================================= +//function : FillVertexData +//purpose : +//============================================================================= +void BRepOffset_SimpleOffset::FillVertexData(const TopoDS_Vertex& theVertex, + const TopTools_IndexedDataMapOfShapeListOfShape& theVertexEdgeMap, + const Standard_Integer theIdx) +{ + // Algorithm: + // Find adjacent edges for the given vertex. + // Find corresponding end on the each adjacent edge. + // Get offset points for founded end. + // Set result vertex position as barycenter of founded points. + + gp_Pnt aCurrPnt = BRep_Tool::Pnt(theVertex); + + const TopTools_ListOfShape& aEdgesList = theVertexEdgeMap(theIdx); + + if (aEdgesList.Size() == 0) + return; // Free verices are skipped. + + // Array to store offset points. + NCollection_Vector anOffsetPointVec; + + Standard_Real aMaxEdgeTol = 0.0; + + // Iterate over adjacent edges. + TopTools_ListOfShape::Iterator anIterEdges(aEdgesList); + for (; anIterEdges.More() ; anIterEdges.Next() ) + { + const TopoDS_Edge& aCurrEdge = TopoDS::Edge(anIterEdges.Value()); + + if (!myEdgeInfo.IsBound(aCurrEdge)) + continue; // Skip shared edges with wrong orientation. + + // Find the closest bound. + Standard_Real aF, aL; + Handle(Geom_Curve) aC3d = BRep_Tool::Curve(aCurrEdge, aF, aL); + + // Protection from degenerated edges. + if (aC3d.IsNull()) + continue; + + const gp_Pnt aPntF = aC3d->Value(aF); + const gp_Pnt aPntL = aC3d->Value(aL); + + const Standard_Real aSqDistF = aPntF.SquareDistance(aCurrPnt); + const Standard_Real aSqDistL = aPntL.SquareDistance(aCurrPnt); + + Standard_Real aMinParam = aF, aMaxParam = aL; + if (aSqDistL < aSqDistF) + { + // Square distance to last point is closer. + aMinParam = aL; aMaxParam = aF; + } + + // Compute point on offset edge. + const NewEdgeData& aNED = myEdgeInfo.Find(aCurrEdge); + const Handle(Geom_Curve) &anOffsetCurve = aNED.myOffsetC; + const gp_Pnt anOffsetPoint = anOffsetCurve->Value(aMinParam); + anOffsetPointVec.Append(anOffsetPoint); + + // Handle situation when edge is closed. + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aCurrEdge, aV1, aV2); + if (aV1.IsSame(aV2)) + { + const gp_Pnt anOffsetPoint = anOffsetCurve->Value(aMaxParam); + anOffsetPointVec.Append(anOffsetPoint); + } + + aMaxEdgeTol = Max(aMaxEdgeTol, aNED.myTol); + } + + // NCollection_Vector starts from 0 by default. + // It's better to use lower() and upper() in this case instead of direct indexes range. + gp_Pnt aCenter(0.0, 0.0, 0.0); + for(Standard_Integer i = anOffsetPointVec.Lower(); + i <= anOffsetPointVec.Upper(); + ++i) + { + aCenter.SetXYZ(aCenter.XYZ() + anOffsetPointVec.Value(i).XYZ()); + } + aCenter.SetXYZ(aCenter.XYZ() / anOffsetPointVec.Size()); + + // Compute max distance. + Standard_Real aSqMaxDist = 0.0; + for(Standard_Integer i = anOffsetPointVec.Lower(); + i <= anOffsetPointVec.Upper(); + ++i) + { + const Standard_Real aSqDist = aCenter.SquareDistance(anOffsetPointVec.Value(i)); + if (aSqDist > aSqMaxDist) + aSqMaxDist = aSqDist; + } + + const Standard_Real aResTol = Max(aMaxEdgeTol, Sqrt(aSqMaxDist)); + + const Standard_Real aMultCoeff = 1.001; // Avoid tolernace problems. + NewVertexData aNVD; + aNVD.myP = aCenter; + aNVD.myTol = aResTol * aMultCoeff; + + // Save computed vertex info. + myVertexInfo.Bind(theVertex, aNVD); +} diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.hxx b/src/BRepOffset/BRepOffset_SimpleOffset.hxx new file mode 100644 index 0000000000..423f1fd8a6 --- /dev/null +++ b/src/BRepOffset/BRepOffset_SimpleOffset.hxx @@ -0,0 +1,183 @@ +// Created on: 2016-10-14 +// Created by: Alexander MALYSHEV +// Copyright (c) 1999-2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepOffset_SimpleOffset_HeaderFile +#define _BRepOffset_SimpleOffset_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class BRepOffset_SimpleOffset; +DEFINE_STANDARD_HANDLE(BRepOffset_SimpleOffset, BRepTools_Modification) + +//! This class represents mechanism of simple offset algorithm i. e. +//! topology-preserve offset construction without intersection. +//! +//! The list below shows mapping scheme: +//! - Each surface is mapped to its geometric offset surface. +//! - For each edge, pcurves are mapped to the same pcurves on offset surfaces. +//! - For each edge, 3d curve is constructed by re-approximation of pcurve on the first offset face. +//! - Position of each vertex in a result shell is computed as average point of all ends of edges shared by that vertex. +//! - Tolerances are updated according to the resulting geometry. +class BRepOffset_SimpleOffset : public BRepTools_Modification +{ +public: + + DEFINE_STANDARD_RTTI_INLINE(BRepOffset_SimpleOffset, BRepTools_Modification) + + //! Constructor. + Standard_EXPORT BRepOffset_SimpleOffset(const TopoDS_Shape& theInputShape, + const Standard_Real theOffsetValue); + + //! Returns Standard_True if the face has been + //! modified. In this case, is the new geometric + //! support of the face, the new location, + //! the new tolerance. has to be set to + //! Standard_True when the modification reverses the + //! normal of the surface.(the wires have to be + //! reversed). has to be set to + //! Standard_True if the orientation of the modified + //! face changes in the shells which contain it. -- + //! Here, will return Standard_True if the + //! -- gp_Trsf is negative. + Standard_EXPORT Standard_Boolean NewSurface (const TopoDS_Face& F, + Handle(Geom_Surface)& S, + TopLoc_Location& L, + Standard_Real& Tol, + Standard_Boolean& RevWires, + Standard_Boolean& RevFace) Standard_OVERRIDE; + + //! Returns Standard_True if the edge has been + //! modified. In this case, is the new geometric + //! support of the edge, the new location, + //! the new tolerance. Otherwise, returns + //! Standard_False, and , , are not + //! significant. + Standard_EXPORT Standard_Boolean NewCurve (const TopoDS_Edge& E, + Handle(Geom_Curve)& C, + TopLoc_Location& L, + Standard_Real& Tol) Standard_OVERRIDE; + + //! Returns Standard_True if the vertex has been + //! modified. In this case,

is the new geometric + //! support of the vertex, the new tolerance. + //! Otherwise, returns Standard_False, and

, + //! are not significant. + Standard_EXPORT Standard_Boolean NewPoint (const TopoDS_Vertex& V, + gp_Pnt& P, + Standard_Real& Tol) Standard_OVERRIDE; + + //! Returns Standard_True if the edge has a new + //! curve on surface on the face .In this case, + //! is the new geometric support of the edge, the + //! new location, the new tolerance. + //! Otherwise, returns Standard_False, and , , + //! are not significant. + Standard_EXPORT Standard_Boolean NewCurve2d (const TopoDS_Edge& E, + const TopoDS_Face& F, + const TopoDS_Edge& NewE, + const TopoDS_Face& NewF, + Handle(Geom2d_Curve)& C, + Standard_Real& Tol) Standard_OVERRIDE; + + //! Returns Standard_True if the Vertex has a new + //! parameter on the edge . In this case,

is + //! the parameter, the new tolerance. + //! Otherwise, returns Standard_False, and

, + //! are not significant. + Standard_EXPORT Standard_Boolean NewParameter (const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& P, + Standard_Real& Tol) Standard_OVERRIDE; + + //! Returns the continuity of between + //! and . + //! + //! is the new edge created from . + //! (resp. ) is the new face created from + //! (resp. ). + Standard_EXPORT GeomAbs_Shape Continuity (const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const TopoDS_Edge& NewE, + const TopoDS_Face& NewF1, + const TopoDS_Face& NewF2) Standard_OVERRIDE; + +private: + + //! Method to fill new face data for single face. + void FillFaceData(const TopoDS_Face& theFace); + + //! Method to fill new edge data for single edge. + void FillEdgeData(const TopoDS_Edge& theEdge, + const TopTools_IndexedDataMapOfShapeListOfShape& theEdgeFaceMap, + const Standard_Integer theIdx); + + //! Method to fill new vertex data for single vertex. + void FillVertexData(const TopoDS_Vertex& theVertex, + const TopTools_IndexedDataMapOfShapeListOfShape& theVertexEdgeMap, + const Standard_Integer theIdx); + + struct NewFaceData + { + Handle(Geom_Surface) myOffsetS; + TopLoc_Location myL; + Standard_Real myTol; + Standard_Boolean myRevWires; + Standard_Boolean myRevFace; + }; + + struct NewEdgeData + { + Handle(Geom_Curve) myOffsetC; // Resulting curve. + TopLoc_Location myL; + Standard_Real myTol; + }; + + struct NewVertexData + { + gp_Pnt myP; + Standard_Real myTol; + }; + + //! Fills offset data. + void FillOffsetData(const TopoDS_Shape& theInputShape); + + //! Copy-assignment constructor and copy constructor are not allowed. + void operator=(const BRepOffset_SimpleOffset&); + BRepOffset_SimpleOffset(const BRepOffset_SimpleOffset&); + + //! Map of faces to new faces information. + NCollection_DataMap myFaceInfo; + + //! Map of edges to new edges information. + NCollection_DataMap myEdgeInfo; + + //! Map of vertices to new vertices information. + NCollection_DataMap myVertexInfo; + + //! Offset value. + Standard_Real myOffsetValue; +}; + +#endif // _BRepOffset_SimpleOffset_HeaderFile diff --git a/src/BRepOffset/FILES b/src/BRepOffset/FILES index c01c500bd6..0f650d4566 100644 --- a/src/BRepOffset/FILES +++ b/src/BRepOffset/FILES @@ -23,9 +23,13 @@ BRepOffset_MakeLoops.hxx BRepOffset_MakeOffset.cxx BRepOffset_MakeOffset_1.cxx BRepOffset_MakeOffset.hxx +BRepOffset_MakeSimpleOffset.cxx +BRepOffset_MakeSimpleOffset.hxx BRepOffset_Mode.hxx BRepOffset_Offset.cxx BRepOffset_Offset.hxx +BRepOffset_SimpleOffset.cxx +BRepOffset_SimpleOffset.hxx BRepOffset_Offset.lxx BRepOffset_Status.hxx BRepOffset_Tool.cxx diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx index 5a7318ff4c..c720e6c2be 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx @@ -14,9 +14,6 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// Modified by skv - Tue Mar 15 16:20:43 2005 -// Add methods for supporting history. - #include #include #include @@ -28,6 +25,7 @@ //purpose : //======================================================================= BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape() +: myLastUsedAlgo(OffsetAlgo_NONE) { } @@ -35,29 +33,72 @@ BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape() //function : BRepOffsetAPI_MakeOffsetShape //purpose : //======================================================================= +BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape(const TopoDS_Shape& S, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode, + const Standard_Boolean Intersection, + const Standard_Boolean SelfInter, + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges) +: myLastUsedAlgo(OffsetAlgo_NONE) +{ + PerformByJoin(S, Offset, Tol, Mode, Intersection, SelfInter, Join, RemoveIntEdges); +} -BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape -(const TopoDS_Shape& S, - const Standard_Real Offset, - const Standard_Real Tol, - const BRepOffset_Mode Mode, +//======================================================================= +//function : PerformByJoin +//purpose : +//======================================================================= +void BRepOffsetAPI_MakeOffsetShape::PerformByJoin +(const TopoDS_Shape& S, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode, const Standard_Boolean Intersection, const Standard_Boolean SelfInter, const GeomAbs_JoinType Join, const Standard_Boolean RemoveIntEdges) { + NotDone(); + myLastUsedAlgo = OffsetAlgo_JOIN; + myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter, Join, Standard_False, RemoveIntEdges); - Build(); + myOffsetShape.MakeOffsetShape(); + + if (!myOffsetShape.IsDone()) + return; + + myShape = myOffsetShape.Shape(); + Done(); } +//======================================================================= +//function : PerformBySimple +//purpose : +//======================================================================= +void BRepOffsetAPI_MakeOffsetShape::PerformBySimple(const TopoDS_Shape& theS, + const Standard_Real theOffsetValue) +{ + NotDone(); + myLastUsedAlgo = OffsetAlgo_SIMPLE; + + mySimpleOffsetShape.Initialize(theS, theOffsetValue); + mySimpleOffsetShape.Perform(); + + if (!mySimpleOffsetShape.IsDone()) + return; + + myShape = mySimpleOffsetShape.GetResultShape(); + Done(); +} //======================================================================= //function :MakeOffset //purpose : //======================================================================= - -const BRepOffset_MakeOffset& BRepOffsetAPI_MakeOffsetShape::MakeOffset() const +const BRepOffset_MakeOffset& BRepOffsetAPI_MakeOffsetShape::MakeOffset() const { return myOffsetShape; } @@ -66,72 +107,74 @@ const BRepOffset_MakeOffset& BRepOffsetAPI_MakeOffsetShape::MakeOffset() const //function : Build //purpose : //======================================================================= - void BRepOffsetAPI_MakeOffsetShape::Build() { - if (!IsDone()) { - myOffsetShape.MakeOffsetShape(); - if (!myOffsetShape.IsDone()) return; - myShape = myOffsetShape.Shape(); - Done(); - } } - //======================================================================= //function : Generated //purpose : //======================================================================= - -const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::Generated (const TopoDS_Shape& S) - -{ +const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::Generated (const TopoDS_Shape& S) +{ myGenerated.Clear(); - if (!myOffsetShape.ClosingFaces().Contains(S)) { + + if (myLastUsedAlgo == OffsetAlgo_JOIN && !myOffsetShape.ClosingFaces().Contains(S)) + { myOffsetShape.OffsetFacesFromShapes ().LastImage (S, myGenerated); - - if (!myOffsetShape.ClosingFaces().IsEmpty()) { + + if (!myOffsetShape.ClosingFaces().IsEmpty()) + { // Reverse generated shapes in case of small solids. // Useful only for faces without influence on others. TopTools_ListIteratorOfListOfShape it(myGenerated); for (; it.More(); it.Next()) - it.Value().Reverse(); + it.Value().Reverse(); } } + else if (myLastUsedAlgo == OffsetAlgo_SIMPLE) + { + TopoDS_Shape aGenShape = mySimpleOffsetShape.Generated(S); + if (!aGenShape.IsNull()) + myGenerated.Append(aGenShape); + } + return myGenerated; } - -// Modified by skv - Tue Mar 15 16:20:43 2005 Begin - //======================================================================= //function : GeneratedEdge //purpose : //======================================================================= - -const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::GeneratedEdge (const TopoDS_Shape& S) - -{ +const TopTools_ListOfShape& BRepOffsetAPI_MakeOffsetShape::GeneratedEdge (const TopoDS_Shape& S) +{ myGenerated.Clear(); - myOffsetShape.OffsetEdgesFromShapes ().LastImage (S, myGenerated); - if (!myGenerated.IsEmpty()) { - if (S.IsSame(myGenerated.First())) - myGenerated.RemoveFirst(); + if (myLastUsedAlgo == OffsetAlgo_JOIN) + { + myOffsetShape.OffsetEdgesFromShapes().LastImage (S, myGenerated); + + if (!myGenerated.IsEmpty()) + { + if (S.IsSame(myGenerated.First())) + myGenerated.RemoveFirst(); + } + } + else if (myLastUsedAlgo == OffsetAlgo_SIMPLE) + { + TopoDS_Shape aGenShape = mySimpleOffsetShape.Generated(S); + if (!aGenShape.IsNull()) + myGenerated.Append(aGenShape); } return myGenerated; } - //======================================================================= //function : GetJoinType //purpose : Query offset join type. //======================================================================= - GeomAbs_JoinType BRepOffsetAPI_MakeOffsetShape::GetJoinType() const { return myOffsetShape.GetJoinType(); } - -// Modified by skv - Tue Mar 15 16:20:43 2005 End diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.hxx index f37ea514ed..b528e391ee 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.hxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -44,9 +45,24 @@ public: DEFINE_STANDARD_ALLOC - + //! Constructor does nothing. Standard_EXPORT BRepOffsetAPI_MakeOffsetShape(); - + + //! Deprecated constructor. Please avoid usage of this constructor. + Standard_DEPRECATED("Deprecated constructor. Please use constructor without parameters and one of perform methods.") + Standard_EXPORT BRepOffsetAPI_MakeOffsetShape(const TopoDS_Shape& S, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode = BRepOffset_Skin, + const Standard_Boolean Intersection = Standard_False, + const Standard_Boolean SelfInter = Standard_False, + const GeomAbs_JoinType Join = GeomAbs_Arc, + const Standard_Boolean RemoveIntEdges = Standard_False); + + //! Constructs offset shape for the given one using simple algorithm without intersections computation. + Standard_EXPORT void PerformBySimple(const TopoDS_Shape& theS, + const Standard_Real theOffsetValue); + //! Constructs a shape parallel to the shape S, where //! - S may be a face, a shell, a solid or a compound of these shape kinds; //! - Offset is the offset value. The offset shape is constructed: @@ -102,22 +118,22 @@ public: //! Exceptions //! Geom_UndefinedDerivative if the underlying //! geometry of S is BSpline with continuity C0. - Standard_EXPORT BRepOffsetAPI_MakeOffsetShape(const TopoDS_Shape& S, - const Standard_Real Offset, - const Standard_Real Tol, - const BRepOffset_Mode Mode = BRepOffset_Skin, - const Standard_Boolean Intersection = Standard_False, - const Standard_Boolean SelfInter = Standard_False, - const GeomAbs_JoinType Join = GeomAbs_Arc, - const Standard_Boolean RemoveIntEdges = Standard_False); + Standard_EXPORT void PerformByJoin(const TopoDS_Shape& S, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode = BRepOffset_Skin, + const Standard_Boolean Intersection = Standard_False, + const Standard_Boolean SelfInter = Standard_False, + const GeomAbs_JoinType Join = GeomAbs_Arc, + const Standard_Boolean RemoveIntEdges = Standard_False); + //! Returns instance of the unrelying intersection / arc algorithm. Standard_EXPORT virtual const BRepOffset_MakeOffset& MakeOffset() const; - - //! Builds the resulting shape (redefined from MakeShape). + + //! Does nothing. Standard_EXPORT virtual void Build() Standard_OVERRIDE; - //! Returns the list of shapes generated from the - //! shape . + //! Returns the list of shapes generated from the shape . Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& S) Standard_OVERRIDE; //! Returns the list of edges generated from the shape . @@ -126,28 +142,19 @@ public: //! Returns offset join type. Standard_EXPORT GeomAbs_JoinType GetJoinType() const; - - - protected: + enum OffsetAlgo_Type + { + OffsetAlgo_NONE, + OffsetAlgo_JOIN, + OffsetAlgo_SIMPLE + }; + OffsetAlgo_Type myLastUsedAlgo; BRepOffset_MakeOffset myOffsetShape; - - -private: - - - - - + BRepOffset_MakeSimpleOffset mySimpleOffsetShape; }; - - - - - - #endif // _BRepOffsetAPI_MakeOffsetShape_HeaderFile diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx index 79f444c2f9..b4a4a4c343 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx @@ -22,22 +22,44 @@ #include #include + //======================================================================= //function : BRepOffsetAPI_MakeThickSolid //purpose : //======================================================================= BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid() { + // Build only solids. + mySimpleOffsetShape.SetBuildSolidFlag(Standard_True); } - //======================================================================= //function : BRepOffsetAPI_MakeThickSolid //purpose : //======================================================================= +BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid(const TopoDS_Shape& S, + const TopTools_ListOfShape& ClosingFaces, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode, + const Standard_Boolean Intersection, + const Standard_Boolean SelfInter, + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges) +{ + // Build only solids. + mySimpleOffsetShape.SetBuildSolidFlag(Standard_True); -BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid -(const TopoDS_Shape& S, + MakeThickSolidByJoin(S, ClosingFaces, Offset, Tol, + Mode, Intersection, SelfInter, Join, RemoveIntEdges); +} + +//======================================================================= +//function : MakeThickSolidByJoin +//purpose : +//======================================================================= +void BRepOffsetAPI_MakeThickSolid::MakeThickSolidByJoin +(const TopoDS_Shape& S, const TopTools_ListOfShape& ClosingFaces, const Standard_Real Offset, const Standard_Real Tol, @@ -47,51 +69,78 @@ BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid const GeomAbs_JoinType Join, const Standard_Boolean RemoveIntEdges) { + NotDone(); + myLastUsedAlgo = OffsetAlgo_JOIN; + myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter, Join, Standard_False, RemoveIntEdges); TopTools_ListIteratorOfListOfShape it(ClosingFaces); - for (; it.More(); it.Next()) { + for (; it.More(); it.Next()) myOffsetShape.AddFace(TopoDS::Face(it.Value())); - } - Build(); + + myOffsetShape.MakeThickSolid(); + if (!myOffsetShape.IsDone()) + return; + + myShape = myOffsetShape.Shape(); + Done(); } //======================================================================= -//function : virtual +//function : MakeThickSolidBySimple //purpose : //======================================================================= - -void BRepOffsetAPI_MakeThickSolid::Build() +void BRepOffsetAPI_MakeThickSolid::MakeThickSolidBySimple(const TopoDS_Shape& theS, + const Standard_Real theOffsetValue) { - if (!IsDone()) { - myOffsetShape.MakeThickSolid(); - if (!myOffsetShape.IsDone()) return; - myShape = myOffsetShape.Shape(); - Done(); - } + NotDone(); + myLastUsedAlgo = OffsetAlgo_SIMPLE; + + mySimpleOffsetShape.Initialize(theS, theOffsetValue); + mySimpleOffsetShape.Perform(); + + if (!mySimpleOffsetShape.IsDone()) + return; + + myShape = mySimpleOffsetShape.GetResultShape(); + Done(); } - +//======================================================================= +//function : Build +//purpose : +//======================================================================= +void BRepOffsetAPI_MakeThickSolid::Build() +{ +} //======================================================================= //function : Modified //purpose : //======================================================================= - -const TopTools_ListOfShape& BRepOffsetAPI_MakeThickSolid::Modified (const TopoDS_Shape& F) - +const TopTools_ListOfShape& BRepOffsetAPI_MakeThickSolid::Modified (const TopoDS_Shape& F) { myGenerated.Clear(); - if (myOffsetShape.OffsetFacesFromShapes().HasImage(F)) { - if (myOffsetShape.ClosingFaces().Contains(F)) { - myOffsetShape.OffsetFacesFromShapes().LastImage (F, myGenerated); - // Les face du resultat sont orientees comme dans la piece initiale. - //si offset a l interieur. + + if (myLastUsedAlgo == OffsetAlgo_JOIN && myOffsetShape.OffsetFacesFromShapes().HasImage(F)) + { + if (myOffsetShape.ClosingFaces().Contains(F)) + { + myOffsetShape.OffsetFacesFromShapes().LastImage (F, myGenerated); + + // Reverse generated shapes in case of small solids. + // Useful only for faces without influence on others. TopTools_ListIteratorOfListOfShape it(myGenerated); for (; it.More(); it.Next()) - it.Value().Reverse(); - + it.Value().Reverse(); } } + else if (myLastUsedAlgo == OffsetAlgo_SIMPLE) + { + TopoDS_Shape aModShape = mySimpleOffsetShape.Modified(F); + if (!aModShape.IsNull()) + myGenerated.Append(aModShape); + } + return myGenerated; } diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.hxx index 1ef6c6b0ee..7facdce00d 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.hxx @@ -51,9 +51,29 @@ public: DEFINE_STANDARD_ALLOC - + //! Constructor does nothing. Standard_EXPORT BRepOffsetAPI_MakeThickSolid(); - + + //! Deprecated constructor. Please avoid usage of this constructor. + Standard_DEPRECATED("Deprecated constructor. Please use constructor without parameters and one of make methods.") + Standard_EXPORT BRepOffsetAPI_MakeThickSolid(const TopoDS_Shape& S, + const TopTools_ListOfShape& ClosingFaces, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode = BRepOffset_Skin, + const Standard_Boolean Intersection = Standard_False, + const Standard_Boolean SelfInter = Standard_False, + const GeomAbs_JoinType Join = GeomAbs_Arc, + const Standard_Boolean RemoveIntEdges = Standard_False); + + //! Constructs solid using simple algorithm. + //! According to its nature it is not possible to set list of the closing faces. + //! This algorithm does not support faces removing. It is caused by fact that + //! intersections are not computed during offset creation. + //! Non-closed shell or face is expected as input. + Standard_EXPORT void MakeThickSolidBySimple(const TopoDS_Shape& theS, + const Standard_Real theOffsetValue); + //! Constructs a hollowed solid from //! the solid S by removing the set of faces ClosingFaces from S, where: //! Offset defines the thickness of the walls. Its sign indicates @@ -94,44 +114,22 @@ public: //! Since the algorithm of MakeThickSolid is based on //! MakeOffsetShape algorithm, the warnings are the same as for //! MakeOffsetShape. - Standard_EXPORT BRepOffsetAPI_MakeThickSolid(const TopoDS_Shape& S, - const TopTools_ListOfShape& ClosingFaces, - const Standard_Real Offset, - const Standard_Real Tol, - const BRepOffset_Mode Mode = BRepOffset_Skin, - const Standard_Boolean Intersection = Standard_False, - const Standard_Boolean SelfInter = Standard_False, - const GeomAbs_JoinType Join = GeomAbs_Arc, - const Standard_Boolean RemoveIntEdges = Standard_False); - - //! Builds the resulting shape (redefined from MakeOffsetShape). + Standard_EXPORT void MakeThickSolidByJoin(const TopoDS_Shape& S, + const TopTools_ListOfShape& ClosingFaces, + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode = BRepOffset_Skin, + const Standard_Boolean Intersection = Standard_False, + const Standard_Boolean SelfInter = Standard_False, + const GeomAbs_JoinType Join = GeomAbs_Arc, + const Standard_Boolean RemoveIntEdges = Standard_False); + + // Does nothing. Standard_EXPORT virtual void Build() Standard_OVERRIDE; //! Returns the list of shapes modified from the shape //! . Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& S) Standard_OVERRIDE; - - - - -protected: - - - - - -private: - - - - - }; - - - - - - #endif // _BRepOffsetAPI_MakeThickSolid_HeaderFile diff --git a/src/BRepTest/BRepTest_FeatureCommands.cxx b/src/BRepTest/BRepTest_FeatureCommands.cxx index bcf5f2e669..d69a51a818 100644 --- a/src/BRepTest/BRepTest_FeatureCommands.cxx +++ b/src/BRepTest/BRepTest_FeatureCommands.cxx @@ -54,8 +54,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -2239,6 +2239,52 @@ static Standard_Integer BOSS(Draw_Interpretor& theCommands, return 1; } +//============================================================================= +//function : ComputeSimpleOffset +//purpose : Computes simple offset. +//============================================================================= +static Standard_Integer ComputeSimpleOffset(Draw_Interpretor& theCommands, + Standard_Integer narg, + const char** a) +{ + if (narg != 4 && narg != 5) + { + theCommands << "offsetshapesimple result shape offsetvalue [solid]\n"; + return 1; + } + + // Input data. + TopoDS_Shape aShape = DBRep::Get(a[2]); + if (aShape.IsNull()) + { + theCommands << "Input shape is null"; + return 0; + } + const Standard_Real anOffsetValue = Draw::Atof(a[3]); + if (Abs(anOffsetValue) < gp::Resolution()) + { + theCommands << "Null offset value"; + return 0; + } + + BRepOffset_MakeSimpleOffset aMaker(aShape, anOffsetValue); + if (narg == 5 && !strcasecmp(a[4],"solid") ) + { + aMaker.SetBuildSolidFlag(Standard_True); + } + + aMaker.Perform(); + + if (!aMaker.IsDone()) + { + theCommands << "ERROR:" << aMaker.GetErrorMessage() << "\n"; + return 0; + } + + DBRep::Set(a[1], aMaker.GetResultShape()); + + return 0; +} //======================================================================= //function : FeatureCommands @@ -2385,4 +2431,7 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands) " Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)", __FILE__,BOSS); + theCommands.Add("offsetshapesimple", + "offsetshapesimple result shape offsetvalue [solid]", + __FILE__, ComputeSimpleOffset); } diff --git a/tests/offset/begin b/tests/offset/begin index cceddc05bc..4308b170c2 100644 --- a/tests/offset/begin +++ b/tests/offset/begin @@ -1,4 +1,4 @@ -# To prevent loops limit to 10 minutes +# To prevent loops limit to 15 minutes cpulimit 900 if { [array get Draw_Groups "TOPOLOGY Feature commands"] == "" } { pload TOPTEST diff --git a/tests/offset/grids.list b/tests/offset/grids.list index 3d188428bc..e4364ebb5f 100644 --- a/tests/offset/grids.list +++ b/tests/offset/grids.list @@ -16,3 +16,4 @@ 016 with_intersect_20 017 with_intersect_80 018 shape_type_i_c +019 simple diff --git a/tests/offset/simple/A01 b/tests/offset/simple/A01 new file mode 100644 index 0000000000..94cd957bae --- /dev/null +++ b/tests/offset/simple/A01 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_J8.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 3.05711e+006 +set ExpectedMaxTol 26.38 \ No newline at end of file diff --git a/tests/offset/simple/A02 b/tests/offset/simple/A02 new file mode 100644 index 0000000000..47d6f84ede --- /dev/null +++ b/tests/offset/simple/A02 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K3.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 1.3279e+007 +set ExpectedMaxTol 0.09 \ No newline at end of file diff --git a/tests/offset/simple/A03 b/tests/offset/simple/A03 new file mode 100644 index 0000000000..4a36c6d64b --- /dev/null +++ b/tests/offset/simple/A03 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K4.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.72622e+006 +set ExpectedMaxTol 23.75 \ No newline at end of file diff --git a/tests/offset/simple/A04 b/tests/offset/simple/A04 new file mode 100644 index 0000000000..4e0f1aa1d9 --- /dev/null +++ b/tests/offset/simple/A04 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K5.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.96921e+006 +set ExpectedMaxTol 1.02 \ No newline at end of file diff --git a/tests/offset/simple/A05 b/tests/offset/simple/A05 new file mode 100644 index 0000000000..639c54ee50 --- /dev/null +++ b/tests/offset/simple/A05 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K6.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 3.82881e+006 +set ExpectedMaxTol 1.25 \ No newline at end of file diff --git a/tests/offset/simple/A06 b/tests/offset/simple/A06 new file mode 100644 index 0000000000..ae9693bccc --- /dev/null +++ b/tests/offset/simple/A06 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K7.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 1.52853e+006 +set ExpectedMaxTol 26.38 \ No newline at end of file diff --git a/tests/offset/simple/A07 b/tests/offset/simple/A07 new file mode 100644 index 0000000000..c0a48b2301 --- /dev/null +++ b/tests/offset/simple/A07 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K9.brep] s +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.65579e+007 +set ExpectedMaxTol 24.55 \ No newline at end of file diff --git a/tests/offset/simple/A08 b/tests/offset/simple/A08 new file mode 100644 index 0000000000..922f9f4f9c --- /dev/null +++ b/tests/offset/simple/A08 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_J8.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.03486e+006 +set ExpectedMaxTol 105.52 \ No newline at end of file diff --git a/tests/offset/simple/A09 b/tests/offset/simple/A09 new file mode 100644 index 0000000000..fe7accae93 --- /dev/null +++ b/tests/offset/simple/A09 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K3.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.32749e+007 +set ExpectedMaxTol 0.3556 \ No newline at end of file diff --git a/tests/offset/simple/A10 b/tests/offset/simple/A10 new file mode 100644 index 0000000000..6774615284 --- /dev/null +++ b/tests/offset/simple/A10 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K4.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.68488e+006 +set ExpectedMaxTol 94.99 \ No newline at end of file diff --git a/tests/offset/simple/A11 b/tests/offset/simple/A11 new file mode 100644 index 0000000000..d93bb44a00 --- /dev/null +++ b/tests/offset/simple/A11 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K5.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.94956e+006 +set ExpectedMaxTol 4.06 \ No newline at end of file diff --git a/tests/offset/simple/A12 b/tests/offset/simple/A12 new file mode 100644 index 0000000000..16d8e674a9 --- /dev/null +++ b/tests/offset/simple/A12 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K6.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.79364e+006 +set ExpectedMaxTol 5.02 \ No newline at end of file diff --git a/tests/offset/simple/A13 b/tests/offset/simple/A13 new file mode 100644 index 0000000000..cc9a0c9fb7 --- /dev/null +++ b/tests/offset/simple/A13 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K7.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.51738e+006 +set ExpectedMaxTol 105.52 \ No newline at end of file diff --git a/tests/offset/simple/A14 b/tests/offset/simple/A14 new file mode 100644 index 0000000000..0f51753b8a --- /dev/null +++ b/tests/offset/simple/A14 @@ -0,0 +1,8 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K9.brep] s +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.65498e+007 +set ExpectedMaxTol 98.21 \ No newline at end of file diff --git a/tests/offset/simple/B01 b/tests/offset/simple/B01 new file mode 100644 index 0000000000..799452ebb9 --- /dev/null +++ b/tests/offset/simple/B01 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_J9.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 3.44079e+006 +set ExpectedMaxTol 21.55 \ No newline at end of file diff --git a/tests/offset/simple/B02 b/tests/offset/simple/B02 new file mode 100644 index 0000000000..7dc985f466 --- /dev/null +++ b/tests/offset/simple/B02 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M9.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.82491e+007 +set ExpectedMaxTol 0.3932 \ No newline at end of file diff --git a/tests/offset/simple/B03 b/tests/offset/simple/B03 new file mode 100644 index 0000000000..8c07d42f64 --- /dev/null +++ b/tests/offset/simple/B03 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K1.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.45168e+007 +set ExpectedMaxTol 1.141 \ No newline at end of file diff --git a/tests/offset/simple/B04 b/tests/offset/simple/B04 new file mode 100644 index 0000000000..4b1ff06f72 --- /dev/null +++ b/tests/offset/simple/B04 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K2.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.2251e+007 +set ExpectedMaxTol 2.412 \ No newline at end of file diff --git a/tests/offset/simple/B05 b/tests/offset/simple/B05 new file mode 100644 index 0000000000..5fb28e7cff --- /dev/null +++ b/tests/offset/simple/B05 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L3.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.00982e+007 +set ExpectedMaxTol 7.98 \ No newline at end of file diff --git a/tests/offset/simple/B06 b/tests/offset/simple/B06 new file mode 100644 index 0000000000..e0847cd224 --- /dev/null +++ b/tests/offset/simple/B06 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L4.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.82262e+007 +set ExpectedMaxTol 0.1681 \ No newline at end of file diff --git a/tests/offset/simple/B07 b/tests/offset/simple/B07 new file mode 100644 index 0000000000..26b27f528a --- /dev/null +++ b/tests/offset/simple/B07 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L6.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.93426e+007 +set ExpectedMaxTol 1.339 \ No newline at end of file diff --git a/tests/offset/simple/B08 b/tests/offset/simple/B08 new file mode 100644 index 0000000000..665200cd2b --- /dev/null +++ b/tests/offset/simple/B08 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L7.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.2251e+007 +set ExpectedMaxTol 2.412 \ No newline at end of file diff --git a/tests/offset/simple/B09 b/tests/offset/simple/B09 new file mode 100644 index 0000000000..e7bb52f2a8 --- /dev/null +++ b/tests/offset/simple/B09 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L8.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.93227e+007 +set ExpectedMaxTol 1.179 \ No newline at end of file diff --git a/tests/offset/simple/B10 b/tests/offset/simple/B10 new file mode 100644 index 0000000000..ac8e8832d5 --- /dev/null +++ b/tests/offset/simple/B10 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M9.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.82486e+007 +set ExpectedMaxTol 1.573 \ No newline at end of file diff --git a/tests/offset/simple/B11 b/tests/offset/simple/B11 new file mode 100644 index 0000000000..30a41bfd37 --- /dev/null +++ b/tests/offset/simple/B11 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L9.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.00982e+007 +set ExpectedMaxTol 7.98 \ No newline at end of file diff --git a/tests/offset/simple/B12 b/tests/offset/simple/B12 new file mode 100644 index 0000000000..1b1ac4a3bf --- /dev/null +++ b/tests/offset/simple/B12 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M1.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.45168e+007 +set ExpectedMaxTol 1.141 \ No newline at end of file diff --git a/tests/offset/simple/B13 b/tests/offset/simple/B13 new file mode 100644 index 0000000000..8cebb17a75 --- /dev/null +++ b/tests/offset/simple/B13 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M6.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.06441e+006 +set ExpectedMaxTol 2.81 \ No newline at end of file diff --git a/tests/offset/simple/B14 b/tests/offset/simple/B14 new file mode 100644 index 0000000000..ac8e8832d5 --- /dev/null +++ b/tests/offset/simple/B14 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M9.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.82486e+007 +set ExpectedMaxTol 1.573 \ No newline at end of file diff --git a/tests/offset/simple/B15 b/tests/offset/simple/B15 new file mode 100644 index 0000000000..d9d843a878 --- /dev/null +++ b/tests/offset/simple/B15 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_N7.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.12726e+007 +set ExpectedMaxTol 1.621 \ No newline at end of file diff --git a/tests/offset/simple/C01 b/tests/offset/simple/C01 new file mode 100644 index 0000000000..a5e23df78c --- /dev/null +++ b/tests/offset/simple/C01 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M8.brep] s + +set OffsetValue 100.0 + +# Reference data. +set ExpectedMass 1.26285e+007 +set ExpectedMaxTol 1.862 diff --git a/tests/offset/simple/C02 b/tests/offset/simple/C02 new file mode 100644 index 0000000000..0b2ed9c058 --- /dev/null +++ b/tests/offset/simple/C02 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26578_test_offset_plate2.brep] s + +set OffsetValue -30.0 + +# Reference data. +set ExpectedMass 6.3874e+006 +set ExpectedMaxTol 26.338 \ No newline at end of file diff --git a/tests/offset/simple/C03 b/tests/offset/simple/C03 new file mode 100644 index 0000000000..90aedfc51d --- /dev/null +++ b/tests/offset/simple/C03 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_C4.brep] s + +set OffsetValue 4.0 + +# Reference data. +set ExpectedMass 2.98155e+007 +set ExpectedMaxTol 1.636 diff --git a/tests/offset/simple/C04 b/tests/offset/simple/C04 new file mode 100644 index 0000000000..525bb32861 --- /dev/null +++ b/tests/offset/simple/C04 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_G4.brep] s + +set OffsetValue 2.0 + +# Reference data. +set ExpectedMass 2.3543e+006 +set ExpectedMaxTol 0.883 diff --git a/tests/offset/simple/C05 b/tests/offset/simple/C05 new file mode 100644 index 0000000000..a5b6292bd4 --- /dev/null +++ b/tests/offset/simple/C05 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_I5.brep] s + +set OffsetValue 2.0 + +# Reference data. +set ExpectedMass 3.91552e+007 +set ExpectedMaxTol 0.808 diff --git a/tests/offset/simple/C06 b/tests/offset/simple/C06 new file mode 100644 index 0000000000..d90e17f2d4 --- /dev/null +++ b/tests/offset/simple/C06 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26578_test_offset_plate6.brep] s + +set OffsetValue 60.0 + +# Reference data. +set ExpectedMass 2.31634e+007 +set ExpectedMaxTol 2.351 diff --git a/tests/offset/simple/C07 b/tests/offset/simple/C07 new file mode 100644 index 0000000000..eccbd2801d --- /dev/null +++ b/tests/offset/simple/C07 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L3.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.02449e+007 +set ExpectedMaxTol 1.994 \ No newline at end of file diff --git a/tests/offset/simple/C08 b/tests/offset/simple/C08 new file mode 100644 index 0000000000..6bb3d41422 --- /dev/null +++ b/tests/offset/simple/C08 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L9.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 2.02449e+007 +set ExpectedMaxTol 1.994 \ No newline at end of file diff --git a/tests/offset/simple/C09 b/tests/offset/simple/C09 new file mode 100644 index 0000000000..3d4a34c7ea --- /dev/null +++ b/tests/offset/simple/C09 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_J9.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.54341e+006 +set ExpectedMaxTol 86.160 \ No newline at end of file diff --git a/tests/offset/simple/C10 b/tests/offset/simple/C10 new file mode 100644 index 0000000000..e219accc13 --- /dev/null +++ b/tests/offset/simple/C10 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_K8.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.63567e+006 +set ExpectedMaxTol 6.937 \ No newline at end of file diff --git a/tests/offset/simple/C11 b/tests/offset/simple/C11 new file mode 100644 index 0000000000..e82d7394db --- /dev/null +++ b/tests/offset/simple/C11 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_L1.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.26556e+007 +set ExpectedMaxTol 1.490 \ No newline at end of file diff --git a/tests/offset/simple/C12 b/tests/offset/simple/C12 new file mode 100644 index 0000000000..173001335e --- /dev/null +++ b/tests/offset/simple/C12 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M3.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 3.15379e+006 +set ExpectedMaxTol 1.519 \ No newline at end of file diff --git a/tests/offset/simple/C13 b/tests/offset/simple/C13 new file mode 100644 index 0000000000..c9d105334f --- /dev/null +++ b/tests/offset/simple/C13 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M5.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 8.64266e+006 +set ExpectedMaxTol 3.569 \ No newline at end of file diff --git a/tests/offset/simple/C14 b/tests/offset/simple/C14 new file mode 100644 index 0000000000..e8a2a52b5e --- /dev/null +++ b/tests/offset/simple/C14 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_M8.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 1.26552e+007 +set ExpectedMaxTol 1.490 \ No newline at end of file diff --git a/tests/offset/simple/C15 b/tests/offset/simple/C15 new file mode 100644 index 0000000000..992aa87fca --- /dev/null +++ b/tests/offset/simple/C15 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26663_test_offset_N1.brep] s + +set OffsetValue 80.0 + +# Reference data. +set ExpectedMass 2.27708e+007 +set ExpectedMaxTol 3.143 \ No newline at end of file diff --git a/tests/offset/simple/D01 b/tests/offset/simple/D01 new file mode 100644 index 0000000000..83b10b7814 --- /dev/null +++ b/tests/offset/simple/D01 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: N/A" +restore [locate_data_file bug26587_plate.brep] s + +set OffsetValue 50.0 + +# Reference data. +set ExpectedMass 984797 +set ExpectedMaxTol 32.317 diff --git a/tests/offset/simple/D02 b/tests/offset/simple/D02 new file mode 100644 index 0000000000..15cdd99973 --- /dev/null +++ b/tests/offset/simple/D02 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: HA-1901" +restore [locate_data_file bug27907_2.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 1.5967e+007 +set ExpectedMaxTol 0.10549 diff --git a/tests/offset/simple/D03 b/tests/offset/simple/D03 new file mode 100644 index 0000000000..be241e16e4 --- /dev/null +++ b/tests/offset/simple/D03 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: A88BBB2B-89EE-496B-8C35-5B2AB9808EBD" +restore [locate_data_file bug27908.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 178976 +set ExpectedMaxTol 0.479111 diff --git a/tests/offset/simple/D04 b/tests/offset/simple/D04 new file mode 100644 index 0000000000..480f391324 --- /dev/null +++ b/tests/offset/simple/D04 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: BDC7375D-EFDD-48A4-942B-2B5ECA4E48DB" +restore [locate_data_file bug27909.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 368902 +set ExpectedMaxTol 0.49793 diff --git a/tests/offset/simple/D05 b/tests/offset/simple/D05 new file mode 100644 index 0000000000..11aef39a47 --- /dev/null +++ b/tests/offset/simple/D05 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: C779BA35-596C-4E12-96DF-53D4F6CD32D2" +restore [locate_data_file bug27910.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 386834 +set ExpectedMaxTol 0.037686 diff --git a/tests/offset/simple/D06 b/tests/offset/simple/D06 new file mode 100644 index 0000000000..1ec90c27da --- /dev/null +++ b/tests/offset/simple/D06 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: E45BCDC8-7222-4751-A15D-C2865BE26158" +restore [locate_data_file bug27911.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 109689 +set ExpectedMaxTol 0.043343 diff --git a/tests/offset/simple/D07 b/tests/offset/simple/D07 new file mode 100644 index 0000000000..209c0aaf54 --- /dev/null +++ b/tests/offset/simple/D07 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: HA-2023" +restore [locate_data_file bug27913.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 5.28198e+006 +set ExpectedMaxTol 2.6431 diff --git a/tests/offset/simple/E01 b/tests/offset/simple/E01 new file mode 100644 index 0000000000..94aba717bb --- /dev/null +++ b/tests/offset/simple/E01 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 28561742-E228-487D-9D66-C602A2065885" +restore [locate_data_file bug27954_E01.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 6.25923e+006 +set ExpectedMaxTol 0.05005 diff --git a/tests/offset/simple/E02 b/tests/offset/simple/E02 new file mode 100644 index 0000000000..3628ae53dd --- /dev/null +++ b/tests/offset/simple/E02 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 4831349C-7F37-4177-9ACD-14A12115B2EF" +restore [locate_data_file bug27954_E02.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 1.79498e+006 +set ExpectedMaxTol 0.01254 diff --git a/tests/offset/simple/E03 b/tests/offset/simple/E03 new file mode 100644 index 0000000000..f47cbdefe3 --- /dev/null +++ b/tests/offset/simple/E03 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: A01DD63B-C1FD-439D-9BF5-11905AF9C009" +restore [locate_data_file bug27954_E03.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 1.89284e+006 +set ExpectedMaxTol 0.052422 diff --git a/tests/offset/simple/E04 b/tests/offset/simple/E04 new file mode 100644 index 0000000000..2ba9db9ca3 --- /dev/null +++ b/tests/offset/simple/E04 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: BDCB0224-144F-4392-9229-19029AEBF346" +restore [locate_data_file bug27954_E04.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 2.55458e+006 +set ExpectedMaxTol 6.47469 diff --git a/tests/offset/simple/E05 b/tests/offset/simple/E05 new file mode 100644 index 0000000000..23910fde22 --- /dev/null +++ b/tests/offset/simple/E05 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: F6C5F855-E079-4024-A864-3DB9332003DB" +restore [locate_data_file bug27954_E05.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 1.10984e+006 +set ExpectedMaxTol 0.05005 diff --git a/tests/offset/simple/E06 b/tests/offset/simple/E06 new file mode 100644 index 0000000000..0937eab33f --- /dev/null +++ b/tests/offset/simple/E06 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 04A16521-038C-4639-851C-A7933BDDE511" +restore [locate_data_file bug27954_E06.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 2.59283e+006 +set ExpectedMaxTol 1.0801 \ No newline at end of file diff --git a/tests/offset/simple/E07 b/tests/offset/simple/E07 new file mode 100644 index 0000000000..1c7505d584 --- /dev/null +++ b/tests/offset/simple/E07 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 38F3B4F3-7482-4FD9-9082-78EE260ECB9C" +restore [locate_data_file bug27954_E07.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 2.20979e+007 +set ExpectedMaxTol 0.14277 diff --git a/tests/offset/simple/E08 b/tests/offset/simple/E08 new file mode 100644 index 0000000000..d7483486d1 --- /dev/null +++ b/tests/offset/simple/E08 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 20E0D114-29C3-46E1-9D69-35289E0C8C9D" +restore [locate_data_file bug27954_E08.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 6.78711e+006 +set ExpectedMaxTol 9.6347 diff --git a/tests/offset/simple/E09 b/tests/offset/simple/E09 new file mode 100644 index 0000000000..955e5a637f --- /dev/null +++ b/tests/offset/simple/E09 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 4147D9F2-0F3C-47D7-A877-738703334311" +restore [locate_data_file bug27954_E09.brep] s + +set OffsetValue 10.0 + +# Reference data. +set ExpectedMass 3.09695e+006 +set ExpectedMaxTol 10.1039 diff --git a/tests/offset/simple/E10 b/tests/offset/simple/E10 new file mode 100644 index 0000000000..bf09a5184d --- /dev/null +++ b/tests/offset/simple/E10 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: DEAB5074-6068-490B-9CE9-9EA0145004E6" +restore [locate_data_file bug27954_E10.brep] s + +set OffsetValue 12.0 + +# Reference data. +set ExpectedMass 3.14161e+006 +set ExpectedMaxTol 9.7758551227229384e-005 diff --git a/tests/offset/simple/E11 b/tests/offset/simple/E11 new file mode 100644 index 0000000000..86311ebcc7 --- /dev/null +++ b/tests/offset/simple/E11 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: EF75D6C4-4A1F-4A2C-A705-D645503B71FF" +restore [locate_data_file bug27954_E11.brep] s + +set OffsetValue 12.0 + +# Reference data. +set ExpectedMass 502659 +set ExpectedMaxTol 9.7753906249999995e-005 diff --git a/tests/offset/simple/E12 b/tests/offset/simple/E12 new file mode 100644 index 0000000000..cf6ad3c005 --- /dev/null +++ b/tests/offset/simple/E12 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 3DAF015F-C558-453C-ABD9-2D27F4202C54" +restore [locate_data_file bug27954_E12.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 3.30002e+006 +set ExpectedMaxTol 6.688170 diff --git a/tests/offset/simple/E13 b/tests/offset/simple/E13 new file mode 100644 index 0000000000..af6c619c23 --- /dev/null +++ b/tests/offset/simple/E13 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 26033800-3BA7-4E42-8EBE-7ABF24F5B8CD" +restore [locate_data_file bug27954_E13.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 6.97008e+006 +set ExpectedMaxTol 0.05445 diff --git a/tests/offset/simple/E14 b/tests/offset/simple/E14 new file mode 100644 index 0000000000..8dfeadf67b --- /dev/null +++ b/tests/offset/simple/E14 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: D9640BFE-FE1D-4CE6-8099-792B3576EE2B" +restore [locate_data_file bug27954_E14.brep] s + +set OffsetValue 10.5 + +# Reference data. +set ExpectedMass 3.15565e+006 +set ExpectedMaxTol 4.72124 diff --git a/tests/offset/simple/E15 b/tests/offset/simple/E15 new file mode 100644 index 0000000000..549e461b99 --- /dev/null +++ b/tests/offset/simple/E15 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 1F354708-BED2-49BE-9EFC-CFB80F35B632" +restore [locate_data_file bug27954_E15.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 5.62613e+006 +set ExpectedMaxTol 13.7670 diff --git a/tests/offset/simple/E16 b/tests/offset/simple/E16 new file mode 100644 index 0000000000..69e3ee04ad --- /dev/null +++ b/tests/offset/simple/E16 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 17FD83B1-187D-4BAE-95CC-18F4286BC305" +restore [locate_data_file bug27954_E16.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 3.02779e+006 +set ExpectedMaxTol 14.1629 diff --git a/tests/offset/simple/E17 b/tests/offset/simple/E17 new file mode 100644 index 0000000000..6485f175ef --- /dev/null +++ b/tests/offset/simple/E17 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: 4272E662-E79A-4109-898A-ACDFF729A027" +restore [locate_data_file bug27954_E17.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 1.07145e+006 +set ExpectedMaxTol 14.103 diff --git a/tests/offset/simple/E18 b/tests/offset/simple/E18 new file mode 100644 index 0000000000..2bdb3c6389 --- /dev/null +++ b/tests/offset/simple/E18 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: AA9E9570-12E5-46C5-B949-C012D3CC0648" +restore [locate_data_file bug27954_E18.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 1.5982e+007 +set ExpectedMaxTol 13.7670 diff --git a/tests/offset/simple/E19 b/tests/offset/simple/E19 new file mode 100644 index 0000000000..dfe0411788 --- /dev/null +++ b/tests/offset/simple/E19 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: HA-2498" +restore [locate_data_file bug27954_E19.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 3.65525e+007 +set ExpectedMaxTol 0.105926 diff --git a/tests/offset/simple/E20 b/tests/offset/simple/E20 new file mode 100644 index 0000000000..a3ec1425ef --- /dev/null +++ b/tests/offset/simple/E20 @@ -0,0 +1,9 @@ +# Test data: +puts "USER GUID: HA-2502" +restore [locate_data_file bug27954_E20.brep] s + +set OffsetValue 15.0 + +# Reference data. +set ExpectedMass 7.35034e+006 +set ExpectedMaxTol 35.6647 diff --git a/tests/offset/simple/begin b/tests/offset/simple/begin new file mode 100644 index 0000000000..fd3b5f71f4 --- /dev/null +++ b/tests/offset/simple/begin @@ -0,0 +1,8 @@ +pload MODELING VISUALIZATION +cpulimit 100 + +# "A" letter 26528 +# "B" letter 26577 +# "C" letter 26578 +# "D" letter 26587, 27907, 27908, 27909, 27910, 27911, 27912, 27913 +# "E" letter SPE 2016_Oct pack \ No newline at end of file diff --git a/tests/offset/simple/end b/tests/offset/simple/end new file mode 100644 index 0000000000..4bd90b996e --- /dev/null +++ b/tests/offset/simple/end @@ -0,0 +1,20 @@ +# Compute offset. +offsetshapesimple result s $OffsetValue + +# 1% relative tolerance +set TolRel 1.0e-2 + +# Check result validity. +checkshape result + +# Check result area. +checkprops result -s $ExpectedMass -eps $TolRel + +# Check maximal tolerance +checkmaxtol result -ref $ExpectedMaxTol + +# Make screenshot. +smallview +don result +fit +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file