1 // Copyright (C) 2014-2021 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "PartSet_PreviewSketchPlane.h"
21 #include "PartSet_Tools.h"
23 #include <ModuleBase_IWorkshop.h>
25 #include <ModelAPI_ResultBody.h>
26 #include <ModelAPI_ResultConstruction.h>
27 #include <ModelAPI_CompositeFeature.h>
28 #include <ModelAPI_Tools.h>
30 #include <GeomAPI_AISObject.h>
31 #include <GeomAPI_Pnt.h>
33 #include <XGUI_Tools.h>
34 #include <XGUI_Displayer.h>
35 #include <XGUI_Workshop.h>
37 #include <Config_PropManager.h>
38 #include <GeomAlgoAPI_FaceBuilder.h>
40 #include <SketchPlugin_Sketch.h>
41 #include <SketchPlugin_SketchEntity.h>
43 #include <BRepBndLib.hxx>
45 PartSet_PreviewSketchPlane::PartSet_PreviewSketchPlane()
46 : myPreviewIsDisplayed(false), mySizeOfView(0), myIsUseSizeOfView(false)
50 void PartSet_PreviewSketchPlane::eraseSketchPlane(ModuleBase_IWorkshop* theWorkshop,
51 const bool isClearPlane)
53 if (myPreviewIsDisplayed) {
54 XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
55 aDisp->eraseAIS(myPlane, false);
56 myPreviewIsDisplayed = false;
58 if (isClearPlane) clearPlanePreview();
61 void PartSet_PreviewSketchPlane::displaySketchPlane(ModuleBase_IWorkshop* theWorkshop)
63 if (myPlane.get() && (!myPreviewIsDisplayed)) {
64 XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
65 aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
66 myPreviewIsDisplayed = true;
71 void PartSet_PreviewSketchPlane::clearPlanePreview()
73 myPlane = std::shared_ptr<GeomAPI_AISObject>();
74 myShape = std::shared_ptr<GeomAPI_Shape>();
78 void PartSet_PreviewSketchPlane::createSketchPlane(const CompositeFeaturePtr& theSketch,
79 ModuleBase_IWorkshop* theWorkshop)
81 // plane is visualized only if sketch plane is filled
82 if (!PartSet_Tools::sketchPlane(theSketch).get())
85 AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
86 (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
90 if (myShape.get() && myShape->isSame(aSelAttr->value()) && myPlane.get())
93 XGUI_Displayer* aDisp = XGUI_Tools::workshop(theWorkshop)->displayer();
94 if (myPreviewIsDisplayed) {
95 aDisp->eraseAIS(myPlane, false);
99 // selected linear face parameters
100 myShape = aSelAttr->value();
101 // this case is needed by constructing sketch on a plane, where result shape is equal
102 // to context result, therefore value() returns NULL and we should use shape of context.
103 if (!myShape.get() && aSelAttr->context().get())
104 myShape = aSelAttr->context()->shape();
106 if (!myShape.get()) {
107 // Create Preview for default planes
108 std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
109 theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
110 std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
111 theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
113 double aFaceSize = myIsUseSizeOfView ? mySizeOfView
114 : Config_PropManager::real(SKETCH_TAB_NAME, "planes_size");
115 if (aFaceSize <= Precision::Confusion())
116 aFaceSize = 200; // Set default value
118 myShape = GeomAlgoAPI_FaceBuilder::squareFace(
119 myViewCentralPoint.get() ? myViewCentralPoint : anOrigin->pnt(), aNormal->dir(), aFaceSize);
121 else if (myIsUseSizeOfView && (mySizeOfView > 0)) {
122 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(myShape));
123 std::shared_ptr<GeomAPI_Pln> aPlane = aFace->getPlane();
125 double anA, aB, aC, aD;
126 aPlane->coefficients(anA, aB, aC, aD);
127 std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
128 std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
129 std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
130 aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
131 std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
132 myShape = GeomAlgoAPI_FaceBuilder::squareFace(
133 myViewCentralPoint.get() ? myViewCentralPoint : anOrigPnt, aNormDir, mySizeOfView);
136 myPlane = createPreviewPlane();
138 aDisp->displayAIS(myPlane, false/*load object in selection*/, 1/*shaded*/, false);
139 myPreviewIsDisplayed = true;
142 double maximumSize(double theXmin, double theYmin, double theZmin,
143 double theXmax, double theYmax, double theZmax)
145 double aSize = fabs(theXmax - theXmin);
146 double aSizeToCompare = fabs(theYmax - theYmin);
147 if (aSizeToCompare > aSize)
148 aSize = aSizeToCompare;
149 aSizeToCompare = fabs(theZmax - theZmin);
150 if (aSizeToCompare > aSize)
151 aSize = aSizeToCompare;
156 bool PartSet_PreviewSketchPlane::getDefaultSizeOfView(
157 const CompositeFeaturePtr& theSketch, double& theSizeOfView,
158 std::shared_ptr<GeomAPI_Pnt>& theCentralPnt)
160 if (!PartSet_Tools::sketchPlane(theSketch).get())
163 AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
164 (theSketch->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
166 myShape = aSelAttr->value();
167 // this case is needed by constructing sketch on a plane, where result shape is equal
168 // to context result, therefore value() returns NULL and we should use shape of context.
169 if (!myShape.get() && aSelAttr->context().get())
170 myShape = aSelAttr->context()->shape();
177 int aNumberOfSubs = theSketch->numberOfSubs();
178 for (int aSubFeatureId = 0; aSubFeatureId < aNumberOfSubs; aSubFeatureId++) {
179 FeaturePtr aFeature = theSketch->subFeature(aSubFeatureId);
183 std::list<ResultPtr> aResults = aFeature->results();
184 std::list<ResultPtr>::const_iterator aResultIt;
185 for (aResultIt = aResults.begin(); aResultIt != aResults.end(); ++aResultIt) {
186 ResultPtr aResult = *aResultIt;
187 std::shared_ptr<GeomAPI_Shape> aShapePtr = aResult->shape();
188 if (aShapePtr.get()) {
189 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
192 BRepBndLib::Add(aShape, aBox);
199 double aXmin, aXmax, anYmin, anYmax, aZmin, aZmax;
200 aBox.Get(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
202 theSizeOfView = maximumSize(aXmin, anYmin, aZmin, aXmax, anYmax, aZmax);
203 if (theSizeOfView > 0) {
204 gp_Pnt aCentre(aXmax-fabs(aXmax-aXmin)/2., anYmax-fabs(anYmax-anYmin)/2.,
205 aZmax - fabs(aZmax-aZmin)/2.);
206 theCentralPnt = std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(),
212 void PartSet_PreviewSketchPlane::setSizeOfView(double theSizeOfView, bool isUseSizeOfView,
213 const std::shared_ptr<GeomAPI_Pnt>& theCentralPoint)
215 mySizeOfView = theSizeOfView;
216 myIsUseSizeOfView = isUseSizeOfView;
218 myViewCentralPoint = theCentralPoint;
221 AISObjectPtr PartSet_PreviewSketchPlane::createPreviewPlane()
224 myPlane->createShape(myShape);
228 AISObjectPtr aAIS = AISObjectPtr(new GeomAPI_AISObject());
229 aAIS->createShape(myShape);
230 std::vector<int> aColor = Config_PropManager::color("Visualization", "sketch_preview_plane");
231 if (aColor.size() == 3)
232 aAIS->setColor(aColor[0], aColor[1], aColor[2]);
233 aAIS->setTransparensy(0.8);
235 int aDispMode = 1; // shading
236 Handle(AIS_InteractiveObject) anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
237 if (!anAISIO.IsNull()) {
238 //anAISIO->SetInfiniteState(Standard_True);
239 anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
240 anAISIO->SetDisplayMode(aDispMode);