Salome HOME
Issue #1834: Fix length of lines
[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
20 //=================================================================================================
21 BuildPlugin_Face::BuildPlugin_Face()
22 {
23 }
24
25 //=================================================================================================
26 void BuildPlugin_Face::initAttributes()
27 {
28   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
29 }
30
31 //=================================================================================================
32 void BuildPlugin_Face::execute()
33 {
34   // Get base objects list.
35   AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
36   if(!aSelectionList.get()) {
37     setError("Error: Could not get selection list.");
38     return;
39   }
40   if(aSelectionList->size() == 0) {
41     setError("Error: Empty selection list.");
42     return;
43   }
44
45   // Collect base shapes.
46   ListOfShape anEdges;
47   std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
48   for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
49     AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
50     GeomShapePtr aShape = aSelection->value();
51     GeomShapePtr aContext = aSelection->context()->shape();
52     if(!aShape.get()) {
53       aShape = aContext;
54     }
55     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
56       GeomShapePtr anEdge = anExp.current();
57       anEdges.push_back(anEdge);
58     }
59
60     // check whether the context is a sketch, in this case store its normal for further needs
61     std::shared_ptr<GeomAPI_PlanarEdges> aSketch =
62         std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContext);
63     if (aSketch)
64       aListOfNormals.push_back(aSketch->norm());
65   }
66
67   // Get plane.
68   std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
69   std::shared_ptr<GeomAPI_Dir> aNormal = aPln->direction();
70   bool isReverse = !aListOfNormals.empty();
71   std::list< std::shared_ptr<GeomAPI_Dir> >::const_iterator aNormIt = aListOfNormals.begin();
72   for (; aNormIt != aListOfNormals.end() && isReverse; ++aNormIt)
73     if ((*aNormIt)->dot(aNormal) > 1.e-7)
74       isReverse = false;
75   if (isReverse) {
76     aNormal->reverse();
77     aPln = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aPln->location(), aNormal));
78   }
79
80   // Get faces.
81   ListOfShape aFaces;
82   GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
83                                          aPln->direction(), anEdges, aFaces);
84
85   // Get wires from faces.
86   ListOfShape aWires;
87   for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
88     aWires.push_back(GeomAlgoAPI_ShapeTools::getFaceOuterWire(*anIt));
89     //for(GeomAPI_ShapeExplorer anExp(*anIt, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
90     //  if(anExp.current()->orientation() == GeomAPI_Shape::REVERSED) {
91     //    continue;
92     //  }
93     //  aWires.push_back(anExp.current());
94     //}
95   }
96
97   // Make faces with holes.
98   aFaces.clear();
99   GeomAlgoAPI_ShapeTools::makeFacesWithHoles(aPln->location(), aPln->direction(), aWires, aFaces);
100
101   // Store result.
102   int anIndex = 0;
103   for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
104     ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
105     GeomShapePtr aShape = *anIt;
106     aResultBody->store(aShape);
107
108     int anEdgeIndex = 1;
109
110     for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
111       GeomShapePtr anEdgeInResult = anExp.current();
112       for(ListOfShape::const_iterator anIt = anEdges.cbegin(); anIt != anEdges.cend(); ++anIt) {
113         std::shared_ptr<GeomAPI_Edge> anEdgeInList(new GeomAPI_Edge(*anIt));
114         if(anEdgeInList->isEqual(anEdgeInResult)) {
115           aResultBody->modified(anEdgeInList, anEdgeInResult,
116                                 "Edge_" + std::to_string((long long)anEdgeIndex), anEdgeIndex);
117           ++anEdgeIndex;
118           break;
119         }
120       }
121     }
122
123     setResult(aResultBody, anIndex);
124     ++anIndex;
125   }
126
127   removeResults(anIndex);
128 }