Salome HOME
Issues #2027, #2024, #2063, #2067: reentrant message to fill new operation by result...
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_ConstraintCoincidence.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:    SketchPlugin_ConstraintCoincidence.cpp
4 // Created: 08 May 2014
5 // Author:  Artem ZHIDKOV
6
7 #include "SketchPlugin_ConstraintCoincidence.h"
8
9 #include <SketchPlugin_Point.h>
10 #include <SketchPlugin_Line.h>
11 #include <SketchPlugin_Arc.h>
12 #include <SketchPlugin_Circle.h>
13
14 #include <ModelAPI_Events.h>
15 #include <ModelGeomAlgo_Point2D.h>
16 #include <GeomDataAPI_Point2D.h>
17
18 #include <SketcherPrs_Factory.h>
19
20 #include <Events_Loop.h>
21
22 SketchPlugin_ConstraintCoincidence::SketchPlugin_ConstraintCoincidence()
23 {
24 }
25
26 void SketchPlugin_ConstraintCoincidence::initAttributes()
27 {
28   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
29   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
30 }
31
32 void SketchPlugin_ConstraintCoincidence::execute()
33 {
34 }
35
36 AISObjectPtr SketchPlugin_ConstraintCoincidence::getAISObject(AISObjectPtr thePrevious)
37 {
38   if (!sketch())
39     return thePrevious;
40
41   AISObjectPtr anAIS = SketcherPrs_Factory::coincidentConstraint(this, sketch()->coordinatePlane(),
42                                                                  thePrevious);
43   return anAIS;
44 }
45
46 FeaturePtr SketchPlugin_ConstraintCoincidence::findCoincidenceFeature(const FeaturePtr& theFeature1,
47                                                                       const FeaturePtr& theFeature2)
48 {
49   FeaturePtr aResultFeature;
50
51   std::list<AttributePtr> anAttrList;
52   if (theFeature1->getKind() == SketchPlugin_Circle::ID() ||
53       theFeature2->getKind() == SketchPlugin_Circle::ID())
54     return aResultFeature;
55
56   if (theFeature2->getKind() == SketchPlugin_Line::ID()) {
57     anAttrList.push_back(theFeature2->attribute(SketchPlugin_Line::START_ID()));
58     anAttrList.push_back(theFeature2->attribute(SketchPlugin_Line::END_ID()));
59   } else if (theFeature2->getKind() == SketchPlugin_Arc::ID()) {
60     anAttrList.push_back(theFeature2->attribute(SketchPlugin_Arc::START_ID()));
61     anAttrList.push_back(theFeature2->attribute(SketchPlugin_Arc::END_ID()));
62   }
63
64   const std::set<AttributePtr>& aRefsList = theFeature1->data()->refsToMe();
65   std::set<AttributePtr>::const_iterator aRefIt = aRefsList.begin();
66   for (; aRefIt != aRefsList.end() && !aResultFeature.get(); ++aRefIt) {
67     FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIt)->owner());
68     if (aConstrFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
69       continue;
70     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
71     AttributePtr anAttr = aRefAttr->attr();
72     if (anAttr->id() == SketchPlugin_Arc::CENTER_ID())
73       continue;
74
75     anAttr = aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
76     if (anAttr == *aRefIt)
77       anAttr = aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
78
79     aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
80     if (!aRefAttr)
81       continue;
82     anAttr = aRefAttr->attr();
83     for (std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
84          anIt != anAttrList.end() && !aResultFeature.get(); ++anIt)
85       if (*anIt == anAttr)
86         aResultFeature = aConstrFeature;
87   }
88   return aResultFeature;
89 }
90
91 AttributePoint2DPtr SketchPlugin_ConstraintCoincidence::getPoint(const FeaturePtr& theFeature)
92 {
93   AttributePoint2DPtr aPoint = ModelGeomAlgo_Point2D::getPointOfRefAttr(theFeature.get(),
94                                                          SketchPlugin_Constraint::ENTITY_A(),
95                                  SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
96   if (!aPoint.get())
97     aPoint = ModelGeomAlgo_Point2D::getPointOfRefAttr(theFeature.get(),
98                                                       SketchPlugin_Constraint::ENTITY_B(),
99                                  SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
100   return aPoint;
101 }
102
103 void SketchPlugin_ConstraintCoincidence::createCoincidenceFeature(SketchPlugin_Sketch* theSketch,
104                                                   const std::shared_ptr<GeomDataAPI_Point2D>& thePoint1,
105                                                   const std::shared_ptr<GeomDataAPI_Point2D>& thePoint2)
106 {
107   FeaturePtr aFeature;
108   if (theSketch) {
109     aFeature = theSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
110   } else {
111     std::shared_ptr<ModelAPI_Document> aDoc = theSketch->document();
112     aFeature = aDoc->addFeature(SketchPlugin_ConstraintCoincidence::ID());
113   }
114
115   std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
116
117   std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
118       ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
119   aRef1->setAttr(thePoint1);
120
121   std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
122       ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
123   aRef2->setAttr(thePoint2);
124
125   // we need to flush created signal in order to coincidence is processed by solver
126   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
127 }