X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FFeaturesPlugin%2FFeaturesPlugin_Intersection.cpp;h=e76619bfe672de6c0933f171eb9b27c06fa7e75a;hb=57f95f226733dbd01fcd42c4b1f842c71560b7d7;hp=39fdb9782d576af4c55dc4568d820032c1edfced;hpb=c9b9d4d4af3b96661c280a7e3ab829f26b5c7b95;p=modules%2Fshaper.git diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp index 39fdb9782..e76619bfe 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: FeaturesPlugin_Intersection.cpp -// Created: 15 Feb 2016 -// Author: Dmitry Bobylev +// Copyright (C) 2014-2022 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 +// #include "FeaturesPlugin_Intersection.h" @@ -10,12 +23,23 @@ #include #include #include +#include +#include #include +#include #include +#include +#include +#include #include + +static const std::string INTERSECTION_VERSION_1("v9.5"); +static const double DEFAULT_FUZZY = 1.e-5; + + //================================================================================================= FeaturesPlugin_Intersection::FeaturesPlugin_Intersection() { @@ -24,111 +48,73 @@ FeaturesPlugin_Intersection::FeaturesPlugin_Intersection() //================================================================================================= void FeaturesPlugin_Intersection::initAttributes() { - data()->addAttribute(FeaturesPlugin_Intersection::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); - data()->addAttribute(FeaturesPlugin_Intersection::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + AttributePtr anObjectsAttr = data()->addAttribute(OBJECT_LIST_ID(), + ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(USE_FUZZY_ID(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(FUZZY_PARAM_ID(), ModelAPI_AttributeDouble::typeId()); + boolean(USE_FUZZY_ID())->setValue(false); // Do NOT use the fuzzy parameter by default. + real(FUZZY_PARAM_ID())->setValue(DEFAULT_FUZZY); + + initVersion(INTERSECTION_VERSION_1, anObjectsAttr, AttributePtr()); } //================================================================================================= void FeaturesPlugin_Intersection::execute() { - ListOfShape anObjects, aTools; - + GeomAPI_ShapeHierarchy anObjectsHierarchy; + ListOfShape aPlanes; // Getting objects. - AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID()); - for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - std::shared_ptr anObjectAttr = anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if (!anObject.get()) { - return; - } - anObjects.push_back(anObject); + if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes)) { + setError("Error: Objects or tools are empty."); + return; } - // Getting tools. - AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Intersection::TOOL_LIST_ID()); - for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) { - std::shared_ptr aToolAttr = aToolsSelList->value(aToolsIndex); - std::shared_ptr aTool = aToolAttr->value(); - if (!aTool.get()) { - return; - } - aTools.push_back(aTool); - } + // Getting fuzzy parameter. + // Used as additional tolerance to eliminate tiny results. + // Using -1 as fuzzy value in the GeomAlgoAPI means to ignore it during the boolean operation! + bool aUseFuzzy = boolean(USE_FUZZY_ID())->value(); + double aFuzzy = (aUseFuzzy ? real(FUZZY_PARAM_ID())->value() : -1); - if(anObjects.empty() || aTools.empty()) { - setError("Error: Objects or tools are empty."); + int aResultIndex = 0; + + // Create result. + const ListOfShape& anObjects = anObjectsHierarchy.objects(); + GeomMakeShapePtr anIntersectionAlgo(new GeomAlgoAPI_Intersection(anObjects, aFuzzy)); + + // Checking that the algorithm worked properly. + std::string anError; + if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(anIntersectionAlgo, getKind(), anError)) { + setError(anError); return; } - int aResultIndex = 0; + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList); + aMakeShapeList->appendAlgo(anIntersectionAlgo); - // Create result for each object. - for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) { - std::shared_ptr anObject = *anObjectsIt; - ListOfShape aListWithObject; aListWithObject.push_back(anObject); - GeomAlgoAPI_Intersection anIntersectionAlgo(aListWithObject, aTools); - - // Checking that the algorithm worked properly. - if (!anIntersectionAlgo.isDone()) { - static const std::string aFeatureError = "Error: Intersection algorithm failed."; - setError(aFeatureError); - return; - } - if (anIntersectionAlgo.shape()->isNull()) { - static const std::string aShapeError = "Error: Resulting shape is Null."; - setError(aShapeError); - return; - } - if (!anIntersectionAlgo.isValid()) { - std::string aFeatureError = "Error: resulting shape is not valid"; - setError(aFeatureError); - return; - } - - std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, anObject, aTools, anIntersectionAlgo); - setResult(aResultBody, aResultIndex); - aResultIndex++; + GeomShapePtr aResShape = anIntersectionAlgo->shape(); + if (data()->version() == INTERSECTION_VERSION_1) { + // merge hierarchies of compounds containing objects and tools + // and append the result of the FUSE operation + aResShape = keepUnusedSubsOfCompound(aResShape, anObjectsHierarchy, + GeomAPI_ShapeHierarchy(), aMakeShapeList); } + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); + ModelAPI_Tools::loadModifiedShapes(aResultBody, + anObjects, + ListOfShape(), + aMakeShapeList, + aResShape); + setResult(aResultBody, aResultIndex); + aResultIndex++; + + ModelAPI_Tools::loadDeletedShapes(aResultBody, + GeomShapePtr(), + anObjects, + aMakeShapeList, + aResShape); + // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); } - -//================================================================================================= -void FeaturesPlugin_Intersection::loadNamingDS(std::shared_ptr theResultBody, - const std::shared_ptr theBaseShape, - const ListOfShape& theTools, - GeomAlgoAPI_MakeShape& theMakeShape) -{ - //load result - std::shared_ptr aResultShape = theMakeShape.shape(); - std::shared_ptr aMapOfShapes = theMakeShape.mapOfSubShapes(); - const int aDeletedTag = 1; - const int aSubsolidsTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids - const int aModifyTag = 100000; - int aModifyToolsTag = 200000; - std::ostringstream aStream; - - theResultBody->storeModified(theBaseShape, aResultShape, aSubsolidsTag); - - std::string aModName = "Modified"; - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX, - aModifyTag, aModName, *aMapOfShapes.get(), true); - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::EDGE, - aModifyTag, aModName, *aMapOfShapes.get(), true); - theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE, aDeletedTag); - - int anIndex = 1; - for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) { - aStream.str(std::string()); - aStream.clear(); - aStream << aModName << "_" << anIndex++; - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::VERTEX, - aModifyToolsTag, aStream.str(), *aMapOfShapes.get(), true); - theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter, GeomAPI_Shape::EDGE, - aModifyToolsTag, aStream.str(), *aMapOfShapes.get(), true); - theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag); - aModifyToolsTag += 10000; - } -}