From ed570009fbcba00f7f6dc7f05690d4d9a34d28c8 Mon Sep 17 00:00:00 2001 From: dbv Date: Wed, 10 Jan 2018 18:51:44 +0300 Subject: [PATCH] Issue #2395: Custom direction in extrusion not working Fixed --- src/FeaturesPlugin/CMakeLists.txt | 1 + src/FeaturesPlugin/Test/Test2377.py | 2 +- src/FeaturesPlugin/Test/Test2395.py | 64 +++++++++++++++++++++++ src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp | 74 ++++++++++++++++----------- 4 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 src/FeaturesPlugin/Test/Test2395.py diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 9a39487a9..1dad2073d 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -242,4 +242,5 @@ ADD_UNIT_TESTS(TestExtrusion.py Test2289.py Test2304.py Test2377.py + Test2395.py ) diff --git a/src/FeaturesPlugin/Test/Test2377.py b/src/FeaturesPlugin/Test/Test2377.py index 9457daa8d..36e38d9d5 100644 --- a/src/FeaturesPlugin/Test/Test2377.py +++ b/src/FeaturesPlugin/Test/Test2377.py @@ -48,6 +48,6 @@ model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.SOLID, [1]) model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.FACE, [3]) model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.EDGE, [6]) model.testNbSubShapes(Extrusion_2, GeomAPI_Shape.VERTEX, [12]) -model.testResultsVolumes(Extrusion_2, [36480.150452606350881978869438171]) +model.testResultsVolumes(Extrusion_2, [25446.012037604283250402659177780]) assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/Test2395.py b/src/FeaturesPlugin/Test/Test2395.py new file mode 100644 index 000000000..5364304ea --- /dev/null +++ b/src/FeaturesPlugin/Test/Test2395.py @@ -0,0 +1,64 @@ +## Copyright (C) 2014-2017 CEA/DEN, EDF R&D +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchLine_1 = Sketch_1.addLine(79.57337041028953, 0, 0, 0) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result()) +SketchLine_2 = Sketch_1.addLine(0, 0, 0, 72.40068540018763) +SketchLine_3 = Sketch_1.addLine(0, 72.40068540018763, 79.57337041028953, 72.40068540018763) +SketchLine_4 = Sketch_1.addLine(79.57337041028953, 72.40068540018763, 79.57337041028953, 0) +SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint()) +SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint()) +SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint()) +SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result()) +SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result()) +SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result()) +SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result()) +model.do() +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ")) +SketchLine_5 = Sketch_2.addLine(0, 0, -37.87650574447493, 64.03712943185892) +SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/Vertex-SketchProjection_1-SketchPoint_1-SketchLine_2s-SketchLine_1e"), False) +SketchPoint_2 = SketchProjection_2.createdFeature() +SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_5.startPoint(), SketchPoint_2.result()) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection("EDGE", "Sketch_2/Edge-SketchLine_5"), 100, 0) +model.do() +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Extrusion_1, 1) +model.testNbSubResults(Extrusion_1, [0]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.EDGE, [24]) +model.testNbSubShapes(Extrusion_1, GeomAPI_Shape.VERTEX, [48]) +model.testResultsVolumes(Extrusion_1, [495870.673305030388291925191879272]) + +assert(model.checkPythonDump()) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 91cd80630..2576423e7 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -144,22 +144,12 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, } // Getting direction. - gp_Vec aDirVec; + gp_Vec aBaseVec; std::shared_ptr aBaseLoc; std::shared_ptr aBaseDir; - GeomShapePtr aBasePlane; - const bool isBoundingShapesSet = theFromShape.get() || theToShape.get(); BRepBuilderAPI_FindPlane aFindPlane(aBaseShape); - if ((aBaseShape.ShapeType() == TopAbs_VERTEX || aBaseShape.ShapeType() == TopAbs_EDGE) - && theDirection.get()) + if(aFindPlane.Found() == Standard_True) { - aBaseDir = theDirection; - aDirVec = theDirection->impl(); - } else { - if(aFindPlane.Found() == Standard_False) { - return; - } - Handle(Geom_Plane) aPlane; if(aBaseShape.ShapeType() == TopAbs_FACE || aBaseShape.ShapeType() == TopAbs_SHELL) { TopExp_Explorer anExp(aBaseShape, TopAbs_FACE); @@ -178,13 +168,23 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, aPlane = aFindPlane.Plane(); } gp_Pnt aLoc = aPlane->Axis().Location(); - aDirVec = aPlane->Axis().Direction(); + aBaseVec = aPlane->Axis().Direction(); aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); - aBaseDir.reset(new GeomAPI_Dir(aDirVec.X(), aDirVec.Y(), aDirVec.Z())); + aBaseDir.reset(new GeomAPI_Dir(aBaseVec.X(), aBaseVec.Y(), aBaseVec.Z())); } + else if (theDirection.get()) + { + aBaseDir = theDirection; + aBaseVec = theDirection->impl(); + } + else + { + return; + } + if(!aBaseLoc.get()) { gp_Pnt aLoc; - gp_XYZ aDirXYZ = aDirVec.XYZ(); + gp_XYZ aDirXYZ = aBaseVec.XYZ(); Standard_Real aMinParam = Precision::Infinite(); for(TopExp_Explorer anExp(aBaseShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) { const TopoDS_Shape& aVertex = anExp.Current(); @@ -197,13 +197,29 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, } aBaseLoc.reset(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); } - aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); + + GeomShapePtr aBasePlane = GeomAlgoAPI_FaceBuilder::planarFace(aBaseLoc, aBaseDir); + + gp_Vec anExtVec; + std::shared_ptr anExtDir; + if (theDirection.get()) + { + anExtDir = theDirection; + anExtVec = theDirection->impl(); + } + else + { + anExtDir = aBaseDir; + anExtVec = aBaseDir->impl(); + } + TopoDS_Shape aResult; + const bool isBoundingShapesSet = theFromShape.get() || theToShape.get(); if(!isBoundingShapesSet) { // Moving base shape. gp_Trsf aTrsf; - aTrsf.SetTranslation(aDirVec * -theFromSize); + aTrsf.SetTranslation(anExtVec * -theFromSize); BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf); if(!aTransformBuilder) { @@ -218,7 +234,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, // Making prism. BRepPrimAPI_MakePrism* aPrismBuilder = - new BRepPrimAPI_MakePrism(aMovedBase, aDirVec * (theFromSize + theToSize)); + new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * (theFromSize + theToSize)); if(!aPrismBuilder) { return; } @@ -249,15 +265,15 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, std::shared_ptr aToLoc = aToPln->location(); std::shared_ptr aToDir = aToPln->direction(); - bool aSign = aFromLoc->xyz()->dot(aBaseDir->xyz()) > aToLoc->xyz()->dot(aBaseDir->xyz()); + bool aSign = aFromLoc->xyz()->dot(anExtDir->xyz()) > aToLoc->xyz()->dot(anExtDir->xyz()); std::shared_ptr aFromPnt( - new GeomAPI_Pnt(aFromLoc->xyz()->added(aBaseDir->xyz()->multiplied( + new GeomAPI_Pnt(aFromLoc->xyz()->added(anExtDir->xyz()->multiplied( aSign ? theFromSize : -theFromSize)))); aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); std::shared_ptr aToPnt( - new GeomAPI_Pnt(aToLoc->xyz()->added(aBaseDir->xyz()->multiplied( + new GeomAPI_Pnt(aToLoc->xyz()->added(anExtDir->xyz()->multiplied( aSign ? -theToSize : theToSize)))); aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); @@ -283,7 +299,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, IntAna_Quadric aBndFromQuadric(gp_Pln(aFromPnt->impl(), aFromDir->impl())); Standard_Real aMaxToDist = 0, aMaxFromDist = 0; for(int i = 0; i < 8; i++) { - gp_Lin aLine(aPoints[i], aDirVec); + gp_Lin aLine(aPoints[i], anExtVec); IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); if(aToIntAna.NbPoints() == 0 || aFromIntAna.NbPoints() == 0) { @@ -304,7 +320,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, // Moving base shape. gp_Trsf aTrsf; - aTrsf.SetTranslation(aDirVec * -aPrismLength); + aTrsf.SetTranslation(anExtVec * -aPrismLength); BRepBuilderAPI_Transform* aTransformBuilder = new BRepBuilderAPI_Transform(aBaseShape, aTrsf); if(!aTransformBuilder) { return; @@ -318,7 +334,7 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, // Making prism. BRepPrimAPI_MakePrism* aPrismBuilder = - new BRepPrimAPI_MakePrism(aMovedBase, aDirVec * 2 * aPrismLength); + new BRepPrimAPI_MakePrism(aMovedBase, anExtVec * 2 * aPrismLength); if(!aPrismBuilder) { return; } @@ -332,30 +348,30 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, // Orienting bounding planes. std::shared_ptr aCentreOfMass = GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape); const gp_Pnt& aCentrePnt = aCentreOfMass->impl(); - gp_Lin aLine(aCentrePnt, aDirVec); + gp_Lin aLine(aCentrePnt, anExtVec); IntAna_IntConicQuad aToIntAna(aLine, aBndToQuadric); IntAna_IntConicQuad aFromIntAna(aLine, aBndFromQuadric); Standard_Real aToParameter = aToIntAna.ParamOnConic(1); Standard_Real aFromParameter = aFromIntAna.ParamOnConic(1); if(aToParameter > aFromParameter) { gp_Vec aVec = aToDir->impl(); - if((aVec * aDirVec) > 0) { + if((aVec * anExtVec) > 0) { aToDir->setImpl(new gp_Dir(aVec.Reversed())); aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); } aVec = aFromDir->impl(); - if((aVec * aDirVec) < 0) { + if((aVec * anExtVec) < 0) { aFromDir->setImpl(new gp_Dir(aVec.Reversed())); aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); } } else { gp_Vec aVec = aToDir->impl(); - if((aVec * aDirVec) < 0) { + if((aVec * anExtVec) < 0) { aToDir->setImpl(new gp_Dir(aVec.Reversed())); aBoundingToShape = GeomAlgoAPI_FaceBuilder::planarFace(aToPnt, aToDir); } aVec = aFromDir->impl(); - if((aVec * aDirVec) > 0) { + if((aVec * anExtVec) > 0) { aFromDir->setImpl(new gp_Dir(aVec.Reversed())); aBoundingFromShape = GeomAlgoAPI_FaceBuilder::planarFace(aFromPnt, aFromDir); } -- 2.39.2