1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <FeaturesPlugin_Sewing.h>
22 #include <GeomAlgoAPI_Sewing.h>
23 #include <GeomAlgoAPI_Tools.h>
25 #include <GeomAPI_Shape.h>
27 #include <ModelAPI_AttributeBoolean.h>
28 #include <ModelAPI_AttributeDouble.h>
29 #include <ModelAPI_AttributeSelectionList.h>
30 #include <ModelAPI_ResultBody.h>
34 //=================================================================================================
35 FeaturesPlugin_Sewing::FeaturesPlugin_Sewing()
39 //=================================================================================================
40 void FeaturesPlugin_Sewing::initAttributes()
42 data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
43 data()->addAttribute(ALLOW_NON_MANIFOLD_ID(), ModelAPI_AttributeBoolean::typeId());
44 data()->addAttribute(TOLERANCE_ID(), ModelAPI_AttributeDouble::typeId());
45 data()->addAttribute(ALWAYS_CREATE_RESULT_ID(), ModelAPI_AttributeBoolean::typeId());
48 //=================================================================================================
49 void FeaturesPlugin_Sewing::execute()
51 // Collect all base shapes
53 getOriginalShapes(OBJECTS_LIST_ID(), aShapes);
55 // Get all other feature arguments
56 bool isAllowNonManifold = boolean(FeaturesPlugin_Sewing::ALLOW_NON_MANIFOLD_ID())->value();
57 bool isAlwaysCreateResult = boolean(FeaturesPlugin_Sewing::ALWAYS_CREATE_RESULT_ID())->value();
58 double aTolerance = real(FeaturesPlugin_Sewing::TOLERANCE_ID())->value();
60 std::shared_ptr<GeomAlgoAPI_Sewing> aSewingAlgo(new GeomAlgoAPI_Sewing(aShapes, isAllowNonManifold, aTolerance));
63 if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aSewingAlgo, getKind(), anError))
70 GeomShapePtr aResult = aSewingAlgo->shape();
72 if (!isSewn(aShapes, aResult) && !isAlwaysCreateResult)
74 static const std::string anError = "Error: No faces were sewn.";
80 ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
81 aResultBody->storeModified(aShapes, aResult, aSewingAlgo);
83 setResult(aResultBody, anIndex);
86 //=================================================================================================
87 void FeaturesPlugin_Sewing::getOriginalShapes(const std::string& theAttributeName,
88 ListOfShape& theShapes)
90 // Collect all selections into a single list of shapes
91 AttributeSelectionListPtr aSelectionList = selectionList(theAttributeName);
92 for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex)
94 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
95 GeomShapePtr aShape = aSelection->value();
96 GeomShapePtr aContext = aSelection->context()->shape();
101 theShapes.push_back(aShape);
105 //=================================================================================================
106 bool FeaturesPlugin_Sewing::isSewn(const ListOfShape& theInputs,
107 const GeomShapePtr theResult)
109 // Consider the list of input shapes the same as the result, if
110 // * both arguments have the same number of shells
111 // * the total number of faces in these shells did NOT change.
112 int nbInputShells = 0, nbInputFaces = 0;
113 for (ListOfShape::const_iterator anIt = theInputs.cbegin();
114 anIt != theInputs.cend();
117 GeomShapePtr aShape = *anIt;
120 if (aShape->isShell()) nbInputShells++;
121 nbInputFaces += aShape->subShapes(GeomAPI_Shape::FACE, true).size();
125 int nbResultShells = 0, nbResultFaces = 0;
126 if (theResult->isCompound())
128 ListOfShape shells = theResult->subShapes(GeomAPI_Shape::SHELL, true);
129 nbResultShells = shells.size();
130 for (ListOfShape::const_iterator anIt = shells.cbegin();
131 anIt != shells.cend();
134 GeomShapePtr aShape = *anIt;
135 if (aShape.get() && aShape->isShell())
137 nbInputFaces += aShape->subShapes(GeomAPI_Shape::FACE, true).size();
141 else if (theResult->isShell())
144 nbResultFaces = theResult->subShapes(GeomAPI_Shape::FACE, true).size();
147 return ((nbInputShells == 0 && nbResultShells > 0) || (nbResultShells < nbInputShells) || (nbResultShells == nbInputShells && nbResultFaces > nbInputFaces));