Salome HOME
Merge commit 'refs/tags/V9_2_0^{}'
[modules/shaper.git] / src / PartSet / PartSet_PreviewSketchPlane.cpp
1 // Copyright (C) 2014-2017  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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "PartSet_PreviewSketchPlane.h"
22 #include "PartSet_Tools.h"
23
24 #include <ModuleBase_IWorkshop.h>
25
26 #include <ModelAPI_ResultBody.h>
27 #include <ModelAPI_ResultConstruction.h>
28 #include <ModelAPI_CompositeFeature.h>
29 #include <ModelAPI_Tools.h>
30
31 #include <GeomAPI_AISObject.h>
32 #include <GeomAPI_Pnt.h>
33
34 #include <XGUI_Tools.h>
35 #include <XGUI_Displayer.h>
36 #include <XGUI_Workshop.h>
37
38 #include <Config_PropManager.h>
39 #include <GeomAlgoAPI_FaceBuilder.h>
40
41 #include <SketchPlugin_Sketch.h>
42 #include <SketchPlugin_SketchEntity.h>
43
44 #include <BRepBndLib.hxx>
45
46 PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane()
47  : myPreviewIsDisplayed(false), mySizeOfView(0), myIsUseSizeOfView(false)
48 {
49 }
50
51 void PartSet_PreviewSketchPlane::eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop,
52                                                   const bool isClearPlane)
53 {
54   if (myPreviewIsDisplayed) {
55     XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
56     aDisp->eraseAIS(myPlane, false);
57     if (isClearPlane) {
58       myPlane = std::shared_ptr<GeomAPI_AISObject>();
59       myShape = std::shared_ptr<GeomAPI_Shape>();
60     }
61     myPreviewIsDisplayed = false;
62   }
63 }
64
65 void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& theSketch,
66                                                    ModuleBase_IWorkshop* theWorkshop)
67 {
68   // the preview plane has been already created and displayed
69   if (myPreviewIsDisplayed)
70     return;
71
72   // plane is visualized only if sketch plane is filled
73   if (!PartSet_Tools::sketchPlane(theSketch).get())
74     return;
75
76   if (!myPlane) { // If planes are not created
77     // Create Preview
78     // selected linear face parameters
79     AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
80       (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
81     if (aSelAttr) {
82       myShape = aSelAttr->value();
83       // this case is needed by constructing sketch on a plane, where result shape is equal
84       // to context result, therefore value() returns NULL and we should use shape of context.
85       if (!myShape.get() && aSelAttr->context().get())
86         myShape = aSelAttr->context()->shape();
87     }
88     if (!myShape.get()) {
89       // Create Preview for default planes
90       std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
91           theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
92       std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
93           theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
94
95       double aFaceSize = myIsUseSizeOfView ? mySizeOfView
96         : Config_PropManager::real(SKETCH_TAB_NAME, "planes_size");
97       if (aFaceSize <= Precision::Confusion())
98         aFaceSize = 200;   // Set default value
99
100       myShape = GeomAlgoAPI_FaceBuilder::squareFace(
101         myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize);
102     }
103     myPlane = createPreviewPlane();
104   }
105
106   XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
107   aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
108   myPreviewIsDisplayed = true;
109 }
110
111 double maximumSize(double theXmin, double theYmin, double theZmin,
112                    double theXmax, double theYmax, double theZmax)
113 {
114   double aSize = fabs(theXmax - theXmin);
115   double aSizeToCompare = fabs(theYmax - theYmin);
116   if (aSizeToCompare > aSize)
117     aSize = aSizeToCompare;
118   aSizeToCompare = fabs(theZmax - theZmin);
119   if (aSizeToCompare > aSize)
120     aSize = aSizeToCompare;
121
122   return aSize;
123 }
124
125 bool PartSet_PreviewSketchPlane::getDefaultSizeOfView(
126   const CompositeFeaturePtr& theSketch, double& theSizeOfView,
127   std::shared_ptr<GeomAPI_Pnt>& theCentralPnt)
128 {
129   if (!PartSet_Tools::sketchPlane(theSketch).get())
130     return false;
131
132   AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
133     (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
134   if (aSelAttr) {
135     myShape = aSelAttr->value();
136     // this case is needed by constructing sketch on a plane, where result shape is equal
137     // to context result, therefore value() returns NULL and we should use shape of context.
138     if (!myShape.get() && aSelAttr->context().get())
139       myShape = aSelAttr->context()->shape();
140   }
141
142   if (myShape.get())
143     return false;
144
145   Bnd_Box aBox;
146   int aNumberOfSubs = theSketch->numberOfSubs();
147   for (int aSubFeatureId = 0; aSubFeatureId < aNumberOfSubs; aSubFeatureId++) {
148     FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId);
149     if (!aFeature.get())
150       continue;
151
152     std::list<ResultPtr> aResults = aFeature->results();
153     std::list<ResultPtr>::const_iterator aResultIt;
154     for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) {
155       ResultPtr aResult = *aResultIt;
156       std::shared_ptr<GeomAPI_Shape> aShapePtr = aResult->shape();
157       if (aShapePtr.get()) {
158         TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
159         if (aShape.IsNull())
160           continue;
161         BRepBndLib::Add(aShape, aBox);
162       }
163     }
164   }
165   if (aBox.IsVoid())
166     return 0;
167
168   double aXmin, aXmax, anYmin, anYmax, aZmin, aZmax;
169   aBox.Get(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
170
171   theSizeOfView = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
172   if (theSizeOfView > 0) {
173     gp_Pnt aCentre(aXmax-fabs(aXmax-aXmin)/2., anYmax-fabs(anYmax-anYmin)/2.,
174                    aZmax - fabs(aZmax-aZmin)/2.);
175     theCentralPnt = std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(),
176                                                                  aCentre.Z()));
177   }
178   return true;
179 }
180
181 void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView,
182   const std::shared_ptr<GeomAPI_Pnt>& theCentralPoint)
183 {
184   mySizeOfView = theSizeOfView;
185   myIsUseSizeOfView = isUseSizeOfView;
186
187   myViewCentralPoint = theCentralPoint;
188 }
189
190 AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane()
191 {
192   if (myPlane.get()) {
193     myPlane->createShape(myShape);
194     return myPlane;
195   }
196   else {
197     AISObjectPtr aAIS = AISObjectPtr(new GeomAPI_AISObject());
198     aAIS->createShape(myShape);
199     std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_preview_plane");
200     if (aColor.size() == 3)
201       aAIS->setColor(aColor[0], aColor[1], aColor[2]);
202     aAIS->setTransparensy(0.8);
203
204     int aDispMode = 1; // shading
205     Handle(AIS_InteractiveObject) anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
206     if (!anAISIO.IsNull()) {
207       //anAISIO->SetInfiniteState(Standard_True);
208       anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
209       anAISIO->SetDisplayMode(aDispMode);
210     }
211     return aAIS;
212   }
213 }