From: jfa Date: Fri, 10 Apr 2009 11:06:03 +0000 (+0000) Subject: Bug 0020233: Infinite loop in boolean operation with a sphere with r=0 X-Git-Tag: V4_1_5rc1~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=3313eb5f07aceeec66e441705e85e315c179ea70;p=modules%2Fgeom.git Bug 0020233: Infinite loop in boolean operation with a sphere with r=0 --- diff --git a/src/GEOMImpl/GEOMImpl_CircleDriver.cxx b/src/GEOMImpl/GEOMImpl_CircleDriver.cxx index 1b1d0ea9e..662345381 100644 --- a/src/GEOMImpl/GEOMImpl_CircleDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_CircleDriver.cxx @@ -78,65 +78,92 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; if (aType == CIRCLE_PNT_VEC_R) { - Handle(GEOM_Function) aRefPoint = aCI.GetCenter(); + // Center + gp_Pnt aP = gp::Origin(); + Handle(GEOM_Function) aRefPoint = aCI.GetCenter(); + if (!aRefPoint.IsNull()) { + TopoDS_Shape aShapePnt = aRefPoint->GetValue(); + if (aShapePnt.ShapeType() != TopAbs_VERTEX) { + Standard_ConstructionError::Raise + ("Circle creation aborted: invalid center argument, must be a point"); + } + aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); + } + // Normal + gp_Vec aV = gp::DZ(); Handle(GEOM_Function) aRefVector = aCI.GetVector(); - TopoDS_Shape aShapePnt = aRefPoint->GetValue(); - TopoDS_Shape aShapeVec = aRefVector->GetValue(); - if (aShapePnt.ShapeType() == TopAbs_VERTEX && - aShapeVec.ShapeType() == TopAbs_EDGE) { - gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); + if (!aRefVector.IsNull()) { + TopoDS_Shape aShapeVec = aRefVector->GetValue(); + if (aShapeVec.ShapeType() != TopAbs_EDGE) { + Standard_ConstructionError::Raise + ("Circle creation aborted: invalid vector argument, must be a vector or an edge"); + } TopoDS_Edge anE = TopoDS::Edge(aShapeVec); TopoDS_Vertex V1, V2; TopExp::Vertices(anE, V1, V2, Standard_True); if (!V1.IsNull() && !V2.IsNull()) { - gp_Vec aV (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2)); - gp_Ax2 anAxes (aP, aV); - gp_Circ aCirc (anAxes, aCI.GetRadius()); - aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); + aV = gp_Vec(BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2)); + if (aV.Magnitude() < gp::Resolution()) { + Standard_ConstructionError::Raise + ("Circle creation aborted: vector of zero length is given"); + } } } + // Axes + gp_Ax2 anAxes (aP, aV); + // Radius + double anR = aCI.GetRadius(); + char aMsg[] = "Circle creation aborted: radius value less than 1e-07 is not acceptable"; + if (anR < Precision::Confusion()) + Standard_ConstructionError::Raise(aMsg); + // Circle + gp_Circ aCirc (anAxes, anR); + aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); } - else if (aType == CIRCLE_CENTER_TWO_PNT) { - Handle(GEOM_Function) aRefPoint1 = aCI.GetPoint1(); - Handle(GEOM_Function) aRefPoint2 = aCI.GetPoint2(); - Handle(GEOM_Function) aRefPoint3 = aCI.GetPoint3(); - TopoDS_Shape aShapePnt1 = aRefPoint1->GetValue(); - TopoDS_Shape aShapePnt2 = aRefPoint2->GetValue(); - TopoDS_Shape aShapePnt3 = aRefPoint3->GetValue(); - if (aShapePnt1.ShapeType() == TopAbs_VERTEX && aShapePnt2.ShapeType() == TopAbs_VERTEX && - aShapePnt3.ShapeType() == TopAbs_VERTEX) - { - gp_Pnt aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt1)); - gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt2)); - gp_Pnt aP3 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt3)); - - if (aP1.Distance(aP2) < gp::Resolution() || - aP1.Distance(aP3) < gp::Resolution() || - aP2.Distance(aP3) < gp::Resolution()) - Standard_ConstructionError::Raise("Circle creation aborted: coincident points given"); - if (gp_Vec(aP1, aP2).IsParallel(gp_Vec(aP1, aP3), Precision::Angular())) - Standard_ConstructionError::Raise("Circle creation aborted: points lay on one line"); - double x, y, z, x1, y1, z1, x2, y2, z2, dx, dy, dz, dx2, dy2, dz2, dx3, dy3, dz3, aRadius; - //Calculations for Radius - x = aP1.X(); y = aP1.Y(); z = aP1.Z(); - x1 = aP2.X(); y1 = aP2.Y(); z1 = aP2.Z(); - dx = x1 - x; - dy = y1 - y; - dz = z1 - z; - aRadius = sqrt(dx*dx + dy*dy + dz*dz); - //Calculations for Plane Vector - x2 = aP3.X(); y2 = aP3.Y(); z2 = aP3.Z(); - dx2 = x2 - x; dy2 = y2 - y; dz2 = z2 - z; - dx3 = ((dy*dz2) - (dy2*dz))/100; - dy3 = ((dx2*dz) - (dx*dz2))/100; - dz3 = ((dx*dy2) - (dx2*dy))/100; - //Make Plane Vector - gp_Dir aDir ( dx3, dy3, dz3 ); - //Make Circle - gp_Ax2 anAxes (aP1, aDir); - gp_Circ aCirc (anAxes, aRadius); - aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); - } + else if (aType == CIRCLE_CENTER_TWO_PNT) { + Handle(GEOM_Function) aRefPoint1 = aCI.GetPoint1(); + Handle(GEOM_Function) aRefPoint2 = aCI.GetPoint2(); + Handle(GEOM_Function) aRefPoint3 = aCI.GetPoint3(); + TopoDS_Shape aShapePnt1 = aRefPoint1->GetValue(); + TopoDS_Shape aShapePnt2 = aRefPoint2->GetValue(); + TopoDS_Shape aShapePnt3 = aRefPoint3->GetValue(); + if (aShapePnt1.ShapeType() == TopAbs_VERTEX && + aShapePnt2.ShapeType() == TopAbs_VERTEX && + aShapePnt3.ShapeType() == TopAbs_VERTEX) + { + gp_Pnt aP1 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt1)); + gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt2)); + gp_Pnt aP3 = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt3)); + + if (aP1.Distance(aP2) < gp::Resolution() || + aP1.Distance(aP3) < gp::Resolution() || + aP2.Distance(aP3) < gp::Resolution()) + Standard_ConstructionError::Raise("Circle creation aborted: coincident points given"); + + if (gp_Vec(aP1, aP2).IsParallel(gp_Vec(aP1, aP3), Precision::Angular())) + Standard_ConstructionError::Raise("Circle creation aborted: points lay on one line"); + + double x, y, z, x1, y1, z1, x2, y2, z2, dx, dy, dz, dx2, dy2, dz2, dx3, dy3, dz3, aRadius; + //Calculations for Radius + x = aP1.X(); y = aP1.Y(); z = aP1.Z(); + x1 = aP2.X(); y1 = aP2.Y(); z1 = aP2.Z(); + dx = x1 - x; + dy = y1 - y; + dz = z1 - z; + aRadius = sqrt(dx*dx + dy*dy + dz*dz); + //Calculations for Plane Vector + x2 = aP3.X(); y2 = aP3.Y(); z2 = aP3.Z(); + dx2 = x2 - x; dy2 = y2 - y; dz2 = z2 - z; + dx3 = ((dy*dz2) - (dy2*dz))/100; + dy3 = ((dx2*dz) - (dx*dz2))/100; + dz3 = ((dx*dy2) - (dx2*dy))/100; + //Make Plane Vector + gp_Dir aDir ( dx3, dy3, dz3 ); + //Make Circle + gp_Ax2 anAxes (aP1, aDir); + gp_Circ aCirc (anAxes, aRadius); + aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); + } } else if (aType == CIRCLE_THREE_PNT) { Handle(GEOM_Function) aRefPoint1 = aCI.GetPoint1(); @@ -161,7 +188,7 @@ Standard_Integer GEOMImpl_CircleDriver::Execute(TFunction_Logbook& log) const aShape = BRepBuilderAPI_MakeEdge(aCirc).Edge(); } } - else { + else { } if (aShape.IsNull()) return 0; diff --git a/src/GEOMImpl/GEOMImpl_SphereDriver.cxx b/src/GEOMImpl/GEOMImpl_SphereDriver.cxx index 9bc4f0e8d..335f8c7c5 100644 --- a/src/GEOMImpl/GEOMImpl_SphereDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_SphereDriver.cxx @@ -18,7 +18,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// + #include #include @@ -67,16 +67,27 @@ Standard_Integer GEOMImpl_SphereDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; + char aMsg[] = "Sphere creation aborted: radius value less than 1e-07 is not acceptable"; + if (aType == SPHERE_R) { - aShape = BRepPrimAPI_MakeSphere(aCI.GetR()).Shape(); + double anR = aCI.GetR(); + if (anR < Precision::Confusion()) + Standard_ConstructionError::Raise(aMsg); + + aShape = BRepPrimAPI_MakeSphere(anR).Shape(); } else if (aType == SPHERE_PNT_R) { + double anR = aCI.GetR(); + if (anR < Precision::Confusion()) + Standard_ConstructionError::Raise(aMsg); + Handle(GEOM_Function) aRefPoint = aCI.GetPoint(); TopoDS_Shape aShapePnt = aRefPoint->GetValue(); - if (aShapePnt.ShapeType() == TopAbs_VERTEX) { - gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); - aShape = BRepPrimAPI_MakeSphere(aP, aCI.GetR()).Shape(); - } + if (aShapePnt.ShapeType() != TopAbs_VERTEX) + Standard_ConstructionError::Raise("Invalid shape given for sphere center: it must be a point"); + gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt)); + + aShape = BRepPrimAPI_MakeSphere(aP, anR).Shape(); } else { }