Salome HOME
Copyright update 2022
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_IntersectionPoint.cpp
1 // Copyright (C) 2014-2022  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_IntersectionPoint.h"
21 #include "SketchPlugin_Point.h"
22
23 #include <ModelAPI_AttributeSelection.h>
24 #include <ModelAPI_AttributeRefList.h>
25 #include <ModelAPI_ResultConstruction.h>
26 #include <ModelAPI_Session.h>
27 #include <ModelAPI_Tools.h>
28 #include <ModelAPI_Validator.h>
29
30 #include <GeomAPI_Edge.h>
31 #include <GeomAPI_Lin.h>
32 #include <GeomAPI_Pnt2d.h>
33 #include <GeomDataAPI_Point2D.h>
34
35 SketchPlugin_IntersectionPoint::SketchPlugin_IntersectionPoint()
36   : SketchPlugin_SketchEntity(),
37     myIsComputing(false)
38 {
39 }
40
41 void SketchPlugin_IntersectionPoint::initDerivedClassAttributes()
42 {
43   data()->addAttribute(EXTERNAL_FEATURE_ID(), ModelAPI_AttributeSelection::typeId());
44   data()->addAttribute(INTERSECTION_POINTS_ID(), ModelAPI_AttributeRefList::typeId());
45   data()->attribute(INTERSECTION_POINTS_ID())->setIsArgument(false);
46
47   data()->addAttribute(INCLUDE_INTO_RESULT(), ModelAPI_AttributeBoolean::typeId());
48
49   data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
50   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
51
52   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID());
53 }
54
55 void SketchPlugin_IntersectionPoint::execute()
56 {
57   AttributeRefListPtr anIntersectionsList = reflist(INTERSECTION_POINTS_ID());
58   if (!anIntersectionsList || !anIntersectionsList->isInitialized())
59     return; // no intersections
60
61   computePoint(EXTERNAL_FEATURE_ID());
62 }
63
64 void SketchPlugin_IntersectionPoint::attributeChanged(const std::string& theID)
65 {
66   // compute intersection between line and sketch plane
67   computePoint(theID);
68 }
69
70 void SketchPlugin_IntersectionPoint::computePoint(const std::string& theID)
71 {
72   if (theID != EXTERNAL_FEATURE_ID() && theID != EXTERNAL_ID())
73     return;
74
75   if (myIsComputing)
76     return;
77   myIsComputing = true;
78
79   AttributeSelectionPtr anExternalFeature = selection(EXTERNAL_FEATURE_ID());
80
81   GeomShapePtr aShape;
82   GeomEdgePtr anEdge;
83   if (anExternalFeature)
84     aShape = anExternalFeature->value();
85   if (!aShape && anExternalFeature->context())
86     aShape = anExternalFeature->context()->shape();
87   if (aShape && aShape->isEdge())
88     anEdge = GeomEdgePtr(new GeomAPI_Edge(aShape));
89
90   if (anEdge) {
91     std::shared_ptr<GeomAPI_Pln> aSketchPlane = sketch()->plane();
92
93     std::list<GeomPointPtr> anIntersectionsPoints;
94     anEdge->intersectWithPlane(aSketchPlane, anIntersectionsPoints);
95
96     AttributeRefListPtr anIntersectionsList = reflist(INTERSECTION_POINTS_ID());
97     std::list<ObjectPtr> anExistentIntersections = anIntersectionsList->list();
98     std::list<ObjectPtr>::const_iterator aExistInterIt = anExistentIntersections.begin();
99
100     const std::list<ResultPtr>& aResults = results();
101     std::list<ResultPtr>::const_iterator aResIt = aResults.begin();
102
103     int aResultIndex = 0;
104     for (std::list<GeomPointPtr>::iterator aPntIt = anIntersectionsPoints.begin();
105          aPntIt != anIntersectionsPoints.end(); ++aPntIt, ++aResultIndex) {
106       std::shared_ptr<SketchPlugin_Point> aCurSketchPoint;
107       if (aExistInterIt == anExistentIntersections.end()) {
108         keepCurrentFeature();
109
110         // create new point
111         aCurSketchPoint = std::dynamic_pointer_cast<SketchPlugin_Point>(
112           sketch()->addFeature(SketchPlugin_Point::ID()));
113         aCurSketchPoint->boolean(COPY_ID())->setValue(true);
114         anIntersectionsList->append(aCurSketchPoint);
115
116         restoreCurrentFeature();
117       } else {
118         // update existent point
119         aCurSketchPoint = std::dynamic_pointer_cast<SketchPlugin_Point>(*aExistInterIt);
120         ++aExistInterIt;
121       }
122
123       ResultConstructionPtr aCurResult;
124       if (aResIt == aResults.end()) {
125         // create new result
126         aCurResult = document()->createConstruction(data(), aResultIndex);
127         aCurResult->setIsInHistory(false);
128         aCurResult->setDisplayed(false);
129       } else {
130         // update existent result
131         aCurResult = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aResIt);
132         aCurResult->setShape(std::shared_ptr<GeomAPI_Edge>());
133         ++aResIt;
134       }
135
136       // update coordinates of intersection
137       GeomPnt2dPtr aPointInSketch = sketch()->to2D(*aPntIt);
138       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
139         aCurSketchPoint->attribute(SketchPlugin_Point::COORD_ID()))->setValue(aPointInSketch);
140       aCurSketchPoint->execute();
141
142       // update result
143       aCurResult->setShape(aCurSketchPoint->lastResult()->shape());
144       setResult(aCurResult, aResultIndex);
145
146       // make intersection point external
147       GeomShapePtr anEmptyVal;
148       aCurSketchPoint->selection(EXTERNAL_ID())->setValue(aCurResult, anEmptyVal);
149     }
150
151     // remove rest results from previous pass
152     removeResults(aResultIndex);
153     std::set<FeaturePtr> aFeaturesToBeRemoved;
154     for (; aExistInterIt != anExistentIntersections.end(); ++aExistInterIt) {
155       aFeaturesToBeRemoved.insert(ModelAPI_Feature::feature(*aExistInterIt));
156       anIntersectionsList->removeLast();
157     }
158     ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
159
160     if (theID != EXTERNAL_ID())
161       selection(EXTERNAL_ID())->selectValue(anExternalFeature);
162   }
163   myIsComputing = false;
164 }