Salome HOME
8ce3a4b4fc5a85a53d536ff0494ff72bfc904ce0
[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 == 1:
81             # Create 1-4 lines to compose the rectangle
82             for i in range (0, 3):
83                 aLine = self.__sketch.addFeature("SketchLine")
84                 aLinesList.append(aLine)
85             aNbLines = aLinesList.size()
86             # Create constraints to keep the rectangle
87             for i in range (0, aNbLines):
88                 aLine = ModelAPI.objectToFeature(aLinesList.object(i))
89                 # connect neighbor lines by coincidence
90                 iPrev = i - 1
91                 if iPrev < 0:
92                     iPrev = aNbLines - 1
93                 aPrevLine = ModelAPI.objectToFeature(aLinesList.object(iPrev))
94                 aCoincidence = self.__sketch.addFeature("SketchConstraintCoincidence")
95                 aRefAttrA = aCoincidence.refattr("ConstraintEntityA")
96                 aRefAttrB = aCoincidence.refattr("ConstraintEntityB")
97                 aRefAttrA.setAttr(aPrevLine.attribute("EndPoint"))
98                 aRefAttrB.setAttr(aLine.attribute("StartPoint"))
99             # Flags which show horizontal or vertical constraint is build for correponding line
100             self.__isHV = [False, False, False, False]
101             # Update coordinates of created lines
102             self.updateLines()
103         # Add horizontal and vertical constraint for the lines which already have result
104         for i in range (0, aNbLines):
105             if self.__isHV[i]:
106                 continue
107             aLine = ModelAPI.objectToFeature(aLinesList.object(i))
108             aLineResult = aLine.lastResult()
109             if aLineResult is None:
110                 continue
111             aHVName = "SketchConstraintHorizontal"
112             if i % 2 == 1:
113                 aHVName = "SketchConstraintVertical"
114             aHVConstraint = self.__sketch.addFeature(aHVName)
115             aRefAttrA = aHVConstraint.refattr("ConstraintEntityA")
116             aRefAttrA.setObject(aLine.lastResult())
117             self.__isHV[i] = True
118
119     def attributeChanged(self, theID):
120         if theID == self.START_ID() or theID == self.END_ID():
121             # Search the sketch containing this rectangle
122             self.__sketch = None
123             aRefs = self.data().refsToMe();
124             for iter in aRefs:
125                 aFeature = ModelAPI.objectToFeature(iter.owner())
126                 if aFeature.getKind() == "Sketch":
127                     self.__sketch = ModelAPI.featureToCompositeFeature(aFeature)
128                     break
129
130             aLinesList = self.reflist(self.LINES_LIST_ID())
131             aNbLines = aLinesList.size()
132             if aNbLines == 0:
133                 # Create first line to be able to create a coincidence with selected point/feature
134                 for i in range (0, 1):
135                     aLine = self.__sketch.addFeature("SketchLine")
136                     aLinesList.append(aLine)
137
138             aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
139             aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
140             if aStartPoint.isInitialized() and aEndPoint.isInitialized():
141               self.updateLines()
142             else:
143               self.updateStartPoint()
144         if theID == self.AUXILIARY_ID():
145             anAuxiliary = self.data().boolean(self.AUXILIARY_ID()).value()
146             aLinesList = self.reflist(self.LINES_LIST_ID())
147             aNbLines = aLinesList.size()
148             # Update coordinates of rectangle lines
149             for i in range (0, aNbLines):
150                 aLine = ModelAPI.objectToFeature(aLinesList.object(i))
151                 aLine.data().boolean("Auxiliary").setValue(anAuxiliary)
152
153
154     def updateLines(self):
155         # Retrieving list of already created lines
156         aLinesList = self.reflist(self.LINES_LIST_ID())
157         aNbLines = aLinesList.size()
158         aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
159         aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
160         aX = [aStartPoint.x(), aStartPoint.x(), aEndPoint.x(), aEndPoint.x()]
161         aY = [aStartPoint.y(), aEndPoint.y(), aEndPoint.y(), aStartPoint.y()]
162
163         # Update coordinates of rectangle lines
164         for i in range (0, aNbLines):
165             aLine = ModelAPI.objectToFeature(aLinesList.object(i))
166             aLineStart = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("StartPoint"))
167             aLineEnd = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("EndPoint"))
168             aLineStart.setValue(aX[i-1], aY[i-1])
169             aLineEnd.setValue(aX[i], aY[i])
170
171     def updateStartPoint(self):
172         # Retrieving list of already created lines
173         aLinesList = self.reflist(self.LINES_LIST_ID())
174         aNbLines = aLinesList.size()
175
176         aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
177         aX = aStartPoint.x()
178         aY = aStartPoint.y()
179
180         # Update coordinates of rectangle lines
181         for i in range (0, aNbLines):
182             aLine = ModelAPI.objectToFeature(aLinesList.object(i))
183             aLineStart = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("EndPoint"))
184             aLineStart.setValue(aX, aY)