Salome HOME
Rectangle feature: coincidence debug: 1. lines should not be updated in execute becau...
[modules/shaper.git] / src / PythonAddons / macros / rectangle / feature.py
1 """
2 Macro-feature to produce rectangle in the sketcher
3 Author: Artem ZHIDKOV
4 Copyright (C) 2016-20xx CEA/DEN, EDF R&D
5 """
6
7 import model
8 import ModelAPI
9 import GeomDataAPI
10
11 class SketchPlugin_Rectangle(model.Feature):
12     """
13     Implementation of rectangle creation.
14
15     It produced 2 horizontal lines and 2 vertical lines connected by coincidence constraints
16     """
17
18 # Initializations
19
20     def __init__(self):
21         """x.__init__(...) initializes x; see x.__class__.__doc__ for signature"""
22         model.Feature.__init__(self)
23
24     @staticmethod
25     def ID():
26         """Rectangle feature kind."""
27         return "SketchRectangle"
28
29     @staticmethod
30     def START_ID():
31         """Returns ID of first corner."""
32         return "RectStartPoint"
33
34     @staticmethod
35     def END_ID():
36         """Returns ID of second corner."""
37         return "RectEndPoint"
38
39     @staticmethod
40     def AUXILIARY_ID():
41         """Returns whether the rectangle is accessory."""
42         return "Auxiliary"
43
44     @staticmethod
45     def LINES_LIST_ID():
46         """Returns ID of list containing lines created."""
47         return "RectangleList"
48
49     def getKind(self):
50         """Override Feature.getKind()"""
51         return SketchPlugin_Rectangle.ID()
52
53
54 # Initialization of the rectangle
55
56     def initAttributes(self):
57         """Override Feature.initAttributes()"""
58         # Flag whether the rectangle is accessory
59         self.data().addAttribute(self.AUXILIARY_ID(), ModelAPI.ModelAPI_AttributeBoolean_typeId())
60         # Creating corners of the rectangle
61         self.data().addAttribute(self.START_ID(), GeomDataAPI.GeomDataAPI_Point2D_typeId())
62         self.data().addAttribute(self.END_ID(), GeomDataAPI.GeomDataAPI_Point2D_typeId())
63         # Creating list to store lines
64         self.data().addAttribute(self.LINES_LIST_ID(), ModelAPI.ModelAPI_AttributeRefList_typeId())
65         ModelAPI.ModelAPI_Session.get().validators().registerNotObligatory(self.getKind(), self.LINES_LIST_ID())
66
67     def isMacro(self):
68         """
69         Override Feature.isMacro().
70         Rectangle feature is macro: removes itself on the creation transaction finish.
71         """
72         return True
73
74 # Edition of the rectangle
75
76     def execute(self):
77         # Retrieving list of already created lines
78         aLinesList = self.reflist(self.LINES_LIST_ID())
79         aNbLines = aLinesList.size()
80         if aNbLines == 0:
81             # Search the sketch containing this rectangle
82             self.__sketch = None
83             aRefs = self.data().refsToMe();
84             for iter in aRefs:
85                 aFeature = ModelAPI.objectToFeature(iter.owner())
86                 if aFeature.getKind() == "Sketch":
87                     self.__sketch = ModelAPI.featureToCompositeFeature(aFeature)
88                     break
89             # Create lines to compose the rectangle
90             for i in range (0, 4):
91                 aLine = self.__sketch.addFeature("SketchLine")
92                 aLinesList.append(aLine)
93             aNbLines = aLinesList.size()
94             # Create constraints to keep the rectangle
95             for i in range (0, aNbLines):
96                 aLine = ModelAPI.objectToFeature(aLinesList.object(i))
97                 # connect neighbor lines by coincidence
98                 iPrev = i - 1
99                 if iPrev < 0:
100                     iPrev = aNbLines - 1
101                 aPrevLine = ModelAPI.objectToFeature(aLinesList.object(iPrev))
102                 aCoincidence = self.__sketch.addFeature("SketchConstraintCoincidence")
103                 aRefAttrA = aCoincidence.refattr("ConstraintEntityA")
104                 aRefAttrB = aCoincidence.refattr("ConstraintEntityB")
105                 aRefAttrA.setAttr(aPrevLine.attribute("EndPoint"))
106                 aRefAttrB.setAttr(aLine.attribute("StartPoint"))
107             # Flags which show horizontal or vertical constraint is build for correponding line
108             self.__isHV = [False, False, False, False]
109             # Update coordinates of created lines
110             self.updateLines()
111         # Add horizontal and vertical constraint for the lines which already have result
112         for i in range (0, aNbLines):
113             if self.__isHV[i]:
114                 continue
115             aLine = ModelAPI.objectToFeature(aLinesList.object(i))
116             aLineResult = aLine.lastResult()
117             if aLineResult is None:
118                 continue
119             aHVName = "SketchConstraintHorizontal"
120             if i % 2 == 1:
121                 aHVName = "SketchConstraintVertical"
122             aHVConstraint = self.__sketch.addFeature(aHVName)
123             aRefAttrA = aHVConstraint.refattr("ConstraintEntityA")
124             aRefAttrA.setObject(aLine.lastResult())
125             self.__isHV[i] = True
126
127     def attributeChanged(self, theID):
128         if theID == self.START_ID() or theID == self.END_ID():
129             aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
130             aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
131             if aStartPoint.isInitialized() and aEndPoint.isInitialized:
132                 self.updateLines()
133
134     def updateLines(self):
135         # Retrieving list of already created lines
136         aLinesList = self.reflist(self.LINES_LIST_ID())
137         aNbLines = aLinesList.size()
138
139         aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
140         aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
141         aX = [aStartPoint.x(), aStartPoint.x(), aEndPoint.x(), aEndPoint.x()]
142         aY = [aStartPoint.y(), aEndPoint.y(), aEndPoint.y(), aStartPoint.y()]
143
144         # Update coordinates of rectangle lines
145         for i in range (0, aNbLines):
146             aLine = ModelAPI.objectToFeature(aLinesList.object(i))
147             aLineStart = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("StartPoint"))
148             aLineEnd = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("EndPoint"))
149             aLineStart.setValue(aX[i-1], aY[i-1])
150             aLineEnd.setValue(aX[i], aY[i])