From: emv Date: Wed, 14 Aug 2019 10:19:38 +0000 (+0300) Subject: 0030868: Modeling Algorithms - BRepBuilderAPI_GTransform hangs (2) X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=3a65e8062383aa107b6789dc04491afe4542122f;p=occt-copy.git 0030868: Modeling Algorithms - BRepBuilderAPI_GTransform hangs (2) Attempt on healing the BSpline surface with the pole in which the DU and DV vectors are almost parallel by moving the pole outside. --- diff --git a/src/BRepOffset/BRepOffset.cxx b/src/BRepOffset/BRepOffset.cxx index 7fac35f35f..00546a20b6 100644 --- a/src/BRepOffset/BRepOffset.cxx +++ b/src/BRepOffset/BRepOffset.cxx @@ -311,6 +311,74 @@ Handle(Geom_Surface) BRepOffset::CollapseSingularities (const Handle(Geom_Surfac } } + if (aPoles.RowLength() > 2 && aPoles.ColLength() > 2) + { + // Check if the adjacent sides of the surfaces are collapsed, i.e. if normal is + // is impossible to compute in the 'corners' + // If such corner is found, move the pole outside a bit, to make the 'corner' more obvious + + // We are dealing with four points: + // (UMin, VMin), (UMin, VMax), (UMax, VMin), (UMax, VMax) + // or (1, 1), (1, NbVPoles), (NbUPoles, 1), (NbUPoles, NbUPoles) + + Handle(Geom_Surface)& aSurf = aCopy.IsNull() ? aBSpline : aCopy; + + Standard_Real anU[2], aV[2]; + aBSpline->Bounds (anU[0], anU[1], aV[0], aV[1]); + + Standard_Integer aCornerPoleUIndex[2] = { aPoles.LowerRow(), aPoles.UpperRow() }; + Standard_Integer aCornerPoleVIndex[2] = { aPoles.LowerCol(), aPoles.UpperCol() }; + + Standard_Integer aPoleInsideUIndex[2] = { aCornerPoleUIndex[0] + 1, aCornerPoleUIndex[1] - 1 }; + Standard_Integer aPoleInsideVIndex[2] = { aCornerPoleVIndex[0] + 1, aCornerPoleVIndex[1] - 1 }; + + for (int iU = 0; iU < 2; ++iU) + { + for (int iV = 0; iV < 2; ++iV) + { + gp_Pnt aP; + gp_Vec aDU, aDV; + aSurf->D1 (anU[iU], aV[iV], aP, aDU, aDV); + + gp_Vec aSNorm = aDU ^ aDV; + if (aSNorm.SquareMagnitude() < thePrecision * thePrecision) + { + if (aCopy.IsNull()) + { + aCopy = Handle (Geom_BSplineSurface)::DownCast (theSurface->Copy()); + aSurf = aCopy; + } + + // Move the pole outside surface + + // Get the nearest pole inside + gp_Pnt aPInside = aPoles.Value (aPoleInsideUIndex[iU], aPoleInsideVIndex[iV]); + gp_Vec aVecOutside (aPInside, aP); + + aDU.Rotate (gp_Ax1 (aP, aDU ^ aVecOutside), M_PI_2); + aDV.Rotate (gp_Ax1 (aP, aDV ^ aVecOutside), M_PI_2); + + aVecOutside = (aDU + aDV).Normalized(); + + int k = 1; + while (aSNorm.SquareMagnitude() < thePrecision * thePrecision && k <= 1024) + { + k *= 2; + aP.Translate (k * Precision::Confusion() * aVecOutside); + aCopy->SetPole (aCornerPoleUIndex[iU], aCornerPoleVIndex[iV], aP); + + aCopy->D1 (anU[iU], aV[iV], aP, aDU, aDV); + gp_Vec aN1 = aDU ^ aDV; + + //if (aN1 * aSNorm < 0.0) + // break; + aSNorm = aN1; + } + } + } + } + } + if (! aCopy.IsNull()) return aCopy; }