Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_Face.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        BuildPlugin_Face.cpp
4 // Created:     14 April 2016
5 // Author:      Dmitry Bobylev
6
7 #include "BuildPlugin_Face.h"
8
9 #include <ModelAPI_AttributeSelectionList.h>
10 #include <ModelAPI_ResultBody.h>
11
12 #include <GeomAPI_Edge.h>
13 #include <GeomAPI_PlanarEdges.h>
14 #include <GeomAPI_Pln.h>
15 #include <GeomAPI_ShapeExplorer.h>
16
17 #include <GeomAlgoAPI_ShapeTools.h>
18 #include <GeomAlgoAPI_SketchBuilder.h>
19 #include <GeomAlgoAPI_Copy.h>
20
21 //=================================================================================================
22 BuildPlugin_Face::BuildPlugin_Face()
23 {
24 }
25
26 //=================================================================================================
27 void BuildPlugin_Face::initAttributes()
28 {
29   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
30 }
31
32 //=================================================================================================
33 void BuildPlugin_Face::execute()
34 {
35   // Get base objects list.
36   AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
37   if(!aSelectionList.get()) {
38     setError("Error: Could not get selection list.");
39     return;
40   }
41   if(aSelectionList->size() == 0) {
42     setError("Error: Empty selection list.");
43     return;
44   }
45
46   // Collect base shapes.
47   ListOfShape anEdges;
48   std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
49   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
50     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
51     GeomShapePtr aShape = aSelection->value();
52     GeomShapePtr aContext = aSelection->context()->shape();
53     if(!aShape.get()) {
54       aShape = aContext;
55     }
56     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
57       GeomShapePtr anEdge = anExp.current();
58       anEdges.push_back(anEdge);
59     }
60
61     // check whether the context is a sketch, in this case store its normal for further needs
62     std::shared_ptr<GeomAPI_PlanarEdges> aSketch =
63         std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContext);
64     if (aSketch)
65       aListOfNormals.push_back(aSketch->norm());
66   }
67
68   // Get plane.
69   std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
70   std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
71   bool isReverse = !aListOfNormals.empty();
72   std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = aListOfNormals.begin();
73   for (; aNormIt != aListOfNormals.end() && isReverse; ++aNormIt)
74     if ((*aNormIt)->dot(aNormal) > 1.e-7)
75       isReverse = false;
76   if (isReverse) {
77     aNormal->reverse();
78     aPln = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aPln->location(), aNormal));
79   }
80
81   // Get faces.
82   ListOfShape aFaces;
83   GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
84                                          aPln->direction(), anEdges, aFaces);
85
86   // Get wires from faces.
87   ListOfShape aWires;
88   for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
89     aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
90     //for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
91     //  if(anExp.current()->orientation() == GeomAPI_Shape::REVERSED) {
92     //    continue;
93     //  }
94     //  aWires.push_back(anExp.current());
95     //}
96   }
97
98   // Make faces with holes.
99   aFaces.clear();
100   GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
101
102   // Store result.
103   int anIndex = 0;
104   for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
105     ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
106     GeomShapePtr aShape = *anIt;
107     GeomAlgoAPI_Copy aCopy(aShape);
108     aShape = aCopy.shape();
109     aResultBody->store(aShape);
110
111     // Store edges.
112     int anEdgeIndex = 1;
113     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
114       GeomShapePtr anEdge = anExp.current();
115       aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex), anEdgeIndex);
116       ++anEdgeIndex;
117     }
118
119     setResult(aResultBody, anIndex);
120     ++anIndex;
121   }
122
123   removeResults(anIndex);
124 }