From 4f4d7479688645533dd1c4cb03c06890a236efbc Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Nov 2015 11:59:41 +0100 Subject: [PATCH] + fix undefined behaviour in determining grid length for planar meshes --- src/Mod/Mesh/App/Core/Grid.cpp | 78 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/Mod/Mesh/App/Core/Grid.cpp b/src/Mod/Mesh/App/Core/Grid.cpp index fb8654640..063add3a2 100644 --- a/src/Mod/Mesh/App/Core/Grid.cpp +++ b/src/Mod/Mesh/App/Core/Grid.cpp @@ -261,48 +261,50 @@ void MeshGrid::Position (const Base::Vector3f &rclPoint, unsigned long &rulX, un void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids) { - // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen - // pro Grid sollen ca. 10 (?!?!) Facets liegen - // bzw. max Grids sollten 10000 nicht ueberschreiten - Base::BoundBox3f clBBMeshEnlarged = _pclMesh->GetBoundBox(); - float fVolElem; + // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen + // pro Grid sollen ca. 10 (?!?!) Facets liegen + // bzw. max Grids sollten 10000 nicht ueberschreiten + Base::BoundBox3f clBBMeshEnlarged = _pclMesh->GetBoundBox(); + float fGridLen = 0; - // Stelle sicher, dass die Bounding box ein Volumen > 0 besitzt - float fLenX = clBBMeshEnlarged.LengthX(); - float fLenY = clBBMeshEnlarged.LengthY(); - float fLenZ = clBBMeshEnlarged.LengthZ(); - float fMax = 0.005 * std::max(std::max(fLenX, fLenY), fLenZ); - // Falls Bounding box zu einem Punkt degeneriert ist - if (fMax == 0) { - _ulCtGridsX = 1; - _ulCtGridsY = 1; - _ulCtGridsZ = 1; - return; - } - if (fLenX == 0) { - clBBMeshEnlarged.MinX -= fMax; - clBBMeshEnlarged.MaxX += fMax; - } - if (fLenY == 0) { - clBBMeshEnlarged.MinY -= fMax; - clBBMeshEnlarged.MaxY += fMax; - } - if (fLenZ == 0) { - clBBMeshEnlarged.MinZ -= fMax; - clBBMeshEnlarged.MaxZ += fMax; - } + float fLenX = clBBMeshEnlarged.LengthX(); + float fLenY = clBBMeshEnlarged.LengthY(); + float fLenZ = clBBMeshEnlarged.LengthZ(); - if (_ulCtElements > (ulMaxGrids * ulCtGrid)) - fVolElem = (clBBMeshEnlarged.LengthX() * clBBMeshEnlarged.LengthY() * clBBMeshEnlarged.LengthZ()) / float(ulMaxGrids * ulCtGrid); - else - fVolElem = (clBBMeshEnlarged.LengthX() * clBBMeshEnlarged.LengthY() * clBBMeshEnlarged.LengthZ()) / float(_ulCtElements); + float fVolume = fLenX * fLenY * fLenZ; + if (fVolume > 0.0f) { + float fVolElem; + if (_ulCtElements > (ulMaxGrids * ulCtGrid)) + fVolElem = (fLenX * fLenY * fLenZ) / float(ulMaxGrids * ulCtGrid); + else + fVolElem = (fLenX * fLenY * fLenZ) / float(_ulCtElements); - float fVol = fVolElem * float(ulCtGrid); - float fGridLen = float(pow((float)fVol,(float) 1.0f / 3.0f)); + float fVol = fVolElem * float(ulCtGrid); + fGridLen = float(pow(fVol, 1.0f / 3.0f)); + } + else { + // Planare Bounding box + float fArea = fLenX * fLenY + fLenX * fLenZ + fLenY * fLenZ; + float fAreaElem; + if (_ulCtElements > (ulMaxGrids * ulCtGrid)) + fAreaElem = fArea / float(ulMaxGrids * ulCtGrid); + else + fAreaElem = fArea / float(_ulCtElements); - _ulCtGridsX = std::max((unsigned long)(clBBMeshEnlarged.LengthX() / fGridLen), 1); - _ulCtGridsY = std::max((unsigned long)(clBBMeshEnlarged.LengthY() / fGridLen), 1); - _ulCtGridsZ = std::max((unsigned long)(clBBMeshEnlarged.LengthZ() / fGridLen), 1); + fGridLen = sqrt(fAreaElem * float(ulCtGrid)); + } + + if (fGridLen > 0) { + _ulCtGridsX = std::max(static_cast(fLenX / fGridLen), 1); + _ulCtGridsY = std::max(static_cast(fLenY / fGridLen), 1); + _ulCtGridsZ = std::max(static_cast(fLenZ / fGridLen), 1); + } + else { + // Degenerated grid + _ulCtGridsX = 1; + _ulCtGridsY = 1; + _ulCtGridsZ = 1; + } } void MeshGrid::CalculateGridLength (int iCtGridPerAxis)