From f397db69cd3a3e3000f417f932409a22914eb712 Mon Sep 17 00:00:00 2001 From: jfa Date: Tue, 3 May 2011 12:33:14 +0000 Subject: [PATCH] IMP 0021067: Extrusion with scale factor. Fix some cases. --- src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx | 14 ++- src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 39 ++++----- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 7 ++ src/GEOMImpl/GEOMImpl_MeasureDriver.cxx | 19 +--- src/GEOMImpl/GEOMImpl_PrismDriver.cxx | 92 +++++++++++++++++++- src/GEOMImpl/GEOMImpl_PrismDriver.hxx | 4 +- 6 files changed, 130 insertions(+), 45 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 46ce5f9c5..16d58527e 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -778,14 +779,21 @@ gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape) // Origin gp_Pnt aPnt; - if (theShape.ShapeType() == TopAbs_VERTEX) { + + TopAbs_ShapeEnum aShType = theShape.ShapeType(); + + if (aShType == TopAbs_VERTEX) { aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); } else { + if (aShType == TopAbs_COMPOUND) { + aShType = GEOMImpl_IShapesOperations::GetTypeOfSimplePart(theShape); + } + GProp_GProps aSystem; - if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE) + if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) BRepGProp::LinearProperties(theShape, aSystem); - else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL) + else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) BRepGProp::SurfaceProperties(theShape, aSystem); else BRepGProp::VolumeProperties(theShape, aSystem); diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 11e0ee2fd..31f7006fb 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -3726,29 +3726,28 @@ namespace { } return defaultNorm; } +} - //================================================================================ - /*! - * \brief Return type of shape for explode. In case of compound it will be a type of sub shape. - */ - //================================================================================ - - TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape) - { - TopAbs_ShapeEnum aType = theShape.ShapeType(); - if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; - else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; - else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; - else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; - else if (aType == TopAbs_COMPOUND) { - // Only the iType of the first shape in the compound is taken into account - TopoDS_Iterator It (theShape, Standard_False, Standard_False); - if (It.More()) { - return GetTypeOfSimplePart(It.Value()); - } +//================================================================================ +/*! + * \brief Return type of shape for explode. In case of compound it will be a type of sub shape. + */ +//================================================================================ +TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape) +{ + TopAbs_ShapeEnum aType = theShape.ShapeType(); + if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; + else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; + else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; + else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; + else if (aType == TopAbs_COMPOUND) { + // Only the iType of the first shape in the compound is taken into account + TopoDS_Iterator It (theShape, Standard_False, Standard_False); + if (It.More()) { + return GetTypeOfSimplePart(It.Value()); } - return TopAbs_SHAPE; } + return TopAbs_SHAPE; } //============================================================================= diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 25666f82a..2076bdbce 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -399,6 +399,13 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations */ Standard_EXPORT static bool CheckTriangulation (const TopoDS_Shape& theShape); + /*! + * \brief Return type of shape for explode. In case of compound it will be a type of its first sub shape. + * \param theShape The shape to get type of. + * \retval TopAbs_ShapeEnum Return type of shape for explode. + */ + Standard_EXPORT static TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape); + private: Handle(GEOM_Object) MakeShape (std::list theShapes, const Standard_Integer theObjectType, diff --git a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx index 6d8698259..f454de926 100644 --- a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx @@ -18,7 +18,6 @@ // 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 @@ -96,22 +95,8 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const Standard_NullObject::Raise("Shape for centre of mass calculation is null"); } - GProp_GProps aSystem; - gp_Pnt aCenterMass; - - if (aShapeBase.ShapeType() == TopAbs_VERTEX) { - aCenterMass = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)); - } else if (aShapeBase.ShapeType() == TopAbs_EDGE || aShapeBase.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } else if (aShapeBase.ShapeType() == TopAbs_FACE || aShapeBase.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } else { - BRepGProp::VolumeProperties(aShapeBase, aSystem); - aCenterMass = aSystem.CentreOfMass(); - } - + gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase); + gp_Pnt aCenterMass = aPos.Location(); aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); } else if (aType == VERTEX_BY_INDEX) diff --git a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx index ad87f7ad7..e5e82de53 100644 --- a/src/GEOMImpl/GEOMImpl_PrismDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PrismDriver.cxx @@ -24,22 +24,32 @@ #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 @@ -186,15 +196,41 @@ Standard_Integer GEOMImpl_PrismDriver::Execute(TFunction_Logbook& log) const //======================================================================= TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase, const gp_Vec& theVector, - const Standard_Real theScaleFactor) + const Standard_Real theScaleFactor, + const gp_Pnt& theCDG, + bool isCDG) { TopoDS_Shape aShape; + BRep_Builder B; // 1. aCDG = geompy.MakeCDG(theBase) - gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase); - gp_Pnt aCDG = aPos.Location(); + gp_Pnt aCDG = theCDG; + if (!isCDG) { + gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase); + aCDG = aPos.Location(); + } TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape(); + // Process case of several given shapes + if (theShapeBase.ShapeType() == TopAbs_COMPOUND || + theShapeBase.ShapeType() == TopAbs_SHELL) { + int nbSub = 0; + TopoDS_Shape aShapeI; + TopoDS_Compound aCompound; + B.MakeCompound(aCompound); + TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True); + for (; It.More(); It.Next()) { + nbSub++; + aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true); + B.Add(aCompound, aShapeI); + } + if (nbSub == 1) + aShape = aShapeI; + else if (nbSub > 1) + aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True); + return aShape; + } + // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor) // Bug 6839: Check for standalone (not included in faces) degenerated edges @@ -244,6 +280,54 @@ TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShape aLocs->Append(aShapeCDG_2); aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false); + + // 7. Make a solid, if possible + if (theShapeBase.ShapeType() == TopAbs_FACE) { + BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); + TopExp_Explorer expF (aShape, TopAbs_FACE); + Standard_Integer ifa = 0; + for (; expF.More(); expF.Next()) { + aSewing.Add(expF.Current()); + ifa++; + } + if (ifa > 0) { + aSewing.Perform(); + TopoDS_Shape aShell; + + TopoDS_Shape sh = aSewing.SewedShape(); + if (sh.ShapeType() == TopAbs_FACE && ifa == 1) { + // case for creation of shell from one face + TopoDS_Shell ss; + B.MakeShell(ss); + B.Add(ss,sh); + aShell = ss; + } + else { + TopExp_Explorer exp (sh, TopAbs_SHELL); + Standard_Integer ish = 0; + for (; exp.More(); exp.Next()) { + aShell = exp.Current(); + ish++; + } + if (ish != 1) + aShell = sh; + } + BRepCheck_Shell chkShell (TopoDS::Shell(aShell)); + if (chkShell.Closed() == BRepCheck_NoError) { + TopoDS_Solid Sol; + B.MakeSolid(Sol); + B.Add(Sol, aShell); + BRepClass3d_SolidClassifier SC (Sol); + SC.PerformInfinitePoint(Precision::Confusion()); + if (SC.State() == TopAbs_IN) { + B.MakeSolid(Sol); + B.Add(Sol, aShell.Reversed()); + } + aShape = Sol; + } + } + } + return aShape; } diff --git a/src/GEOMImpl/GEOMImpl_PrismDriver.hxx b/src/GEOMImpl/GEOMImpl_PrismDriver.hxx index 80028095c..566ea94ef 100644 --- a/src/GEOMImpl/GEOMImpl_PrismDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_PrismDriver.hxx @@ -154,7 +154,9 @@ public: Standard_EXPORT static TopoDS_Shape MakeScaledPrism (const TopoDS_Shape& theShapeBase, const gp_Vec& theVector, - const Standard_Real theScaleFactor); + const Standard_Real theScaleFactor, + const gp_Pnt& theCDG = gp::Origin(), + bool isCDG = false); // Type management -- 2.39.2