From 032881f4fb6a2e8115a11c2c1109c7c03daa45c3 Mon Sep 17 00:00:00 2001 From: nbv Date: Mon, 15 Aug 2016 15:57:11 +0300 Subject: [PATCH] 0027774: Constructor GeomPlate_BuildAveragePlane crashes if two input normals are parallel to each other Normalization has been avoided in case of impossibility. --- src/GeomPlate/GeomPlate_BuildAveragePlane.cxx | 90 ++++++++++++------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/src/GeomPlate/GeomPlate_BuildAveragePlane.cxx b/src/GeomPlate/GeomPlate_BuildAveragePlane.cxx index 79403f295e..c058110ec1 100644 --- a/src/GeomPlate/GeomPlate_BuildAveragePlane.cxx +++ b/src/GeomPlate/GeomPlate_BuildAveragePlane.cxx @@ -106,10 +106,24 @@ myPts(Pts) if (NN == 1) BestVec = Normals(1); else if (NN == 2) + { + BestVec = Normals(1) + Normals(2); + const Standard_Real aSqMagn = BestVec.SquareMagnitude(); + if(aSqMagn < Precision::SquareConfusion()) { - BestVec = Normals(1) + Normals(2); - BestVec.Normalize(); + const Standard_Real aSq1 = Normals(1).SquareMagnitude(), + aSq2 = Normals(2).SquareMagnitude(); + + if(aSq1 > aSq2) + BestVec = Normals(1).Normalized(); + else + BestVec = Normals(2).Normalized(); } + else + { + BestVec.Divide(sqrt(aSqMagn)); + } + } else //the common case { Standard_Real MaxAngle = 0.; @@ -131,38 +145,46 @@ myPts(Pts) k = 1; for (i = 1; i <= NN-1; i++) - for (j = i+1; j <= NN; j++) - { - Standard_Real Step = MaxAngle/Nint; - Vec = Normals(i) + Normals(j); - Vec.Normalize(); - - Cross1 = Normals(i) ^ Normals(j); - Cross2 = Vec ^ Cross1; - gp_Ax1 Axe( gp_Pnt(0,0,0), Cross2 ); - - Vec1 = Vec.Rotated( Axe, -MaxAngle ); - //Vec2 = Vec.Rotated( Axe, MaxAngle ); - - OptScal(k) = RealFirst(); - for (n = 0; n <= 2*Nint; n++) - { - Vec1.Rotate( Axe, Step ); - Standard_Real minScal = RealLast(); - for (m = 1; m <= NN; m++) - { - Standard_Real Scal = Vec1 * Normals(m); - if (Scal < minScal) - minScal = Scal; - } - if (minScal > OptScal(k)) - { - OptScal(k) = minScal; - OptVec(k) = Vec1; - } - } - k++; - } // for i, for j + for (j = i+1; j <= NN; j++, k++) + { + OptScal(k) = RealFirst(); + + Standard_Real Step = MaxAngle/Nint; + Vec = Normals(i) + Normals(j); + + const Standard_Real aSqMagn = Vec.SquareMagnitude(); + + if(aSqMagn < Precision::SquareConfusion()) + { + continue; + } + + Vec.Divide(sqrt(aSqMagn)); + + Cross1 = Normals(i) ^ Normals(j); + Cross2 = Vec ^ Cross1; + gp_Ax1 Axe( gp_Pnt(0,0,0), Cross2 ); + + Vec1 = Vec.Rotated( Axe, -MaxAngle ); + //Vec2 = Vec.Rotated( Axe, MaxAngle ); + + for (n = 0; n <= 2*Nint; n++) + { + Vec1.Rotate( Axe, Step ); + Standard_Real minScal = RealLast(); + for (m = 1; m <= NN; m++) + { + Standard_Real Scal = Vec1 * Normals(m); + if (Scal < minScal) + minScal = Scal; + } + if (minScal > OptScal(k)) + { + OptScal(k) = minScal; + OptVec(k) = Vec1; + } + } + } // for i, for j //Find maximum among all maximums Standard_Real BestScal = RealFirst();