Salome HOME
Merge remote-tracking branch 'origin/PortingSalome760' into Dev_1.3.0
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Placement.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Placement.cpp
4 // Created:     2 Dec 2014
5 // Author:      Artem ZHIDKOV
6
7 #include "FeaturesPlugin_Placement.h"
8
9 #include <ModelAPI_ResultConstruction.h>
10 #include <ModelAPI_ResultBody.h>
11 #include <ModelAPI_AttributeSelection.h>
12 #include <ModelAPI_AttributeBoolean.h>
13 #include <ModelAPI_AttributeSelectionList.h>
14
15 #include <GeomAPI_Edge.h>
16 #include <GeomAPI_Face.h>
17 #include <GeomAPI_Pln.h>
18 #include <GeomAlgoAPI_Placement.h>
19
20 #define _MODIFIEDF_TAG 1
21 #define _MODIFIEDE_TAG 2
22 #define _MODIFIEDV_TAG 3
23 #define _FACE 4
24 FeaturesPlugin_Placement::FeaturesPlugin_Placement()
25 {
26 }
27
28 void FeaturesPlugin_Placement::initAttributes()
29 {
30   /* Modification for specification of 1.3.0
31   AttributeSelectionListPtr aSelection = 
32     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
33     FeaturesPlugin_Placement::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
34   // extrusion works with faces always
35   aSelection->setSelectionType("SOLID");
36   */
37   data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
38   data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
39   data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
40   data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
41 }
42
43 void FeaturesPlugin_Placement::execute()
44 {
45   // Verify the base face
46   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = std::dynamic_pointer_cast<
47     ModelAPI_AttributeSelection>(data()->attribute(FeaturesPlugin_Placement::BASE_OBJECT_ID()));
48   if (!anObjRef)
49     return;
50
51   std::shared_ptr<GeomAPI_Shape> aBaseShape = 
52     std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
53   if (!aBaseShape)
54     return;
55
56   std::shared_ptr<GeomAPI_Shape> aBaseObject;
57   ResultPtr aContextRes = anObjRef->context();
58   if (aContextRes) {
59     if (aContextRes->groupName() == ModelAPI_ResultBody::group())
60       aBaseObject = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
61     else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
62       aBaseObject = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
63   }
64   if (!aBaseObject) {
65     static const std::string aContextError = "The selection context is bad";
66     setError(aContextError);
67     return;
68   }
69
70   // Verify the attractive face
71   anObjRef = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(
72       data()->attribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID()));
73
74   std::shared_ptr<GeomAPI_Shape> aSlaveShape = 
75     std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
76   if (!aSlaveShape)
77     return;
78
79   std::shared_ptr<GeomAPI_Shape> aSlaveObject;
80   aContextRes = anObjRef->context();
81   if (aContextRes) {
82     if (aContextRes->groupName() == ModelAPI_ResultBody::group())
83       aSlaveObject = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContextRes)->shape();
84     else if (aContextRes->groupName() == ModelAPI_ResultConstruction::group())
85       aSlaveObject = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes)->shape();
86   }
87   if (!aSlaveObject) {
88     static const std::string aContextError = "The selection context is bad";
89     setError(aContextError);
90     return;
91   }
92
93   // Verify planarity of faces and linearity of edges
94   std::shared_ptr<GeomAPI_Shape> aShapes[2] = {aBaseShape, aSlaveShape};
95   for (int i = 0; i < 2; i++) {
96     if (aShapes[i]->isFace()) {
97       std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aShapes[i]));
98       if (!aFace->isPlanar()) {
99         static const std::string aPlanarityError = "One of selected faces is not planar";
100         setError(aPlanarityError);
101         return;
102       }
103     }
104     else if (aShapes[i]->isEdge()) {
105       std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aShapes[i]));
106       if (!anEdge->isLine()) {
107         static const std::string aLinearityError = "One of selected endges is not linear";
108         setError(aLinearityError);
109         return;
110       }
111     }
112   }
113
114   // Flags of the Placement
115   AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
116       data()->attribute(FeaturesPlugin_Placement::REVERSE_ID()));
117   bool isReverse = aBoolAttr->value();
118   aBoolAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
119       data()->attribute(FeaturesPlugin_Placement::CENTERING_ID()));
120   bool isCentering = aBoolAttr->value();
121
122   std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
123   GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseObject, aSlaveShape, aBaseShape, isReverse, isCentering);
124   if(!aFeature.isDone()) {
125     static const std::string aFeatureError = "Placement algorithm failed";
126     setError(aFeatureError);
127     return;
128   }
129
130   // Check if shape is valid
131   if (aFeature.shape()->isNull()) {
132     static const std::string aShapeError = "Resulting shape is Null";
133     setError(aShapeError);
134     return;
135   }
136   if(!aFeature.isValid()) {
137     std::string aFeatureError = "Warning: resulting shape is not valid";
138     setError(aFeatureError);
139     return;
140   }  
141   //LoadNamingDS
142   LoadNamingDS(aFeature, aResultBody, aSlaveObject);
143
144   setResult(aResultBody);
145 }
146
147 //============================================================================
148 void FeaturesPlugin_Placement::LoadNamingDS(
149     GeomAlgoAPI_Placement& theFeature,
150     std::shared_ptr<ModelAPI_ResultBody> theResultBody,
151     std::shared_ptr<GeomAPI_Shape> theSlaveObject)
152 {
153   //load result
154   theResultBody->storeModified(theSlaveObject, theFeature.shape()); // the initial Slave, the resulting Slave
155
156   GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
157   theFeature.mapOfShapes(*aSubShapes);
158   
159     // put modifed faces in DF
160   std::string aModName = "Modified";
161   theResultBody->loadAndOrientModifiedShapes(theFeature.makeShape(), theSlaveObject, _FACE, _MODIFIEDF_TAG, aModName, *aSubShapes); 
162
163 }