From: nbv Date: Tue, 6 Mar 2018 10:31:18 +0000 (+0300) Subject: 0029523: Problem with BRepOffsetAPI_MakeEvolved X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=570c74d4f74cb813e75a65265b8339e28aa9dfa3;p=occt-copy.git 0029523: Problem with BRepOffsetAPI_MakeEvolved 1. New class BRepFill_Voluved has been created in order to provide new OCCT-algorithm combining BRepFill_PipeShell and BOPAlgo_MakerVolume. 2. The interface of DRAW-command "evolved" has been corrected. 3. DRAW-command "evolvedsolid" has been deleted. Currently it can be replaced with DRAW-command "evolved" with specific options. 4. Some test cases have been corrected. 5. Testgrid "evolved" has been created. --- diff --git a/src/BRepFill/BRepFill_PipeShell.cxx b/src/BRepFill/BRepFill_PipeShell.cxx index 65ff2b28a0..3d0eba45f8 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -692,7 +692,7 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) //function : Build //purpose : Construct the Shell and the history //======================================================================= - Standard_Boolean BRepFill_PipeShell::Build() + Standard_Boolean BRepFill_PipeShell::Build() { Standard_Boolean Ok; Standard_Real FirstS, LastS; @@ -746,8 +746,9 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); MkSw.SetAngularControl(angmin, angmax); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.SetBounds(TopoDS::Wire(myFirst), - TopoDS::Wire(myLast)); + MkSw.SetBounds(TopoDS::Wire(myFirst), + TopoDS::Wire(myLast)); + GeomAbs_Shape theContinuity = GeomAbs_C2; if (myTrihedron == GeomFill_IsDiscreteTrihedron) theContinuity = GeomAbs_C0; diff --git a/src/BRepFill/BRepFill_PipeShell.hxx b/src/BRepFill/BRepFill_PipeShell.hxx index c99ab7e758..36d6c824a0 100644 --- a/src/BRepFill/BRepFill_PipeShell.hxx +++ b/src/BRepFill/BRepFill_PipeShell.hxx @@ -168,6 +168,10 @@ public: Standard_EXPORT void Simulate (const Standard_Integer NumberOfSection, TopTools_ListOfShape& Sections); //! Builds the resulting shape (redefined from MakeShape). + //! If theIsToCheckValidity == FALSE then BRepFill_Sweep algorithm + //! is allowed to create invalid faces (having self-interferences). + //! It is considered for them that such faces will be processed and + //! fixed by the high-level algorithms Standard_EXPORT Standard_Boolean Build(); //! Transform the sweeping Shell in Solid. diff --git a/src/BRepFill/BRepFill_Sweep.cxx b/src/BRepFill/BRepFill_Sweep.cxx index c7e9550149..1d2f0214b3 100644 --- a/src/BRepFill/BRepFill_Sweep.cxx +++ b/src/BRepFill/BRepFill_Sweep.cxx @@ -914,7 +914,7 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF, // Control the direction of the rotation Standard_Boolean ToReverseResult = Standard_False; gp_Vec d1u; - d1u = Surf->DN(0, (f1+l1)/2, 1, 0); + d1u = Surf->DN(0, aPrm[aMaxIdx], 1, 0); if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything ToReverseResult = Standard_True; /* @@ -1815,8 +1815,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, const Standard_Boolean WithKPart) : isDone(Standard_False), KPart(WithKPart) - - { mySec = Section; myLoc = Location; @@ -3353,7 +3351,8 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const // Filling B = Filling(It1.Value(), myFaces->Value(ii, I1), It2.Value(), myFaces->Value(ii, I2), - myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF); + myVEdgesModified, myTol3d, Axe, T1, + Bord1, Bord2, FF); if (B) { myAuxShape.Append(FF); diff --git a/src/BRepFill/BRepFill_Sweep.hxx b/src/BRepFill/BRepFill_Sweep.hxx index b3b003a3f9..72b1897959 100644 --- a/src/BRepFill/BRepFill_Sweep.hxx +++ b/src/BRepFill/BRepFill_Sweep.hxx @@ -80,7 +80,7 @@ public: //! to be C0. Standard_EXPORT void SetForceApproxC1 (const Standard_Boolean ForceApproxC1); - //! Build the Sweeep Surface + //! Build the Sweep Surface //! Transition define Transition strategy //! Approx define Approximation Strategy //! - GeomFill_Section : The composed Function Location X Section @@ -118,13 +118,6 @@ public: protected: - - - - -private: - - Standard_EXPORT Standard_Boolean CorrectApproxParameters(); Standard_EXPORT Standard_Boolean BuildWire (const BRepFill_TransitionStyle Transition); @@ -142,6 +135,13 @@ private: Standard_EXPORT void RebuildTopOrBottomEdge (const TopoDS_Edge& aNewEdge, TopoDS_Edge& anEdge, TopTools_MapOfShape& ReversedEdges) const; + + +private: + + + + Standard_Boolean isDone; Standard_Boolean KPart; Standard_Real myTol3d; @@ -168,7 +168,6 @@ private: TopoDS_Wire FirstShape; TopoDS_Wire LastShape; - }; diff --git a/src/BRepFill/BRepFill_Voluved.cxx b/src/BRepFill/BRepFill_Voluved.cxx new file mode 100644 index 0000000000..12efc6f416 --- /dev/null +++ b/src/BRepFill/BRepFill_Voluved.cxx @@ -0,0 +1,1700 @@ +// Created on: 2018-03-14 +// Created by: Nikolai BUKHALOV +// Copyright (c) 1999-2018 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 + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const Standard_Real aPipeLinearTolerance = 1.0e-4; +static const Standard_Real aPipeAngularTolerance = 1.0e-2; + +static Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF, + const Standard_Real theFuzzyToler, + TopTools_ListOfShape& theListOfFaces, + TopTools_ListOfShape& theListOfSplits); + +//======================================================================= +//function : GetSpineAndProfile +//purpose : +//======================================================================= +void BRepFill_Voluved::GetSpineAndProfile(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile) +{ + mySpine = theSpine; + myProfile = theProfile; + + TopTools_IndexedDataMapOfShapeListOfShape aMVEP; + TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVEP); + + gp_Vec aN2; + gp_Pnt aLoc; + + for (Standard_Integer i = 1; i <= aMVEP.Size(); i++) + { + const TopoDS_Vertex &aVC = TopoDS::Vertex(aMVEP.FindKey(i)); + + const TopTools_ListOfShape &aLE = aMVEP.FindFromIndex(i); + + if (aLE.Extent() < 2) + continue; + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aVC, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aVC, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + aN2 = aT1.Crossed(aT2); + + if (aN2.SquareMagnitude() > Precision::SquareConfusion()) + { + aLoc = BRep_Tool::Pnt(aVC); + break; + } + } + + BRepExtrema_DistShapeShape anExtr; + anExtr.LoadS1(theSpine); + + if (aN2.SquareMagnitude() > Precision::SquareConfusion()) + { + const gp_Pln aPln(aLoc, aN2); + BRepLib_MakeFace aMF(aPln, theProfile); + if (!aMF.IsDone()) + return; + + anExtr.LoadS2(aMF.Face()); + } + else + { + anExtr.LoadS2(theProfile); + } + + if (!anExtr.Perform()) + return; + + const Standard_Integer aNbSol = anExtr.NbSolution(); + if (aNbSol < 1) + return; + + Standard_Real aDistMin = RealLast(); + Standard_Integer anIdxMin = 0; + + for (Standard_Integer aSolId = 1; aSolId <= aNbSol; aSolId++) + { + const Standard_Real aD = anExtr.Value(); + if (aD > aDistMin) + continue; + + aDistMin = aD; + anIdxMin = aSolId; + } + + BRepExtrema_SupportType anExtrType2 = anExtr.SupportTypeShape2(anIdxMin); + + if (aDistMin < Precision::Confusion()) + { + anExtrType2 = BRepExtrema_IsInFace; + } + + switch (anExtrType2) + { + case BRepExtrema_IsInFace: + if (anExtr.SupportTypeShape1(anIdxMin) == BRepExtrema_IsVertex) + { + const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape1(anIdxMin)); + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopExp::MapShapesAndAncestors(theSpine, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + + const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV); + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + // Find minimal sine + const Standard_Real aSqT1 = Max(aT1.SquareMagnitude(), 1.0 / Precision::Infinite()); + const Standard_Real aSqT2 = Max(aT2.SquareMagnitude(), 1.0 / Precision::Infinite()); + + const Standard_Real aSqSin1 = aT1.CrossSquareMagnitude(aN2) / aSqT1; + const Standard_Real aSqSin2 = aT2.CrossSquareMagnitude(aN2) / aSqT2; + + if (aSqSin1 < aSqSin2) + { + if (aT1.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + else + { + if (aT2.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + } + else // if (... == BRepExtrema_IsOnEdge) + { + const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape1(anIdxMin)); + const BRepAdaptor_Curve anAC(anE); + Standard_Real aPar; + anExtr.ParOnEdgeS1(anIdxMin, aPar); + + gp_Pnt aP; + gp_Vec aT1; + anAC.D1(aPar, aP, aT1); + + if (aT1.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + break; + + case BRepExtrema_IsOnEdge: + case BRepExtrema_IsVertex: + { + const BRepLib_MakeFace aMkFSpine(theSpine, Standard_True); + if (!aMkFSpine.IsDone()) + return; + + const TopoDS_Face &aFSpine = aMkFSpine.Face(); + const Handle(Geom_Plane) aPlnSpine = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aFSpine)); + const gp_Vec aN1(aPlnSpine->Axis().Direction()); + gp_Vec aTanV; + + if (anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsVertex) + { + const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape2(anIdxMin)); + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + + const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV); + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + // Find maximal cosine + Standard_Real aSqT1 = aT1.SquareMagnitude(); + Standard_Real aSqT2 = aT2.SquareMagnitude(); + + if (aSqT1 < Precision::SquareConfusion()) + aSqT1 = RealLast(); + + if (aSqT2 < Precision::SquareConfusion()) + aSqT2 = RealLast(); + + const Standard_Real aDP1 = aT1.Dot(aN1); + const Standard_Real aDP2 = aT2.Dot(aN1); + + if (aDP1*aDP1*aSqT2 > aDP2*aDP2*aSqT1) + { + //aDP1*aDP1/aSqT1 > aDP2*aDP2/aSqT2 + aTanV = aT1; + } + else + { + aTanV = aT2; + } + } + else // if(anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsOnEdge) + { + const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape2(anIdxMin)); + const BRepAdaptor_Curve anAC(anE); + Standard_Real aPar; + anExtr.ParOnEdgeS2(anIdxMin, aPar); + + gp_Pnt aP; + anAC.D1(aPar, aP, aTanV); + } + + //The point in the profile, which is the nearest to the spine + const gp_Pnt &aPnear = anExtr.PointOnShape2(anIdxMin); + + BRepClass_FaceClassifier aFClass(aFSpine, aPnear, Precision::Confusion()); + if (aFClass.State() != TopAbs_OUT) + { + if (aN1.Dot(aTanV) < 0.0) + { + myProfile = TopoDS::Wire(theProfile.Reversed()); + } + } + else + { + if (aN1.Dot(aTanV) > 0.0) + { + myProfile = TopoDS::Wire(theProfile.Reversed()); + } + } + } + break; + default: + break; + } +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void BRepFill_Voluved::Perform(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile, + const Standard_Real theTolerance, + const Standard_Boolean theSolidReq) +{ + myErrorStatus = BRepFill_Voluved_Empty; + + if (myFuzzyValue < Precision::Confusion()) + { + myFuzzyValue = theTolerance; + } + + GetSpineAndProfile(theSpine, theProfile); + + myPipeShell.Nullify(); + myTopBottom.Nullify(); + myResult.Nullify(); + + PerformSweep(); + GetLids(); + + if ((myErrorStatus != BRepFill_Voluved_NotSolid) && !theSolidReq) + { + myResult = myPipeShell; + } + + BuildSolid(); +} + +//======================================================================= +//function : PerformSweep +//purpose : +//======================================================================= +void BRepFill_Voluved::PerformSweep() +{ + if (myErrorStatus != BRepFill_Voluved_Empty) + return; + + myErrorStatus = BRepFill_Voluved_SweepError; + + Handle(BRepFill_PipeShell) aPipe = new BRepFill_PipeShell(mySpine); + aPipe->SetTolerance(aPipeLinearTolerance, aPipeLinearTolerance, aPipeAngularTolerance); + aPipe->SetTransition(BRepFill_TransitionStyle::BRepFill_Round); + aPipe->Add(myProfile, Standard_False, Standard_False); + + if (aPipe->Build()) + { + myErrorStatus = BRepFill_Voluved_NoLids; + myPipeShell = aPipe->Shape(); + } +} + +//======================================================================= +//function : GetLids +//purpose : +//======================================================================= +void BRepFill_Voluved::GetLids() +{ + if (myPipeShell.IsNull()) + return; + + if (BRep_Tool::IsClosed(myProfile)) + { + // No need in lids creation + myErrorStatus = BRepFill_Voluved_NotSolid; + return; + } + + myErrorStatus = BRepFill_Voluved_NoLids; + + BRepLib_FindSurface aFS(mySpine, -1.0, Standard_True); + const Handle(Geom_Plane) aSurf = Handle(Geom_Plane)::DownCast(aFS.Surface()); + + if (aSurf.IsNull()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + //Square of the default angular tolerance in + //BOPAlgo_Tools::EdgesToWires(...) and BOPAlgo_Tools::WiresToFaces(...) methods + const Standard_Real aSqAnguarTol = 1.0e-16; + const gp_Dir &aNormal = aSurf->Axis().Direction(); + + // Obtain free-edges from myPipeShell. All edges must be planar + // and parallel to the plane of mySpine + + TopTools_IndexedDataMapOfShapeListOfShape aMap; + + TopExp::MapShapesAndAncestors(myPipeShell, TopAbs_EDGE, TopAbs_FACE, aMap); + + TopTools_ListOfShape aLE; + + gp_Pnt aP; + gp_Vec aTan; + + for (Standard_Integer i = 1; i <= aMap.Size(); i++) + { + TopTools_ListOfShape& aListF = aMap(i); + + if (aListF.Extent() != 1) + continue; + + const TopoDS_Edge &anE = TopoDS::Edge(aMap.FindKey(i)); + + BRepAdaptor_Curve anAC(anE); + if (!anAC.Is3DCurve()) + { + // We are not interested in degenerated edges. + continue; + } + + anAC.D1(0.5*(anAC.FirstParameter() + anAC.LastParameter()), aP, aTan); + + const Standard_Real aSqModulus = aTan.SquareMagnitude(); + if (aSqModulus < Precision::Confusion()) + continue; + + const Standard_Real aDP = aTan.XYZ().Dot(aNormal.XYZ()); + if (aDP*aDP>aSqModulus*aSqAnguarTol) + { + //Only planar edges are considered + continue; + } + + aLE.Append(anE); + } + + if (aLE.IsEmpty()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + // Split interfered edges + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLE); + aPF.SetRunParallel(Standard_True); + + aPF.Perform(); + if (aPF.HasErrors()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(Standard_True); + aBuilder.PerformWithFiller(aPF); + if (aBuilder.HasErrors()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + const TopoDS_Shape& aFreeEdges = aBuilder.Shape(); + + // Collect all free edges to wires and create planar + // top and bottom lids from these wires. + BRep_Builder aBB; + TopoDS_Compound aCompW; + aBB.MakeCompound(aCompW); + aBB.MakeCompound(myTopBottom); + BOPAlgo_Tools::EdgesToWires(aFreeEdges, aCompW, Standard_True); + BOPAlgo_Tools::WiresToFaces(aCompW, myTopBottom); + + myErrorStatus = BRepFill_Voluved_NotSolid; +} + +//======================================================================= +//function : ProcessVertex +//purpose : +//======================================================================= +#include +#include +void ProcessVertex(const TopoDS_Vertex& aV, + const TopTools_ListOfShape& aLE, + const TopTools_ListOfShape& aLF) +{ + Standard_Real aTol, aD2, aTolMax2, aTolE, aParam; + gp_Pnt aPC3D; + gp_Pnt2d aPC2D; + TopAbs_Orientation anOrV; + + TopTools_ListIteratorOfListOfShape anIt; + TopExp_Explorer aVExp; + + BRep_ListIteratorOfListOfCurveRepresentation itcr; + // + aTolMax2 = -1.e6; + // + Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape()); + const gp_Pnt& aPV3D = TV->Pnt(); + aTol = BRep_Tool::Tolerance(aV); + // + anIt.Initialize(aLE); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value()); + // + Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); + const TopLoc_Location& Eloc = aE.Location(); + // + aVExp.Init(aE, TopAbs_VERTEX); + for (; aVExp.More(); aVExp.Next()) + { + const TopoDS_Vertex& aVx = TopoDS::Vertex(aVExp.Current()); + // + if (!aVx.IsSame(aV)) + { + continue; + } + // + anOrV = aVx.Orientation(); + if (!(anOrV == TopAbs_FORWARD || anOrV == TopAbs_REVERSED)) + { + continue; + } + // + const BRep_ListOfCurveRepresentation& aLCR = TE->Curves(); + itcr.Initialize(aLCR); + for (; itcr.More(); itcr.Next()) + { + const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); + const TopLoc_Location& loc = cr->Location(); + TopLoc_Location L = (Eloc * loc).Predivided(aV.Location()); + // + // 3D-Curve + if (cr->IsCurve3D()) + { + const Handle(Geom_Curve)& aC3D = cr->Curve3D(); + // + if (aC3D.IsNull()) + { + continue; + } + // 3D-point treatment + aParam = BRep_Tool::Parameter(aVx, aE); + aPC3D = aC3D->Value(aParam); + aPC3D.Transform(L.Transformation()); + aD2 = aPV3D.SquareDistance(aPC3D); + if (aD2 > aTolMax2) + { + aTolMax2 = aD2; + } + // + }//if (cr->IsCurve3D()) + // + // 2D-Curve + else if (cr->IsCurveOnSurface()) + { + const Handle(Geom2d_Curve)& aC2D = cr->PCurve(); + if (aC2D.IsNull()) + { + continue; + } + // Surface + const Handle(Geom_Surface)& aS = cr->Surface(); + // + // 2D-point treatment + aParam = BRep_Tool::Parameter(aVx, aE, aS, L); + aPC2D = aC2D->Value(aParam); + aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D); + aPC3D.Transform(L.Transformation()); + aD2 = aPV3D.SquareDistance(aPC3D); + if (aD2 > aTolMax2) + { + aTolMax2 = aD2; + } + } //if (cr->IsCurveOnSurface()) + + }//for (; itcr.More(); itcr.Next()) + }//for (; aVExp.More(); aVExp.Next()) + }//for (; anIt.More(); anIt.Next()) + //######################################################### + // + // Reducing + if (aTolMax2<0.) + { + return; + } + // + aTolMax2 = sqrt(aTolMax2); + if (aTolMax2>aTol) + { + return; + } + // + anIt.Initialize(aLE); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value()); + + aTolE = BRep_Tool::Tolerance(aE); + if (aTolMax2 < aTolE) + { + aTolMax2 = aTolE; + } + } + // + anIt.Initialize(aLF); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Face& aF = TopoDS::Face(anIt.Value()); + + aTolE = BRep_Tool::Tolerance(aF); + if (aTolMax2 < aTolE) + { + aTolMax2 = aTolE; + } + } + // + if (aTolMax2>aTol) + { + return; + } + // + // Update Tolerance + TV->Tolerance(aTolMax2); +} + +//======================================================================= +//function : ReduceVertexTolerance +//purpose : +//======================================================================= +void ReduceVertexTolerance(const TopoDS_Shape& aS) +{ + Standard_Integer i, aNbV; + TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap; + + TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap); + TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap); + + aNbV = aVEMap.Extent(); + for (i = 1; i <= aNbV; i++) + { + const TopoDS_Vertex& aV = TopoDS::Vertex(aVEMap.FindKey(i)); + const TopTools_ListOfShape& aLE = aVEMap(i); + const TopTools_ListOfShape& aLF = aVFMap.FindFromKey(aV); + + ProcessVertex(aV, aLE, aLF); + } +} + + +//======================================================================= +//function : BuildSolid +//purpose : +//======================================================================= +void BRepFill_Voluved::BuildSolid() +{ + if (myErrorStatus != BRepFill_Voluved_NotSolid) + return; + + myErrorStatus = BRepFill_Voluved_NotVolume; + + TopTools_MapOfShape aMapF; + TopTools_ListOfShape aLF, aLSplits; + TopExp_Explorer anExpF; + + Handle(ShapeFix_Shape) aSFix = new ShapeFix_Shape; + aSFix->Init(myPipeShell); + aSFix->Perform(); + myPipeShell = aSFix->Shape(); + + for (anExpF.Init(myPipeShell, TopAbs_FACE); + anExpF.More(); anExpF.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExpF.Current()); + if (!aMapF.Add(aF)) + continue; + + TopoDS_Face aFC = aF; + aSFix->Init(aFC); + aSFix->Perform(); + aFC = TopoDS::Face(aSFix->Shape()); + ReduceVertexTolerance(aFC); + + CheckSingularityAndAdd(aFC, myFuzzyValue, aLF, aLSplits); + } + + { + TopTools_ListIteratorOfListOfShape anItrS(aLSplits); + for (; anItrS.More(); anItrS.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrS.Value()); + aLF.Append(aF); + } + + // Split interfered faces + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLF); + aPF.SetRunParallel(Standard_True); + aPF.SetFuzzyValue(myFuzzyValue); + + aPF.Perform(); + if (!aPF.HasErrors()) + { + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLF); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(Standard_True); + aBuilder.PerformWithFiller(aPF); + myPipeShell = aBuilder.Shape(); + } + } + + aLF.Clear(); + aMapF.Clear(); + for (anExpF.Init(myPipeShell, TopAbs_FACE); + anExpF.More(); anExpF.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExpF.Current()); + if (!aMapF.Add(aF)) + continue; + + aLF.Append(aF); + } + + if (!myTopBottom.IsNull()) + { + TopoDS_Iterator anItLids(myTopBottom); + for (; anItLids.More(); anItLids.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItLids.Value()); + aLF.Append(aF); + } + } + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(aLF); + aMV.SetFuzzyValue(myFuzzyValue); + aMV.SetIntersect(Standard_True); + aMV.SetRunParallel(Standard_True); + aMV.SetAvoidInternalShapes(Standard_True); + aMV.Perform(); + + if (aMV.HasErrors()) + { + return; + } + + myResult = aMV.Shape(); + RemoveExcessSolids(aLSplits, myResult, aLF, aMV); + + myErrorStatus = BRepFill_Voluved_OK; +} + +//======================================================================= +//function : ExtractOuterSolid +//purpose : +//======================================================================= +void BRepFill_Voluved::ExtractOuterSolid(TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList) +{ + TopTools_IndexedDataMapOfShapeListOfShape aMapS; + TopExp::MapShapesAndAncestors(theShape, TopAbs_FACE, TopAbs_SOLID, aMapS); + + Standard_Boolean hasBeenDeleted = Standard_False; + + for (Standard_Integer i = 1; i <= aMapS.Extent(); i++) + { + const TopTools_ListOfShape &aL = aMapS(i); + if (aL.Extent() > 1) + { + // Face is shared between several solids. ==> + // It cannot participate in the outer contour and should be removed. + + const TopoDS_Face &aF = TopoDS::Face(aMapS.FindKey(i)); + theArgsList.Remove(aF); + hasBeenDeleted = Standard_True; + } + } + + if (!hasBeenDeleted) + return; + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(theArgsList); + aMV.SetIntersect(Standard_True); + aMV.SetRunParallel(Standard_True); + aMV.SetAvoidInternalShapes(Standard_True); + aMV.Perform(); + + if (aMV.HasErrors()) + { + return; + } + + theShape = aMV.Shape(); +} + +//======================================================================= +//function : RemoveExcessSolids +//purpose : +//======================================================================= +#include +#include +void BRepFill_Voluved::RemoveExcessSolids(const TopTools_ListOfShape& /*theLSplits*/, + TopoDS_Shape& theShape, + TopTools_ListOfShape& /*theArgsList*/, + BOPAlgo_MakerVolume& /*theMV*/) +{ + if (myErrorStatus != BRepFill_Voluved_NotVolume) + return; + +#if 1 + TopExp_Explorer anExpSo(theShape, TopAbs_SOLID); + Standard_Real aMaxVol = RealFirst(); + myResult = anExpSo.Current(); + for(;anExpSo.More(); anExpSo.Next()) + { + const TopoDS_Solid &aSol = TopoDS::Solid(anExpSo.Current()); + GProp_GProps aGprop; + BRepGProp::VolumeProperties(aSol, aGprop, 1.0e-4); + const Standard_Real aV = aGprop.Mass(); + + if(aV > aMaxVol) + { + aMaxVol = aV; + myResult = aSol; + } + } +#else + + TopExp_Explorer anExpSo; + for (Standard_Integer i = 0; i < 2; i++) + { + anExpSo.Init(theShape, TopAbs_SOLID); + if (!anExpSo.More()) + { + myResult = theShape; + return; + } + + anExpSo.Next(); + if (!anExpSo.More()) + { + // Only one solid has been generated + myResult = TopoDS::Solid(anExpSo.Current()); + return; + } + + if (i != 0) + break; + + ExtractOuterSolid(theShape, theArgsList); + } + + // Remove Split faces from the list of arguments + TopTools_ListIteratorOfListOfShape anItl(theLSplits); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + theArgsList.Remove(aF); + } + + // Create a list of invalid faces. The face is invalid if + // BOPAlgo_MakerVolume changes its orientation while creating solids. + // Faces from theLSplits are not checked. + TopTools_ListOfShape aListInvFaces; + for (anItl.Init(theArgsList); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + for (TopTools_ListIteratorOfListOfShape anItM(theMV.Modified(aF)); + anItM.More(); anItM.Next()) + { + const TopoDS_Face &aFM = TopoDS::Face(anItM.Value()); + + if (aFM.Orientation() != aF.Orientation()) + aListInvFaces.Append(aFM); + } + } + + TopTools_ListOfShape aSolidList; + for (anExpSo.Init(theShape, TopAbs_SOLID); anExpSo.More(); anExpSo.Next()) + { + const TopoDS_Solid &aSo = TopoDS::Solid(anExpSo.Current()); + TopTools_IndexedMapOfShape aMapF; + TopExp::MapShapes(aSo, TopAbs_FACE, aMapF); + Standard_Boolean isToDelete = Standard_False; + + for (anItl.Init(aListInvFaces); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + if (aMapF.Contains(aF)) + { + isToDelete = Standard_True; + break; + } + } + + if (isToDelete) + { + continue; + } + + for (anItl.Init(theArgsList); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + const Standard_Integer anIdx = aMapF.FindIndex(aF); + if (anIdx == 0) + continue; + + const TopoDS_Face &aF1 = TopoDS::Face(aMapF.FindKey(anIdx)); + + // aF and aF1 are same shapes. Check if they are equal. + + if (!aF.IsEqual(aF1)) + { + isToDelete = Standard_True; + break; + } + } + + if (isToDelete) + { + continue; + } + + aSolidList.Append(aSo); + } + + if (aSolidList.Extent() < 1) + { + myResult = theShape; + return; + } + + if (aSolidList.Extent() == 1) + { + myResult = aSolidList.First(); + return; + } + + BRep_Builder aBB; + TopoDS_Compound aCmpSol; + aBB.MakeCompound(aCmpSol); + + for (anItl.Init(aSolidList); anItl.More(); anItl.Next()) + { + const TopoDS_Solid &aSo = TopoDS::Solid(anItl.Value()); + aBB.Add(aCmpSol, aSo); + } + + myResult = aCmpSol; +#endif +} + +//======================================================================= +//class : NormalFunc +//purpose : +//======================================================================= +class NormalFunc : public math_MultipleVarFunctionWithHessian +{ +public: + NormalFunc(const Adaptor3d_CurveOnSurface& theCOS) :myCOnS(theCOS) + { + } + + virtual Standard_Integer NbVariables() const Standard_OVERRIDE + { + return 1; + } + + + virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) Standard_OVERRIDE; + virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) Standard_OVERRIDE; + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theF, + math_Vector& theG) Standard_OVERRIDE + { + if (!Value(theX, theF)) + return Standard_False; + + if (!Gradient(theX, theG)) + return Standard_False; + + return Standard_True; + }; + + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theF, + math_Vector& theG, + math_Matrix& theH) Standard_OVERRIDE + { + if (!Values(theX, theF, theG)) + return Standard_False; + + theH(1, 1) = theG(1); + return Standard_True; + }; + + Standard_Real FirstParameter() const + { + return myCOnS.FirstParameter(); + } + + Standard_Real LastParameter() const + { + return myCOnS.LastParameter(); + } + + gp_Pnt GetPoint(const Standard_Real theX) + { + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + const gp_Pnt2d aP2d(aC->Value(theX)); + return aS->Value(aP2d.X(), aP2d.Y()); + } + +protected: + + NormalFunc& operator=(NormalFunc&); + +private: + const Adaptor3d_CurveOnSurface& myCOnS; +}; + +//======================================================================= +//function : Value +//purpose : +aD1v_x^2*aD1u_y^2 + aD1v_x^2*aD1u_z^2 + +// +aD1v_y^2*aD1u_z^2 + aD1u_x^2*aD1v_y^2 + +// +aD1u_x^2*aD1v_z^2 + aD1u_y^2*aD1v_z^2 - +// - 2*(+aD1u_x*aD1v_x*aD1u_y*aD1v_y + +// +aD1u_x*aD1v_x*aD1u_z*aD1v_z + +// +aD1u_y*aD1v_y*aD1u_z*aD1v_z) +//======================================================================= +Standard_Boolean NormalFunc::Value(const math_Vector& theX, Standard_Real& theF) +{ + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + + const gp_Pnt2d aP2d(aC->Value(theX(1))); + gp_Pnt aP3d; + gp_Vec aD1u, aD1v; + aS->D1(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v); + + theF = aD1u.Crossed(aD1v).SquareMagnitude(); + return Standard_True; +} + +//======================================================================= +//function : Gradient +//purpose : +//2 * ((aD1v_x*aD1u_y)*(aD1u_y*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) + +// (aD1v_x*aD1u_z)*(aD1u_z*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) + +// (aD1v_y*aD1u_z)*(aD1u_z*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) + +// (aD1u_x*aD1v_y)*(aD1u_x*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) + +// (aD1u_x*aD1v_z)*(aD1u_x*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) + +// (aD1u_y*aD1v_z)*(aD1u_y*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) - +// +// (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_y*aD1v_y - +// aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_y*aD1v_y - +// aD1u_x*aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y - +// aD1u_x*aD1v_x*aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y) - +// +// (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_z*aD1v_z - +// aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_z*aD1v_z - +// aD1u_x*aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z - +// aD1u_x*aD1v_x*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y) - +// +// (aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y*aD1u_z*aD1v_z - +// aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y)*aD1u_z*aD1v_z - +// aD1u_y*aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z - +// aD1u_y*aD1v_y*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y)) +//======================================================================= +Standard_Boolean NormalFunc::Gradient(const math_Vector& theX, math_Vector& theG) +{ + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + + gp_Pnt2d aP2d; + gp_Vec2d aDc; + aC->D1(theX(1), aP2d, aDc); + + gp_Pnt aP3d; + gp_Vec aD1u, aD1v, aD2u, aD2v, aD2uv; + aS->D2(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v, aD2u, aD2v, aD2uv); + + theG(1) = (aD1v.X()*aD1u.Y())*(aD1u.Y()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y()) + + aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) + + (aD1v.X()*aD1u.Z())*(aD1u.Z()*(aD2uv.X()*aDc.X() + + aD2v.X()*aDc.Y()) + aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + + (aD1v.Y()*aD1u.Z())*(aD1u.Z()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + + aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + (aD1u.X()*aD1v.Y())* + (aD1u.X()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + aD1v.Y()*(aD2u.X()* + aDc.X() + aD2uv.X()*aDc.Y())) + (aD1u.X()*aD1v.Z())*(aD1u.X()*(aD2uv.Z()* + aDc.X() + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.X()*aDc.X() + + aD2uv.X()*aDc.Y())) + (aD1u.Y()*aD1v.Z())*(aD1u.Y()*(aD2uv.Z()*aDc.X() + + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) - + (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Y()*aD1v.Y() - + aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Y()*aD1v.Y() - + aD1u.X()*aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y() - + aD1u.X()*aD1v.X()*aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) - + (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Z()*aD1v.Z() - + aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Z()*aD1v.Z() - + aD1u.X()*aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - + aD1u.X()*aD1v.X()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()) - + (aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y()*aD1u.Z()*aD1v.Z() - + aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y())*aD1u.Z()*aD1v.Z() - + aD1u.Y()*aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - + aD1u.Y()*aD1v.Y()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()); + + return Standard_True; +} + +//======================================================================= +//structure : EInfoTosplit +//purpose : +//======================================================================= +struct EInfoTosplit +{ + TopoDS_Edge myEdge; + TopoDS_Vertex myVertexToSplit; + Standard_Real myParam; + Standard_Real myTolerance; +}; + +//======================================================================= +//function : RebuildFaces +//purpose : Creates a wires from theEdges and puts it to the new face +// which is empty-copied from theSourceFace. +//======================================================================= +static void RebuildFaces(const TopTools_ListOfShape& theLE, + const TopoDS_Face& theSourceFace, + TopTools_ListOfShape& theList) +{ + //build new faces + BOPAlgo_BuilderFace aBF; + + TopoDS_Face aF = TopoDS::Face(theSourceFace.Oriented(TopAbs_FORWARD)); + + aBF.SetFace(aF); + aBF.SetShapes(theLE); + + aBF.Perform(); + + const TopTools_ListOfShape& aLFR = aBF.Areas(); + + if (aLFR.IsEmpty()) + { + theList.Append(theSourceFace); + return; + } + + TopTools_ListIteratorOfListOfShape aItFR(aLFR); + for (; aItFR.More(); aItFR.Next()) + { + const TopoDS_Shape& aFR = TopoDS::Face(aItFR.Value()); + theList.Append(aFR); + } +} + +//======================================================================= +//function : MakeEdgeDegenerated +//purpose : Returns TRUE if degenerated edge has been created. +// Every degenerated edge (to split) must be added in theLEdges twice +// with different orientations. Moreover, Degenerated edges cannot be shared. +// Therefore, make copy of them before adding. +//======================================================================= +static Standard_Boolean MakeEdgeDegenerated(const TopoDS_Vertex& theV, + const TopoDS_Face& theFace, + const gp_Pnt2d& thePf, + const gp_Pnt2d& thePl, + TopTools_ListOfShape& theLEdges) +{ + BRepAdaptor_Surface anAS(theFace, Standard_False); + + const Standard_Real aTol = 2.0*BRep_Tool::Tolerance(theV); + const Standard_Real aTolU = anAS.UResolution(aTol), + aTolV = anAS.VResolution(aTol); + + if ((Abs(thePf.X() - thePl.X()) < aTolU) && (Abs(thePf.Y() - thePl.Y()) < aTolV)) + return Standard_False; + + const TopoDS_Vertex aVf = TopoDS::Vertex(theV.Oriented(TopAbs_FORWARD)), + aVl = TopoDS::Vertex(theV.Oriented(TopAbs_REVERSED)); + + const gp_XY aV = thePl.XY() - thePf.XY(); + const Handle(Geom2d_Line) aL1 = new Geom2d_Line(thePf, gp_Dir2d(aV)); + const Handle(Geom2d_Line) aL2 = new Geom2d_Line(thePl, gp_Dir2d(aV.Reversed())); + + BRep_Builder aBB; + TopoDS_Edge anEdegen1, anEdegen2; + aBB.MakeEdge(anEdegen1); + aBB.MakeEdge(anEdegen2); + + aBB.UpdateEdge(anEdegen1, aL1, theFace, Precision::Confusion()); + aBB.UpdateEdge(anEdegen2, aL2, theFace, Precision::Confusion()); + + anEdegen1.Orientation(TopAbs_FORWARD); + anEdegen2.Orientation(TopAbs_FORWARD); + + aBB.Add(anEdegen1, aVf); + aBB.Add(anEdegen1, aVl); + aBB.Add(anEdegen2, aVf); + aBB.Add(anEdegen2, aVl); + + aBB.Degenerated(anEdegen1, Standard_True); + aBB.Degenerated(anEdegen2, Standard_True); + + const Standard_Real aLPar = aV.Modulus(); + aBB.Range(anEdegen1, 0.0, aLPar); + aBB.Range(anEdegen2, 0.0, aLPar); + + theLEdges.Append(anEdegen1); + theLEdges.Append(anEdegen2); + + return Standard_True; +} + +//======================================================================= +//function : InsertEDegenerated +//purpose : +//======================================================================= +static void InsertEDegenerated(const TopoDS_Face& theFace, + TopTools_ListOfShape& theLEdges) +{ + BRep_Builder aBB; + TopoDS_Wire aWir; + aBB.MakeWire(aWir); + + TopTools_ListIteratorOfListOfShape anItr(theLEdges); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anItr.Value()); + aBB.Add(aWir, anE); + } + + TopTools_IndexedDataMapOfShapeListOfShape aMapVE; + TopExp::MapShapesAndUniqueAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); + + BRepTools_WireExplorer anExp(aWir, theFace); + + TopoDS_Edge anE1 = anExp.Current(), aFirstEdge, aLastEdge; + + if (anE1.IsNull()) + { + // It is possible if aWir contains + // only INTERNAL/EXTERNAL edges. + + return; + } + + aFirstEdge = anE1; + anExp.Next(); + +# if 0 + if (!anExp.More()) + { + // The wire contains only single edge. + // But this edge can be closed itself (e.g. circle). + + TopoDS_Vertex aVf, aVl; + TopExp::Vertices(anE1, aVf, aVl); + if (!aVf.IsNull() && aVf.IsSame(aVl)) + { + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVf, anE1); + aL = BRep_Tool::Parameter(aVl, anE1); + const gp_Pnt2d aPf(aC->Value(aF)), aPl(aC->Value(aL)); + + MakeEdgeDegenerated(aVf, theFace, aPf, aPl, theLEdges); + } + + return; + } +#endif + + // Map containing all vertices of degenerated edges + TopTools_MapOfShape aMapVofDE; + + { + TopExp_Explorer anExpDE(aWir, TopAbs_EDGE); + for (; anExpDE.More(); anExpDE.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anExpDE.Current()); + if (!BRep_Tool::Degenerated(anE)) + continue; + + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(anE, aV1, aV2); + + // aV1 and aV2 are SAME vertices + + aMapVofDE.Add(aV1); + } + } + + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Edge& anE2 = anExp.Current(); + aLastEdge = anE2; +#if 0 + if (anE1.IsSame(anE2)) + { + //Exclude a gap between two seam-edges (e.g. cylinder without roofs). + anE1 = anE2; + continue; + } +#endif + + const TopoDS_Vertex &aVertCurr = anExp.CurrentVertex(); + + if (aMapVofDE.Contains(aVertCurr)) + { + // Necessary degenerated edge has already been created. + anE1 = anE2; + continue; + } + + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL), + aC2 = BRep_Tool::CurveOnSurface(anE2, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVertCurr, anE1); + aL = BRep_Tool::Parameter(aVertCurr, anE2); + const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL)); + + if (MakeEdgeDegenerated(aVertCurr, theFace, aPf, aPl, theLEdges)) + { + aMapVofDE.Add(aVertCurr); + anE1 = anE2; + continue; + } + + const TopTools_ListOfShape *anEList = aMapVE.Seek(aVertCurr); + if ((anEList != 0) && (anEList->Extent() <= 2)) + { + anE1 = anE2; + continue; + } + + // Case like cone with apex. In 2D space all is OK + // (therefore BRepTools_WireExplorer processes this case + // correctly). But in 3D-space, we have several edges with + // the same vertex. Cone apex must be plugged by degenerated edge. + + Standard_Boolean hasDegenerated = Standard_False; + TopTools_ListIteratorOfListOfShape anItr(*anEList); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value()); + if (BRep_Tool::Degenerated(anEdge)) + { + hasDegenerated = Standard_True; + break; + } + } + + if (hasDegenerated) + { + anE1 = anE2; + continue; + } + + // Look for the pair for anE1 and anE2 edges + for (Standard_Integer i = 0; i < 2; i++) + { + const gp_Pnt2d &aPoint = i ? aPl : aPf; + anItr.Initialize(*anEList); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value()); + + if (anEdge.IsSame(anE1) || anEdge.IsSame(anE2)) + continue; + + const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anEdge, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVertCurr, anEdge); + const gp_Pnt2d aP(aC->Value(aF)); + + if (MakeEdgeDegenerated(aVertCurr, theFace, aPoint, aP, theLEdges)) + { + aMapVofDE.Add(aVertCurr); + i = 2; + break; + } + } + } + + anE1 = anE2; + } + + if (aFirstEdge.IsNull() || aLastEdge.IsNull()) + return; + +#if 0 + if (aFirstEdge.IsSame(aLastEdge)) + { + //Exclude a gap between two seam-edges (e.g. cylinder without bottom-base). + + return; + } +#endif + + //TopExp::CommonVertex(...) does not work + //if edges have more than one pair of common vertex + //(e.g. two halves of circle). Here, we process this case. + TopoDS_Vertex aV[4]; + TopExp::Vertices(aFirstEdge, aV[0], aV[1]); + if (!aV[0].IsNull() && aV[0].IsSame(aV[1])) + { + // Possible reason is the NOT-CLOSED edge + // has only single vertex and is covered by it. + return; + } + + TopExp::Vertices(aLastEdge, aV[2], aV[3]); + if (!aV[2].IsNull() && aV[2].IsSame(aV[3])) + { + // Possible reason is the NOT-CLOSED edge + // has only single vertex and is covered by it. + return; + } + + for (Standard_Integer anIDFE = 0; anIDFE < 2; anIDFE++) + { + for (Standard_Integer anIDLE = 2; anIDLE < 4; anIDLE++) + { + if (!aV[anIDFE].IsSame(aV[anIDLE])) + continue; + + const NCollection_List *anEList = aMapVE.Seek(aV[anIDFE]); + if ((anEList != 0) && (anEList->Extent() > 2)) + { + // Causes: + // 1. Non-manifold topology. + // 2. Case such as: + // + // ************************* + // * * + // seam * * seam + // * edge1 edge2 * + // * ******** ********* * + // V1 V2 V3 V4 + // + // + // V1 - vertex between edge1 and seam + // V4 - vertex between edge2 and seam + // + // Indeed, V1 and V4 are same but they + // must not be joined. + + continue; + } + + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(aFirstEdge, theFace, aF, aL), + aC2 = BRep_Tool::CurveOnSurface(aLastEdge, theFace, aF, aL); + aF = BRep_Tool::Parameter(aV[anIDFE], aFirstEdge); + aL = BRep_Tool::Parameter(aV[anIDLE], aLastEdge); + const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL)); + + MakeEdgeDegenerated(aV[anIDFE], theFace, aPf, aPl, theLEdges); + } + } +} + +//======================================================================= +//function : CheckSingularityAndAdd +//purpose : Returns TRUE if theF has been split +//======================================================================= +Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF, + const Standard_Real theFuzzyToler, + TopTools_ListOfShape& theListOfFaces, + TopTools_ListOfShape& theListOfSplits) +{ + const BRepAdaptor_Surface anAS(theF, Standard_False); + GeomAbs_SurfaceType aSType = anAS.GetType(); + + if (aSType == GeomAbs_OffsetSurface) + { + aSType = anAS.BasisSurface()->GetType(); + } + + if (aSType == GeomAbs_Plane) + { + TopTools_MapOfShape aME; + TopTools_ListOfShape aLE; + TopExp_Explorer anExp(theF, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anExp.Current()); + + if (aME.Add(anE)) + aLE.Append(anE); + } + + // Split interfered edges + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLE); + aPF.SetRunParallel(Standard_True); + + aPF.Perform(); + if (aPF.HasErrors()) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + const BOPDS_DS &aDS = aPF.DS(); + if (aDS.NbShapes() == aDS.NbSourceShapes()) + { + //Interfered edges have not been detected + theListOfFaces.Append(theF); + return Standard_False; + } + + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(Standard_True); + aBuilder.PerformWithFiller(aPF); + if (aBuilder.HasErrors()) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + const TopoDS_Shape& anEdges = aBuilder.Shape(); + + BRep_Builder aBB; + TopoDS_Compound aCompW, aCompF; + aBB.MakeCompound(aCompW); + aBB.MakeCompound(aCompF); + BOPAlgo_Tools::EdgesToWires(anEdges, aCompW, Standard_True); + BOPAlgo_Tools::WiresToFaces(aCompW, aCompF); + + aME.Clear(); + anExp.Init(aCompF, TopAbs_FACE); + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExp.Current()); + theListOfSplits.Append(aF); + } + + return Standard_True; + } + + if ((aSType != GeomAbs_Cone) && + (aSType != GeomAbs_Sphere) && + (aSType != GeomAbs_BezierSurface) && + (aSType != GeomAbs_BSplineSurface) && + (aSType != GeomAbs_SurfaceOfRevolution)) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + BRep_Builder aBB; + + TopoDS_Compound aCWires; + aBB.MakeCompound(aCWires); + + Standard_Boolean isSplit = Standard_False; + TopTools_ListOfShape aListEdges; + + const TopoDS_Face aF = TopoDS::Face(theF.Oriented(TopAbs_FORWARD)); + + for (TopoDS_Iterator anExpW(aF); anExpW.More(); anExpW.Next()) + { + const TopoDS_Wire &aWir = TopoDS::Wire(anExpW.Value()); + + TopTools_ListOfShape aLGF; + TopExp_Explorer anEExp(aWir, TopAbs_EDGE); + for (; anEExp.More(); anEExp.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anEExp.Current()); + aLGF.Append(anE); + } + + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLGF); + aPF.SetFuzzyValue(theFuzzyToler); + aPF.Perform(); + + if (aPF.HasErrors()) + { + continue; + } + + const BOPDS_DS &aDS = aPF.DS(); + if (aDS.NbShapes() == aDS.NbSourceShapes()) + { + //No new shapes have been created + continue; + } + + BOPAlgo_Builder aBAB(NCollection_BaseAllocator::CommonBaseAllocator()); + TopTools_ListIteratorOfListOfShape aBItr(aLGF); + for (; aBItr.More(); aBItr.Next()) + { + const TopoDS_Shape &aSh = aBItr.Value(); + aBAB.AddArgument(aSh); + } + + aBAB.SetRunParallel(Standard_True); + aBAB.SetNonDestructive(Standard_True); + aBAB.PerformWithFiller(aPF); + if (aBAB.HasErrors()) + { + continue; + } + + TopTools_ListOfShape aLE; +#if 0 + // This fragment requires fixing the issue #29656 + TopTools_MapOfShape aMM; + TopExp_Explorer anExpEB(aBAB.Shape(), TopAbs_EDGE); + for (; anExpEB.More(); anExpEB.Next()) + { + const TopoDS_Edge anEE = TopoDS::Edge(anExpEB.Current()); + if (!aMM.Add(anEE)) + continue; + + aLE.Append(anEE); + } +#else + for (aBItr.Init(aLGF); aBItr.More(); aBItr.Next()) + { + const TopoDS_Edge &aSh = TopoDS::Edge(aBItr.Value()); + const TopTools_ListOfShape &aLM = aBAB.Modified(aSh); + if (aLM.IsEmpty() || BRep_Tool::Degenerated(aSh)) + { + aLE.Append(aSh); + continue; + } + + TopTools_ListIteratorOfListOfShape anItLM(aLM); + for (; anItLM.More(); anItLM.Next()) + { + const TopoDS_Edge &anEM = TopoDS::Edge(anItLM.Value()); + aLE.Append(anEM); + } + } +#endif + + isSplit = Standard_True; + InsertEDegenerated(aF, aLE); + aListEdges.Append(aLE); + } + + if (!isSplit) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + RebuildFaces(aListEdges, theF, theListOfSplits); + + TopTools_ListIteratorOfListOfShape anItrS(theListOfSplits); + for (; anItrS.More(); anItrS.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrS.Value()); + theListOfFaces.Append(aF.Oriented(theF.Orientation())); + } + + return Standard_True; +} diff --git a/src/BRepFill/BRepFill_Voluved.hxx b/src/BRepFill/BRepFill_Voluved.hxx new file mode 100644 index 0000000000..5675cc9c75 --- /dev/null +++ b/src/BRepFill/BRepFill_Voluved.hxx @@ -0,0 +1,106 @@ +// Created on: 2018-03-14 +// Created by: Nikolai BUKHALOV +// Copyright (c) 1999-2018 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 _BRepFill_Voluved_HeaderFile +#define _BRepFill_Voluved_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +class BOPAlgo_MakerVolume; + +//! Constructs an evolved volume from a spine (wire or face) +//! and a profile ( wire). +class BRepFill_Voluved +{ +public: + + DEFINE_STANDARD_ALLOC + + Standard_EXPORT BRepFill_Voluved() :myErrorStatus(BRepFill_Voluved_Empty), + myFuzzyValue(0.0) + { + } + + Standard_EXPORT void Perform(const TopoDS_Wire& theSpine, const TopoDS_Wire& theProfile, const Standard_Real theTolerance, const Standard_Boolean theSolidReq = Standard_True); + + Standard_Boolean IsDone(unsigned int* theErrorCode = 0) const + { + if (theErrorCode) + *theErrorCode = myErrorStatus; + + return (myErrorStatus == BRepFill_Voluved_OK); + } + + //! returns the resulting shape. + const TopoDS_Shape& Shape() const + { + return myResult; + } + +protected: + + Standard_EXPORT void PerformSweep(); + + Standard_EXPORT void GetLids(); + + Standard_EXPORT void BuildSolid(); + + Standard_EXPORT void RemoveExcessSolids(const TopTools_ListOfShape& theLSplits, + TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList, + BOPAlgo_MakerVolume& theMV); + + Standard_EXPORT void ExtractOuterSolid(TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList); + + Standard_EXPORT void GetSpineAndProfile(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile); + +private: + + enum + { + BRepFill_Voluved_Empty = 0, + BRepFill_Voluved_NotPlanarSpine, + BRepFill_Voluved_SweepError, + BRepFill_Voluved_NoLids, + BRepFill_Voluved_NotSolid, + BRepFill_Voluved_NotVolume, + BRepFill_Voluved_OK = UINT_MAX + } myErrorStatus; + + TopoDS_Wire mySpine; + TopoDS_Wire myProfile; + TopoDS_Shape myPipeShell; + TopoDS_Compound myTopBottom; // Lids can be split on several faces + TopoDS_Shape myResult; + Standard_Real myFuzzyValue; + + +}; + + + + + + + +#endif // _BRepFill_Voluved_HeaderFile diff --git a/src/BRepFill/FILES b/src/BRepFill/FILES index ebba998dd6..e0a9ded7a0 100644 --- a/src/BRepFill/FILES +++ b/src/BRepFill/FILES @@ -83,3 +83,5 @@ BRepFill_TrimShellCorner.hxx BRepFill_TrimSurfaceTool.cxx BRepFill_TrimSurfaceTool.hxx BRepFill_TypeOfContact.hxx +BRepFill_Voluved.cxx +BRepFill_Voluved.hxx \ No newline at end of file diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx index 10310e689d..88f20c46da 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx @@ -22,6 +22,8 @@ #include #include #include +#include +#include //======================================================================= //function : BRepOffsetAPI_MakeEvolved @@ -43,19 +45,29 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spin const Standard_Boolean AxeProf, const Standard_Boolean Solid, const Standard_Boolean ProfOnSpine, - const Standard_Real Tol) + const Standard_Boolean theIsVolume, + const Standard_Real Tol) { - gp_Ax3 Axis(gp_Pnt(0.,0.,0.), - gp_Dir(0.,0.,1.), - gp_Dir(1.,0.,0.)); - - if ( !AxeProf) { - Standard_Boolean POS; - BRepFill::Axe(Spine,Profil,Axis,POS,Tol); - if (ProfOnSpine && !POS) return; + if (theIsVolume) + { + myVolume.Perform(Spine, Profil, Tol); + } + else + { + gp_Ax3 Axis(gp_Pnt(0., 0., 0.), + gp_Dir(0., 0., 1.), + gp_Dir(1., 0., 0.)); + + if (!AxeProf) + { + Standard_Boolean POS; + BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion())); + if (ProfOnSpine && !POS) return; + } + + myEvolved.Perform(Spine, Profil, Axis, Join, Solid); } - myEvolved.Perform(Spine,Profil,Axis,Join,Solid); Build(); Done(); } @@ -72,20 +84,31 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spin const Standard_Boolean AxeProf, const Standard_Boolean Solid, const Standard_Boolean ProfOnSpine, - const Standard_Real Tol) + const Standard_Boolean theIsVolume, + const Standard_Real Tol) { - gp_Ax3 Axis(gp_Pnt(0.,0.,0.), - gp_Dir(0.,0.,1.), - gp_Dir(1.,0.,0.)); - - if ( !AxeProf) { - Standard_Boolean POS; - BRepFill::Axe(Spine,Profil,Axis,POS,Tol); - if (ProfOnSpine && !POS) return; + if (theIsVolume) + { + myVolume.Perform(TopoDS::Wire(TopoDS_Iterator(Spine).Value()), Profil, Tol); + } + else + { + gp_Ax3 Axis(gp_Pnt(0., 0., 0.), + gp_Dir(0., 0., 1.), + gp_Dir(1., 0., 0.)); + + if (!AxeProf) + { + Standard_Boolean POS; + BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion())); + if (ProfOnSpine && !POS) return; + } + + myEvolved.Perform(Spine, Profil, Axis, Join, Solid); } - myEvolved.Perform(Spine,Profil,Axis,Join,Solid); Build(); + Done(); } @@ -107,8 +130,16 @@ const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const void BRepOffsetAPI_MakeEvolved::Build() { - myShape = myEvolved.Shape(); - if (myEvolved.IsDone()) Done(); + if (myEvolved.IsDone()) + { + myShape = myEvolved.Shape(); + } + else if (myVolume.IsDone()) + { + myShape = myVolume.Shape(); + } + + Done(); } diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx index fc778e36a0..1a16adb5d9 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -66,7 +67,7 @@ public: Standard_EXPORT BRepOffsetAPI_MakeEvolved(); - Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001); + Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/); //! These constructors construct an evolved shape by sweeping the profile //! Profile along the spine Spine. @@ -88,7 +89,7 @@ public: //! axis passing along the vertex and the normal to the //! plane of the spine. At present, this is the only //! construction type implemented. - Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001); + Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/); Standard_EXPORT const BRepFill_Evolved& Evolved() const; @@ -118,9 +119,8 @@ protected: private: - BRepFill_Evolved myEvolved; - + BRepFill_Voluved myVolume; }; diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx index c24c81743c..ef0343c4a0 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx @@ -33,8 +33,6 @@ //purpose : //======================================================================= BRepOffsetAPI_MakePipeShell::BRepOffsetAPI_MakePipeShell(const TopoDS_Wire& Spine) - - { myPipe = new (BRepFill_PipeShell) (Spine); SetTolerance(); @@ -255,7 +253,7 @@ void BRepOffsetAPI_MakePipeShell::SetMaxSegments(const Standard_Integer NewMaxSe //function :Build() //purpose : //======================================================================= - void BRepOffsetAPI_MakePipeShell::Build() + void BRepOffsetAPI_MakePipeShell::Build() { Standard_Boolean Ok; Ok = myPipe->Build(); diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.hxx index 513acae207..cf17ee207e 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.hxx @@ -211,7 +211,7 @@ public: //! discontinuities are treated like round //! corner. The corner is treated as rotation //! of the profile around an axis which - //! passes through the point of the spine?s + //! passes through the point of the spine's //! fracture. This axis is based on cross //! product of directions tangent to the //! adjacent segments of the spine at their common point. @@ -276,7 +276,6 @@ private: Handle(BRepFill_PipeShell) myPipe; - }; diff --git a/src/BRepTest/BRepTest_SweepCommands.cxx b/src/BRepTest/BRepTest_SweepCommands.cxx index 8f3b51f120..4d3c1f2c19 100644 --- a/src/BRepTest/BRepTest_SweepCommands.cxx +++ b/src/BRepTest/BRepTest_SweepCommands.cxx @@ -237,34 +237,85 @@ Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char** if ( n < 4 ) return 1; Standard_Boolean IsAFace = Standard_False; - Standard_Boolean Solid = (!strcmp(a[0],"evolvedsolid")); + Standard_Boolean Solid = Standard_False; + Standard_Boolean isVolume = Standard_False; + Standard_Boolean hasToComputeAxes = Standard_False; + Standard_Real aTolerance = 0.0; + TopoDS_Shape Base; + TopoDS_Wire Prof; + + for (Standard_Integer i = 2; i < n; i++) + { + if (a[i][0] != '-') + { + di << "Error: wrong option!\n"; + return 1; + } + if (!Solid && !strcmp(a[i], "-solid")) + { + Solid = Standard_True; + continue; + } - - TopoDS_Shape Base = DBRep::Get(a[2],TopAbs_WIRE,Standard_False); - if ( Base.IsNull()) { - Base = DBRep::Get(a[2],TopAbs_FACE,Standard_False); - IsAFace = Standard_True; - } - if ( Base.IsNull()) return 1; - - TopoDS_Shape InpuTShape(DBRep::Get(a[3],TopAbs_WIRE,Standard_False)); - TopoDS_Wire Prof = TopoDS::Wire(InpuTShape); -// TopoDS_Wire Prof = -// TopoDS::Wire(DBRep::Get(a[3],TopAbs_WIRE,Standard_False)); - if ( Prof.IsNull()) return 1; - - if (IsAFace) { - TopoDS_Shape Volevo - = BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),Prof,GeomAbs_Arc,n == 4,Solid); - DBRep::Set(a[1],Volevo); + switch (a[i][1]) + { + case 's': + { + Base = DBRep::Get(a[++i], TopAbs_WIRE, Standard_False); + if (Base.IsNull()) + { + Base = DBRep::Get(a[i], TopAbs_FACE, Standard_False); + IsAFace = Standard_True; + } + } + break; + + case 'p': + { + Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False)); + } + break; + + case 'v': + { + isVolume = Standard_True; + } + break; + + case 'a': + { + hasToComputeAxes = Standard_True; + } + break; + + case 't': + { + aTolerance = Draw::Atof(a[++i]); + } + break; + + default: + di << "Error: Unknown option!\n"; + break; + } } - else { - TopoDS_Shape Volevo - = BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),Prof,GeomAbs_Arc,n == 4,Solid); - DBRep::Set(a[1],Volevo); + + if (Base.IsNull() || Prof.IsNull()) + { + di << "Error: Null-shapes are not allowed\n"; + return 1; } + TopoDS_Shape Volevo = IsAFace ? BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base), + Prof, GeomAbs_Arc, !hasToComputeAxes, + Solid, Standard_False, isVolume, aTolerance) : + BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base), + Prof, GeomAbs_Arc, !hasToComputeAxes, + Solid, Standard_False, isVolume, aTolerance); + + DBRep::Set(a[1],Volevo); + return 0; } @@ -785,7 +836,11 @@ static Standard_Integer buildsweep(Draw_Interpretor& di, Sweep->SetTransitionMode(Transition); } // Reading solid ? - if ((n>cur) && (!strcmp(a[cur],"-S")) ) mksolid = Standard_True; + if ((n > cur) && (!strcmp(a[cur], "-S"))) + { + mksolid = Standard_True; + ++cur; + } // Calcul le resultat Sweep->Build(); @@ -979,10 +1034,6 @@ void BRepTest::SweepCommands(Draw_Interpretor& theCommands) "evolved , no args to get help", __FILE__,evolved,g); - theCommands.Add("evolvedsolid", - "evolved , no args to get help", - __FILE__,evolved,g); - theCommands.Add("pruled", "pruled result Edge1/Wire1 Edge2/Wire2", __FILE__,pruled,g); diff --git a/src/LocOpe/LocOpe_DPrism.cxx b/src/LocOpe/LocOpe_DPrism.cxx index 8da855d765..362a0269f9 100644 --- a/src/LocOpe/LocOpe_DPrism.cxx +++ b/src/LocOpe/LocOpe_DPrism.cxx @@ -117,7 +117,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face& Spine, myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3); - myDPrism.Perform(mySpine,myProfile,gp::XOY()); + myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); if (myDPrism.IsDone()) { @@ -370,7 +370,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face& Spine, myProfile1 = BRepLib_MakeEdge(Vert4, Vert1); myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3); - myDPrism.Perform(mySpine,myProfile,gp::XOY()); + myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); if (myDPrism.IsDone()) { diff --git a/src/NCollection/NCollection_List.hxx b/src/NCollection/NCollection_List.hxx index ded27c56d9..0a16c0ad5b 100644 --- a/src/NCollection/NCollection_List.hxx +++ b/src/NCollection/NCollection_List.hxx @@ -142,7 +142,8 @@ public: PAppend(pNew, theIter); } - //! Append another list at the end + //! Append another list at the end. + //! After this operation, theOther list will be cleared. void Append (NCollection_List& theOther) { if (this == &theOther || theOther.Extent()<1) diff --git a/src/math/math_NewtonMinimum.cxx b/src/math/math_NewtonMinimum.cxx index dd326dc1a9..76c2b8cd1b 100644 --- a/src/math/math_NewtonMinimum.cxx +++ b/src/math/math_NewtonMinimum.cxx @@ -165,15 +165,19 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F, Standard_Real aMult = RealLast(); for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++) { + const Standard_Real anAbsStep = Abs(TheStep(anIdx)); + if (anAbsStep < gp::Resolution()) + continue; + if (suivant->Value(anIdx) < myLeft(anIdx)) { - Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / Abs(TheStep(anIdx)); + Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / anAbsStep; aMult = Min (aValue, aMult); } if (suivant->Value(anIdx) > myRight(anIdx)) { - Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / Abs(TheStep(anIdx)); + Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / anAbsStep; aMult = Min (aValue, aMult); } } diff --git a/tests/bugs/modalg_4/pro19424 b/tests/bugs/modalg_4/pro19424 index d36810d59b..77fab06a23 100755 --- a/tests/bugs/modalg_4/pro19424 +++ b/tests/bugs/modalg_4/pro19424 @@ -8,7 +8,7 @@ checkshape b restore [locate_data_file pro19424b.brep] p checkshape p -if [catch {evolved result b p o } catch_result] { +if [catch {evolved result -s b -p p -a } catch_result] { puts "Faulty PRO19424 : function EVOLVED works wrongly" } else { puts "PRO19424 OK: function EVOLVED works properly" diff --git a/tests/bugs/modalg_6/bug26470_1 b/tests/bugs/modalg_6/bug26470_1 index 72b5716ff2..8abebafea5 100644 --- a/tests/bugs/modalg_6/bug26470_1 +++ b/tests/bugs/modalg_6/bug26470_1 @@ -8,4 +8,4 @@ puts "" restore [locate_data_file OCC26470-ClosedWire.brep] a restore [locate_data_file OCC26470-wprof1.brep] b -evolved res a b o +evolved res -s a -p b -a diff --git a/tests/bugs/modalg_6/bug26470_2 b/tests/bugs/modalg_6/bug26470_2 index c2cdf9b7f3..404fca3064 100644 --- a/tests/bugs/modalg_6/bug26470_2 +++ b/tests/bugs/modalg_6/bug26470_2 @@ -8,5 +8,5 @@ puts "" restore [locate_data_file OCC26470-ClosedWire.brep] a restore [locate_data_file OCC26470-wprof2.brep] b -evolved res a b o +evolved res -s a -p b -a checkshape res diff --git a/tests/evolved/begin b/tests/evolved/begin new file mode 100644 index 0000000000..0705f2483e --- /dev/null +++ b/tests/evolved/begin @@ -0,0 +1,13 @@ +# To prevent loops limit to 10 minutes +cpulimit 60 + +if { [array get Draw_Groups "TOPOLOGY Feature commands"] == "" } { + pload TOPTEST +} + +if { [info exists imagedir] == 0 } { + set imagedir . +} +if { [info exists test_image ] == 0 } { + set test_image photo +} diff --git a/tests/evolved/end b/tests/evolved/end new file mode 100644 index 0000000000..57901e2abe --- /dev/null +++ b/tests/evolved/end @@ -0,0 +1,2 @@ +# to end a test script +puts "TEST COMPLETED" diff --git a/tests/evolved/evolved/begin b/tests/evolved/evolved/begin new file mode 100644 index 0000000000..2d2ece6e35 --- /dev/null +++ b/tests/evolved/evolved/begin @@ -0,0 +1 @@ +set subgroup evolved diff --git a/tests/evolved/evolved/bug26470_1 b/tests/evolved/evolved/bug26470_1 new file mode 100644 index 0000000000..8abebafea5 --- /dev/null +++ b/tests/evolved/evolved/bug26470_1 @@ -0,0 +1,11 @@ +puts "========" +puts "OCC26470" +puts "========" +puts "" +################################################## +# BRepFill_Evolved: exception and invalid result +################################################## + +restore [locate_data_file OCC26470-ClosedWire.brep] a +restore [locate_data_file OCC26470-wprof1.brep] b +evolved res -s a -p b -a diff --git a/tests/evolved/evolved/bug26470_2 b/tests/evolved/evolved/bug26470_2 new file mode 100644 index 0000000000..404fca3064 --- /dev/null +++ b/tests/evolved/evolved/bug26470_2 @@ -0,0 +1,12 @@ +puts "========" +puts "OCC26470" +puts "========" +puts "" +################################################## +# BRepFill_Evolved: exception and invalid result +################################################## + +restore [locate_data_file OCC26470-ClosedWire.brep] a +restore [locate_data_file OCC26470-wprof2.brep] b +evolved res -s a -p b -a +checkshape res diff --git a/tests/evolved/evolved/pro19424 b/tests/evolved/evolved/pro19424 new file mode 100644 index 0000000000..77fab06a23 --- /dev/null +++ b/tests/evolved/evolved/pro19424 @@ -0,0 +1,20 @@ + +puts "==========" +puts "PRO19424" +puts "==========" + +restore [locate_data_file pro19424a.brep] b +checkshape b +restore [locate_data_file pro19424b.brep] p +checkshape p + +if [catch {evolved result -s b -p p -a } catch_result] { + puts "Faulty PRO19424 : function EVOLVED works wrongly" +} else { + puts "PRO19424 OK: function EVOLVED works properly" +} + +checkprops result -s 246.506 +checkshape result +checkview -display result -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/grids.list b/tests/evolved/grids.list new file mode 100644 index 0000000000..7c8d39711b --- /dev/null +++ b/tests/evolved/grids.list @@ -0,0 +1,2 @@ +001 evolved +002 voluved diff --git a/tests/evolved/parse.rules b/tests/evolved/parse.rules new file mode 100644 index 0000000000..610d206403 --- /dev/null +++ b/tests/evolved/parse.rules @@ -0,0 +1 @@ +FAILED /\bFaulty\b/ bad shape diff --git a/tests/evolved/voluved/AGT001 b/tests/evolved/voluved/AGT001 new file mode 100644 index 0000000000..7c546d529f --- /dev/null +++ b/tests/evolved/voluved/AGT001 @@ -0,0 +1,24 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +profile p F -1 10 TT -1 -1 C 1 90 TT 10 -1 W +polyline t -1 -1 0 0 -1.5 5 +evolved result -s p -p t -a -solid -v + +checkprops result -s 268.774 -v 245.265 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.5e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT002 b/tests/evolved/voluved/AGT002 new file mode 100644 index 0000000000..670be588cb --- /dev/null +++ b/tests/evolved/voluved/AGT002 @@ -0,0 +1,24 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +polyline p 0 0 0 0 10 0 20 10 0 20 0 0 13 0 0 13 5 0 6 5 0 6 0 0 0 0 0 +polyline t -2 2 0 0 2 5 0 2 10 1 2 10 1 2 0 -2 2 0 +evolved result -s p -p t -a -solid -v + +checkprops result -s 1649.58 -v 1023.79 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.5e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT003 b/tests/evolved/voluved/AGT003 new file mode 100644 index 0000000000..3b3c029259 --- /dev/null +++ b/tests/evolved/voluved/AGT003 @@ -0,0 +1,24 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +polyline p 0 0 0 0 10 0 20 10 0 20 0 0 13 0 0 13 5 0 6 5 0 6 0 0 0 0 0 +polyline t -1 2 0 0 1 5 0 1 10 0.5 0.5 10 0.5 0.5 0 +evolved result -s p -p t -a -solid -v + +checkprops result -s 1803.56 -v 532.942 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 5.0e-6 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT004 b/tests/evolved/voluved/AGT004 new file mode 100644 index 0000000000..fbf058e669 --- /dev/null +++ b/tests/evolved/voluved/AGT004 @@ -0,0 +1,25 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +profile p X 10 Y 2 X -10 W +polyline t -1 1 0 1 1 10 +evolved result -s p -p t -a -solid -v + +checkprops result -s 287.517 -v 211.903 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +# See issue #0029657 +#if {[regexp "Faulties" [bopargcheck result]]} { +# puts "Error: bopargcheck has found some faulties in res2" +#} + +checkmaxtol result -ref 1.5e-007 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT005 b/tests/evolved/voluved/AGT005 new file mode 100644 index 0000000000..9d4474379f --- /dev/null +++ b/tests/evolved/voluved/AGT005 @@ -0,0 +1,24 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +profile p X 10 Y 2 X -10 W +polyline t -1 1 0 1.2 1 10 +evolved result -s p -p t -a -solid -v + +checkprops result -s 266.546 -v 192.639 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.5e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT006 b/tests/evolved/voluved/AGT006 new file mode 100644 index 0000000000..b296f85072 --- /dev/null +++ b/tests/evolved/voluved/AGT006 @@ -0,0 +1,25 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +# Different results in command "evolved" with and without "-v" +profile p X 10 Y 2 X -10 W +profile t O 0 1 0 P 0 1 0 0 0 1 X 5 T -1 2 WW +evolved result -s p -p t -a -solid -v + +checkprops result -s 137.58 -v 80.9221 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 0.00011504480776721356 + +smallview +don result p t +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT007 b/tests/evolved/voluved/AGT007 new file mode 100644 index 0000000000..df37ded4cd --- /dev/null +++ b/tests/evolved/voluved/AGT007 @@ -0,0 +1,28 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +# Result contains intersected faces +profile p X 15 C 1 90 Y 5 X -7 Y -2 C -1 90 X -8 W +profile t O 0 1 0 P 0 1 0 0 0 1 X 5 T -1 2 WW +evolved result -s p -p t -a -solid -v + +checkprops result -s 308.284 -v 195.169 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.5e-7 + +regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance result] full toler +checkreal MAXTOL $toler 1.5e-7 0.0 0.1 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT008 b/tests/evolved/voluved/AGT008 new file mode 100644 index 0000000000..fb4f4aceac --- /dev/null +++ b/tests/evolved/voluved/AGT008 @@ -0,0 +1,25 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +# Different results with and without "-v"; internal/intersecting faces created +profile p X 10 Y 2 X -10 W +profile t O 0 1 0 P 0 1 0 0 0 1 X 2 RR -45 C 1 90 T -1 2 WW +evolved result -s p -p t -a -solid -v + +checkprops result -s 129.967 -v 70.6801 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 3.25e-007 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/AGT009 b/tests/evolved/voluved/AGT009 new file mode 100644 index 0000000000..455b917084 --- /dev/null +++ b/tests/evolved/voluved/AGT009 @@ -0,0 +1,25 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +# Solids are correctly built but r_1 should be eliminated as junk +profile p X 10 Y 2 X -10 W +profile t O 0 1 0 P 0 1 0 0 0 1 RR 30 C -10 60 WW +evolved result -s p -p t -a -solid -v + +checkprops result -s 308.284 -v 195.169 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.5e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/HMC001 b/tests/evolved/voluved/HMC001 new file mode 100644 index 0000000000..45b31cd003 --- /dev/null +++ b/tests/evolved/voluved/HMC001 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire00.brep] sw +restore [locate_data_file bug29523_cut_toolwire00.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 1.94263e+010 -v 6.2718e+013 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 0.00013577499521488808 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC002 b/tests/evolved/voluved/HMC002 new file mode 100644 index 0000000000..2900702e2f --- /dev/null +++ b/tests/evolved/voluved/HMC002 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire01.brep] sw +restore [locate_data_file bug29523_cut_toolwire01.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 2.18924e+011 -v 2.47705e+014 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.0e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC003 b/tests/evolved/voluved/HMC003 new file mode 100644 index 0000000000..08d0d09468 --- /dev/null +++ b/tests/evolved/voluved/HMC003 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire02.brep] sw +restore [locate_data_file bug29523_cut_toolwire02.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 2.18616e+011 -v 2.46411e+014 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 1.6e-5 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC004 b/tests/evolved/voluved/HMC004 new file mode 100644 index 0000000000..194f839459 --- /dev/null +++ b/tests/evolved/voluved/HMC004 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire03.brep] sw +restore [locate_data_file bug29523_cut_toolwire03.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 3.02832e+010 -v 4.97434e+013 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 7.0e-7 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC005 b/tests/evolved/voluved/HMC005 new file mode 100644 index 0000000000..654640ebb8 --- /dev/null +++ b/tests/evolved/voluved/HMC005 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire04.brep] sw +restore [locate_data_file bug29523_cut_toolwire04.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 1.94263e+010 -v 6.2718e+013 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 0.00013577500067185611 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC006 b/tests/evolved/voluved/HMC006 new file mode 100644 index 0000000000..7b200551af --- /dev/null +++ b/tests/evolved/voluved/HMC006 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire05.brep] sw +restore [locate_data_file bug29523_cut_toolwire05.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 2.84249e+010 -v 8.95554e+013 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 4.4607852024588505e-007 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC007 b/tests/evolved/voluved/HMC007 new file mode 100644 index 0000000000..83158f3b73 --- /dev/null +++ b/tests/evolved/voluved/HMC007 @@ -0,0 +1,26 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +restore [locate_data_file bug29523_cut_extrudewire06.brep] sw +restore [locate_data_file bug29523_cut_toolwire06.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 1.99565e+011 -v 6.75431e+014 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 4.7e-6 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC008 b/tests/evolved/voluved/HMC008 new file mode 100644 index 0000000000..77cd8f8e8a --- /dev/null +++ b/tests/evolved/voluved/HMC008 @@ -0,0 +1,28 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +cpulimit 100 + +restore [locate_data_file bug29523_cut_extrudewire07.brep] sw +restore [locate_data_file bug29523_cut_toolwire07.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 1.99565e+011 -v 6.75431e+014 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 4.7e-6 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/HMC009 b/tests/evolved/voluved/HMC009 new file mode 100644 index 0000000000..c239295839 --- /dev/null +++ b/tests/evolved/voluved/HMC009 @@ -0,0 +1,28 @@ +puts "==========" +puts "OCC29523" +puts "==========" + +cpulimit 100 + +restore [locate_data_file bug29523_cut_extrudewire08.brep] sw +restore [locate_data_file bug29523_cut_toolwire08.brep] tw + +evolved result -s sw -p tw -solid -a -v + +checkprops result -s 1.99565e+011 -v 6.75431e+014 +checkshape result + +checknbshapes result -solid 1 -shell 1 + +if {[regexp "Faulties" [bopargcheck result]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkmaxtol result -ref 4.7e-6 + +smallview +don result sw tw +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png + diff --git a/tests/evolved/voluved/begin b/tests/evolved/voluved/begin new file mode 100644 index 0000000000..1f09ffe9a7 --- /dev/null +++ b/tests/evolved/voluved/begin @@ -0,0 +1 @@ +set subgroup voluved diff --git a/tests/evolved/voluved/bug26470_1 b/tests/evolved/voluved/bug26470_1 new file mode 100644 index 0000000000..67b5f243b3 --- /dev/null +++ b/tests/evolved/voluved/bug26470_1 @@ -0,0 +1,11 @@ +puts "========" +puts "OCC26470" +puts "========" +puts "" +################################################## +# BRepFill_Evolved: exception and invalid result +################################################## + +restore [locate_data_file OCC26470-ClosedWire.brep] a +restore [locate_data_file OCC26470-wprof1.brep] b +evolved res -s a -p b -a -v diff --git a/tests/evolved/voluved/bug26470_2 b/tests/evolved/voluved/bug26470_2 new file mode 100644 index 0000000000..039e1e9be9 --- /dev/null +++ b/tests/evolved/voluved/bug26470_2 @@ -0,0 +1,12 @@ +puts "========" +puts "OCC26470" +puts "========" +puts "" +################################################## +# BRepFill_Evolved: exception and invalid result +################################################## + +restore [locate_data_file OCC26470-ClosedWire.brep] a +restore [locate_data_file OCC26470-wprof2.brep] b +evolved res -s a -p b -a -v +checkshape res diff --git a/tests/evolved/voluved/pro19424 b/tests/evolved/voluved/pro19424 new file mode 100644 index 0000000000..c86eb48d00 --- /dev/null +++ b/tests/evolved/voluved/pro19424 @@ -0,0 +1,20 @@ + +puts "==========" +puts "PRO19424" +puts "==========" + +restore [locate_data_file pro19424a.brep] b +checkshape b +restore [locate_data_file pro19424b.brep] p +checkshape p + +if [catch {evolved result -s b -p p -a -v } catch_result] { + puts "Faulty PRO19424 : function EVOLVED works wrongly" +} else { + puts "PRO19424 OK: function EVOLVED works properly" +} + +checkprops result -s 246.506 +checkshape result +checkview -display result -2d -path ${imagedir}/${test_image}.png +