]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchPlugin/SketchPlugin_MacroRectangle.cpp
Salome HOME
move rectangle plugin from python addons to C++.
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_MacroRectangle.cpp
1 // Copyright (C) 2014-2020  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "SketchPlugin_MacroRectangle.h"
21 #include "SketchPlugin_Rectangle.h"
22 #include "SketchPlugin_Sketch.h"
23 #include "SketchPlugin_Tools.h"
24
25 #include <ModelAPI_Data.h>
26 #include <ModelAPI_ResultConstruction.h>
27 #include <ModelAPI_AttributeSelection.h>
28 #include <ModelAPI_Validator.h>
29 #include <ModelAPI_AttributeString.h>
30 #include <ModelAPI_Session.h>
31 #include <ModelAPI_AttributeRefList.h>
32 #include <ModelAPI_AttributeRefAttr.h>
33 #include <ModelAPI_AttributeReference.h>
34 #include <GeomAlgoAPI_CompoundBuilder.h>
35 #include <GeomAlgoAPI_EdgeBuilder.h>
36 #include <GeomAlgoAPI_PointBuilder.h>
37
38 #include <GeomAPI_Pnt2d.h>
39
40 #include <cmath>
41
42 const double tolerance = 1e-7;
43
44
45 SketchPlugin_MacroRectangle::SketchPlugin_MacroRectangle()
46   : SketchPlugin_SketchEntity()
47 {  
48 }
49
50 void SketchPlugin_MacroRectangle::initAttributes()
51 {
52   data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
53
54   data()->addAttribute(START1_ID(), GeomDataAPI_Point2D::typeId());
55   data()->addAttribute(END1_ID(), GeomDataAPI_Point2D::typeId());
56
57   data()->addAttribute(START2_ID(), GeomDataAPI_Point2D::typeId());
58   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
59
60   data()->addAttribute(TYPE_ID(), ModelAPI_AttributeString::typeId());
61   data()->addAttribute(EDIT_TYPE_ID(), ModelAPI_AttributeString::typeId());
62
63   string(EDIT_TYPE_ID())->setValue("");
64   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_TYPE_ID());
65 }
66
67 void SketchPlugin_MacroRectangle::startPoint()
68 {
69   std::shared_ptr<GeomDataAPI_Point2D> aStartPoint;
70   if(string(TYPE_ID())->value() == START_END_POINT_TYPE_ID())
71     aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START1_ID()));
72   else
73     aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START2_ID()));
74   if(aStartPoint->isInitialized())
75     myStartPoint = std::make_shared<GeomAPI_Pnt2d>(aStartPoint->x(), aStartPoint->y());
76   else
77     myStartPoint.reset();
78 }
79
80 void SketchPlugin_MacroRectangle::endPoint()
81 {
82   if(string(TYPE_ID())->value() == START_END_POINT_TYPE_ID())
83   {
84     std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
85         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END1_ID()));
86     if(aEndPoint->isInitialized())
87       myEndPoint = std::make_shared<GeomAPI_Pnt2d>(aEndPoint->x(), aEndPoint->y());
88     else
89       myEndPoint.reset();
90   }
91   else
92   {
93     /// Compute end point as the symmetric of start point w.r.t. center
94     std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
95         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START2_ID()));
96     std::shared_ptr<GeomDataAPI_Point2D> aCenterPoint =
97         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
98     double xEnd = 2.0*aCenterPoint->x() - aStartPoint->x();
99     double yEnd = 2.0*aCenterPoint->y() - aStartPoint->y();
100
101     if(aStartPoint ->isInitialized() && aCenterPoint->isInitialized())
102       myEndPoint =  std::make_shared<GeomAPI_Pnt2d>(xEnd, yEnd);
103     else
104       myEndPoint.reset();
105   }
106 }
107
108
109 void SketchPlugin_MacroRectangle::execute()
110 {
111   SketchPlugin_Sketch* aSketch = sketch();
112   if(!myStartPoint || !myEndPoint || !aSketch) {
113     return ;
114   }
115
116   /// create a rectangle sketch
117   FeaturePtr myRectangleFeature = aSketch->addFeature(SketchPlugin_Rectangle::ID());
118   if(!myRectangleFeature)
119     return;
120
121   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
122         myRectangleFeature->attribute(SketchPlugin_Rectangle::START_ID()))->setValue(myStartPoint->x(),
123                                                                                      myStartPoint->y());
124   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
125         myRectangleFeature->attribute(SketchPlugin_Rectangle::END_ID()))->setValue(myEndPoint->x(),
126                                                                                    myEndPoint->y());
127
128   myRectangleFeature->boolean(SketchPlugin_Rectangle::AUXILIARY_ID())
129       ->setValue(boolean(AUXILIARY_ID())->value());
130   myRectangleFeature->execute();
131 }
132
133 void SketchPlugin_MacroRectangle::attributeChanged(const std::string& theID)
134 {
135   if(theID == TYPE_ID()) {
136     SketchPlugin_Tools::resetAttribute(this, START1_ID());
137     SketchPlugin_Tools::resetAttribute(this, END1_ID());
138     SketchPlugin_Tools::resetAttribute(this, CENTER_ID());
139     SketchPlugin_Tools::resetAttribute(this, START2_ID());
140   }
141   else if (theID == START1_ID() || theID == END1_ID() ||
142            theID == START2_ID() || theID == CENTER_ID())
143   {
144     // update points
145     startPoint();
146     endPoint();
147   }
148   bool aWasBlocked = data()->blockSendAttributeUpdated(true);
149   data()->blockSendAttributeUpdated(aWasBlocked, false);
150 }
151
152 AISObjectPtr SketchPlugin_MacroRectangle::getAISObject(AISObjectPtr thePrevious)
153 {
154   SketchPlugin_Sketch* aSketch = sketch();
155
156   if(!aSketch || !myEndPoint || ! myStartPoint)
157     return AISObjectPtr();
158
159   std::vector<double> aX = {myStartPoint->x(), myStartPoint->x(), myEndPoint->x(), myEndPoint->x()};
160   std::vector<double> aY = {myStartPoint->y(), myEndPoint->y(), myEndPoint->y(), myStartPoint->y()};
161
162   std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
163   /// Update coordinates of rectangle lines
164
165   std::set<int> createdPointIndex;
166   for(unsigned  i = 0; i < 4; i++)
167   {
168     std::shared_ptr<GeomAPI_Pnt> theStart(aSketch->to3D(aX[(i+3)%4], aY[(i+3)%4]));
169     std::shared_ptr<GeomAPI_Pnt> theEnd(aSketch->to3D(aX[i], aY[i]));
170     GeomShapePtr aLine = GeomAlgoAPI_EdgeBuilder::line(theStart, theEnd);
171
172     if(aLine)
173     {
174       aShapes.push_back(aLine);
175       if(createdPointIndex.insert(i).second){
176         GeomShapePtr aPointShape = GeomAlgoAPI_PointBuilder::vertex(theStart);
177         aShapes.push_back(aPointShape);
178       }
179       if(createdPointIndex.insert((i+1)%4).second){
180         GeomShapePtr aPointShape = GeomAlgoAPI_PointBuilder::vertex(theEnd);
181         aShapes.push_back(aPointShape);
182       }
183     }
184   }
185
186   if(string(TYPE_ID())->value() == START_CENTER_POINT_TYPE_ID()){
187     /// draw  a line start->center
188     std::shared_ptr<GeomDataAPI_Point2D> aCenterPoint =
189         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
190
191     std::shared_ptr<GeomAPI_Pnt> theStart(aSketch->to3D(myStartPoint->x(), myStartPoint->y()));
192     std::shared_ptr<GeomAPI_Pnt> theEnd(aSketch->to3D(aCenterPoint->x(), aCenterPoint->y()));
193     GeomShapePtr aLine = GeomAlgoAPI_EdgeBuilder::line(theStart, theEnd);
194     if(aLine)
195       aShapes.push_back(aLine);
196   }
197
198   // Compute a rectangle in 3D view.
199
200   std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
201   AISObjectPtr anAIS = thePrevious;
202   if(!anAIS.get()) {
203     anAIS.reset(new GeomAPI_AISObject());
204   }
205   anAIS->createShape(aCompound);
206
207   // Modify attributes
208   SketchPlugin_Tools::customizeFeaturePrs(anAIS, boolean(AUXILIARY_ID())->value());
209
210   return anAIS;
211 }