1 // Copyright (C) 2014-2021 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_Tools.h"
22 #include <ModelAPI_AttributeSelectionList.h>
23 #include <ModelAPI_ResultBody.h>
24 #include <ModelAPI_ResultConstruction.h>
25 #include <ModelAPI_ResultPart.h>
26 #include <ModelAPI_Tools.h>
28 #include <GeomAlgoAPI_CompoundBuilder.h>
29 #include <GeomAlgoAPI_ShapeTools.h>
31 #include <GeomAPI_PlanarEdges.h>
32 #include <GeomAPI_ShapeIterator.h>
34 #include <GeomValidators_ShapeType.h>
36 //==================================================================================================
37 void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
38 const ListOfShape& theBaseShapes,
39 const ListOfShape& theTools,
40 const GeomMakeShapePtr& theMakeShape,
41 const GeomShapePtr theResultShape,
42 const std::string& theNamePrefix)
44 theResultBody->storeModified(theBaseShapes, theResultShape, theMakeShape);
46 ListOfShape aShapes = theBaseShapes;
47 ListOfShape::const_iterator aToolIter = theTools.cbegin();
48 for(; aToolIter != theTools.cend(); aToolIter++)
49 aShapes.push_back(*aToolIter);
51 for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); ++anIter)
53 theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::VERTEX, theNamePrefix);
54 theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::EDGE, theNamePrefix);
55 theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE, theNamePrefix);
59 //==================================================================================================
60 void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
61 const GeomShapePtr& theBaseShape,
62 const GeomMakeShapePtr& theMakeShape,
63 const std::string theName)
65 switch(theBaseShape->shapeType()) {
66 case GeomAPI_Shape::COMPOUND: {
67 for(GeomAPI_ShapeIterator anIt(theBaseShape); anIt.more(); anIt.next())
69 loadModifiedShapes(theResultBody,
76 case GeomAPI_Shape::COMPSOLID:
77 case GeomAPI_Shape::SOLID:
78 case GeomAPI_Shape::SHELL: {
79 theResultBody->loadModifiedShapes(theMakeShape,
84 case GeomAPI_Shape::FACE:
85 case GeomAPI_Shape::WIRE: {
86 theResultBody->loadModifiedShapes(theMakeShape,
91 case GeomAPI_Shape::EDGE: {
92 theResultBody->loadModifiedShapes(theMakeShape,
94 GeomAPI_Shape::VERTEX,
97 default: // [to avoid compilation warning]
102 //==================================================================================================
103 void FeaturesPlugin_Tools::loadDeletedShapes(ResultBodyPtr theResultBody,
104 const GeomShapePtr theBaseShape,
105 const ListOfShape& theTools,
106 const GeomMakeShapePtr& theMakeShape,
107 const GeomShapePtr theResultShapesCompound)
109 ListOfShape aShapes = theTools;
110 if (theBaseShape.get())
111 aShapes.push_front(theBaseShape);
113 for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); anIter++)
115 theResultBody->loadDeletedShapes(theMakeShape,
117 GeomAPI_Shape::VERTEX,
118 theResultShapesCompound);
119 theResultBody->loadDeletedShapes(theMakeShape,
122 theResultShapesCompound);
123 theResultBody->loadDeletedShapes(theMakeShape,
126 theResultShapesCompound);
127 // store information about deleted solids because of unittest TestBooleanCommon_SolidsHistory
128 // on OCCT 7.4.0 : common produces modified compsolid, so, move to the end for removed solids
129 // starts to produce whole compsolid
130 theResultBody->loadDeletedShapes(theMakeShape,
132 GeomAPI_Shape::SOLID,
133 theResultShapesCompound);
137 //==================================================================================================
138 void FeaturesPlugin_Tools::loadDeletedShapes(
139 std::vector<ResultBaseAlgo>& theResultBaseAlgoList,
140 const ListOfShape& theTools,
141 const GeomShapePtr theResultShapesCompound)
143 for (std::vector<ResultBaseAlgo>::iterator anIt = theResultBaseAlgoList.begin();
144 anIt != theResultBaseAlgoList.end();
147 ResultBaseAlgo& aRCA = *anIt;
148 loadDeletedShapes(aRCA.resultBody,
152 theResultShapesCompound);
156 //==================================================================================================
157 bool FeaturesPlugin_Tools::getShape(const AttributeSelectionListPtr theSelectionList,
158 const bool theShareTopology,
159 ListOfShape& theShapesList,
160 std::string& theError)
162 theShapesList.clear();
164 ListOfShape aBaseFacesList;
165 std::map<ResultConstructionPtr, ListOfShape> aSketchWiresMap;
166 if(!theSelectionList.get()) {
167 theError = "Error: Could not get base objects selection list.";
170 if(theSelectionList->size() == 0) {
171 theError = "Error: Base objects list is empty.";
174 for(int anIndex = 0; anIndex < theSelectionList->size(); anIndex++) {
175 AttributeSelectionPtr aBaseObjectSelection = theSelectionList->value(anIndex);
176 if(!aBaseObjectSelection.get()) {
177 theError = "Error: Selected base object is empty.";
180 GeomShapePtr aBaseShape = aBaseObjectSelection->value();
181 if(aBaseShape.get() && !aBaseShape->isNull()) {
182 GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType();
183 if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) {
184 theError = "Error: Selected shapes has unsupported type.";
187 ResultConstructionPtr aConstruction =
188 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseObjectSelection->context());
189 if(aConstruction.get() && !aBaseShape->isEqual(aConstruction->shape()) &&
190 aST == GeomAPI_Shape::WIRE) {
191 // It is a wire on the sketch, store it to make face later.
192 aSketchWiresMap[aConstruction].push_back(aBaseShape);
195 aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
196 theShapesList.push_back(aBaseShape);
199 // This may be the whole sketch result selected, check and get faces.
200 ResultConstructionPtr aConstruction =
201 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseObjectSelection->context());
202 if(!aConstruction.get()) {
203 theError = "Error: Selected sketches does not have results.";
206 GeomValidators_ShapeType::TypeOfShape aSelType =
207 GeomValidators_ShapeType::shapeType(theSelectionList->selectionType());
209 if (aSelType != GeomValidators_ShapeType::Vertex &&
210 aSelType != GeomValidators_ShapeType::Edge)
211 aFacesNum = aConstruction->facesNum();
213 // Probably it can be construction.
214 aBaseShape = aConstruction->shape();
215 if(aBaseShape.get() && !aBaseShape->isNull()) {
216 GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType();
217 if(aST == GeomAPI_Shape::SOLID || aST == GeomAPI_Shape::COMPSOLID) {
218 theError = "Error: Selected shapes has unsupported type.";
221 aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
222 theShapesList.push_back(aBaseShape);
225 for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
226 GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex);
227 if(!aBaseFace.get() || aBaseFace->isNull()) {
228 theError = "Error: One of the faces on selected sketch is null.";
231 aBaseFacesList.push_back(aBaseFace);
237 // Make faces from sketch wires.
238 for(std::map<ResultConstructionPtr, ListOfShape>::const_iterator anIt = aSketchWiresMap.cbegin();
239 anIt != aSketchWiresMap.cend(); ++anIt) {
240 const std::shared_ptr<GeomAPI_PlanarEdges> aSketchPlanarEdges =
241 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>((*anIt).first->shape());
242 const ListOfShape& aWiresList = (*anIt).second;
244 GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aSketchPlanarEdges->origin(),
245 aSketchPlanarEdges->norm(),
248 aBaseFacesList.insert(aBaseFacesList.end(), aFaces.begin(), aFaces.end());
251 // Searching faces with common edges.
252 if(theShareTopology && aBaseFacesList.size() > 1) {
253 GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList);
254 GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, theShapesList);
256 theShapesList.insert(theShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end());
261 //==================================================================================================
262 bool FeaturesPlugin_Tools::shapesFromSelectionList(
263 const std::shared_ptr<ModelAPI_AttributeSelectionList> theSelectionList,
264 const bool theStoreFullHierarchy,
265 GeomAPI_ShapeHierarchy& theHierarchy,
266 std::list<ResultPtr>& theParts, std::string &theTextureFile)
268 int aSize = theSelectionList->size();
271 auto anObjectAttr = theSelectionList->value(0);
272 if(anObjectAttr.get())
274 FeaturePtr aFeature = anObjectAttr->contextFeature();
275 if(aFeature.get() && aFeature->results().size() == 1)
277 theTextureFile = aFeature->firstResult()->getTextureFile();
283 auto aResult = anObjectAttr->context();
286 theTextureFile = aResult->getTextureFile();
292 for (int anObjectsIndex = 0; anObjectsIndex < aSize; anObjectsIndex++) {
293 AttributeSelectionPtr anObjectAttr = theSelectionList->value(anObjectsIndex);
294 std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
295 if (!anObject.get()) { // may be for not-activated parts
298 ResultPtr aContext = anObjectAttr->context();
299 if (aContext && aContext->groupName() == ModelAPI_ResultPart::group())
300 theParts.push_back(aContext);
302 // store full shape hierarchy for the corresponding version only
303 theHierarchy.addObject(anObject);
304 if (theStoreFullHierarchy)
305 ModelAPI_Tools::fillShapeHierarchy(anObject, aContext, theHierarchy);