-# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+# Copyright (C) 2014-2022 CEA/DEN, EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
"""Returns ID of list containing lines created."""
return "RectangleList"
+ @staticmethod
+ def RECTANGLE_TYPE_ID():
+ """Returns ID of type of rectangle creation (by corners or by center and corner)."""
+ return "RectangleType"
+
+ @staticmethod
+ def RECTANGLE_BY_CORNERS_ID():
+ """Returns ID of creation type by opposite corners."""
+ return "RectangleTypeByCorners"
+
+ @staticmethod
+ def RECTANGLE_CENTERED_ID():
+ """Returns ID of creation type by center point and a corner."""
+ return "RectangleTypeCentered"
+
+ @staticmethod
+ def CENTER_ID():
+ """Returns ID of center point."""
+ return "RectCenterPoint"
+
+ @staticmethod
+ def CENTER_REF_ID():
+ """Returns ID of the reference to the center point."""
+ return "RectCenterPointRef"
+
+ @staticmethod
+ def CORNER_ID():
+ """Returns ID of a corner."""
+ return "RectCornerPoint"
+
+
def getKind(self):
"""Override Feature.getKind()"""
return SketchPlugin_Rectangle.ID()
def initAttributes(self):
"""Override Feature.initAttributes()"""
# Flag whether the rectangle is accessory
- self.data().addAttribute(self.AUXILIARY_ID(), ModelAPI.ModelAPI_AttributeBoolean_typeId())
+ self.data().addAttribute(self.AUXILIARY_ID(), ModelAPI.ModelAPI_AttributeBoolean.typeId())
# Creating corners of the rectangle
- self.data().addAttribute(self.START_ID(), GeomDataAPI.GeomDataAPI_Point2D_typeId())
- self.data().addAttribute(self.END_ID(), GeomDataAPI.GeomDataAPI_Point2D_typeId())
+ self.data().addAttribute(self.START_ID(), GeomDataAPI.GeomDataAPI_Point2D.typeId())
+ self.data().addAttribute(self.END_ID(), GeomDataAPI.GeomDataAPI_Point2D.typeId())
# Creating list to store lines
- self.data().addAttribute(self.LINES_LIST_ID(), ModelAPI.ModelAPI_AttributeRefList_typeId())
+ self.data().addAttribute(self.LINES_LIST_ID(), ModelAPI.ModelAPI_AttributeRefList.typeId())
ModelAPI.ModelAPI_Session.get().validators().registerNotObligatory(self.getKind(), self.LINES_LIST_ID())
+ # Type of rectangle
+ self.data().addAttribute(self.RECTANGLE_TYPE_ID(), ModelAPI.ModelAPI_AttributeString.typeId())
+ # Center and corner of the rectangle
+ self.data().addAttribute(self.CENTER_ID(), GeomDataAPI.GeomDataAPI_Point2D.typeId())
+ self.data().addAttribute(self.CORNER_ID(), GeomDataAPI.GeomDataAPI_Point2D.typeId())
+
+ self.data().addAttribute(self.CENTER_REF_ID(), ModelAPI.ModelAPI_AttributeRefAttr.typeId())
+ ModelAPI.ModelAPI_Session.get().validators().registerNotObligatory(self.getKind(), self.CENTER_REF_ID())
def isMacro(self):
"""
aLinesList.append(aLine)
self.updateLines()
aNbLines = aLinesList.size()
+ aStartPoints = []
# Create constraints to keep the rectangle
for i in range (0, aNbLines):
aLine = ModelAPI.objectToFeature(aLinesList.object(i))
aRefAttrB = aCoincidence.refattr("ConstraintEntityB")
aRefAttrA.setAttr(aPrevLine.attribute("EndPoint"))
aRefAttrB.setAttr(aLine.attribute("StartPoint"))
- # Flags which show horizontal or vertical constraint is build for correponding line
- self.__isHV = [False, False, False, False]
+ aStartPoints.append(aLine.attribute("StartPoint"))
+ # Flags which show perpendicular constraint is build for correponding line
+ self.__isPERP = [False, False, False]
# Update coordinates of created lines
self.updateLines()
- # Add horizontal and vertical constraint for the lines which already have result
- for i in range (0, aNbLines):
- if self.__isHV[i]:
+ # Create auxiliary diagonals in case of centered rectangle
+ if self.string(self.RECTANGLE_TYPE_ID()).value() == self.RECTANGLE_CENTERED_ID():
+ aDiag1 = self.__sketch.addFeature("SketchLine")
+ aLinesList.append(aDiag1)
+ aDiag2 = self.__sketch.addFeature("SketchLine")
+ aLinesList.append(aDiag2)
+ # coincidences in corners
+ aPoints = [aDiag1.attribute("StartPoint"), aDiag2.attribute("StartPoint"),
+ aDiag1.attribute("EndPoint"), aDiag2.attribute("EndPoint")]
+ for i in range (0, len(aPoints)):
+ aCoincidence = self.__sketch.addFeature("SketchConstraintCoincidence")
+ aRefAttrA = aCoincidence.refattr("ConstraintEntityA")
+ aRefAttrB = aCoincidence.refattr("ConstraintEntityB")
+ aRefAttrA.setAttr(aStartPoints[i])
+ aRefAttrB.setAttr(aPoints[i])
+ # Update coordinates of created lines
+ self.updateLines()
+ aDiag1.execute()
+ aDiag2.execute()
+ # coincidences between center point and diagonals
+ refPnt = self.getReferencePoint(self.refattr(self.CENTER_REF_ID()))
+ if refPnt is not None:
+ for line in [aDiag1.lastResult(), aDiag2.lastResult()]:
+ aCoincidence = self.__sketch.addFeature("SketchConstraintCoincidence")
+ aCoincidence.refattr("ConstraintEntityA").setAttr(refPnt)
+ aCoincidence.refattr("ConstraintEntityB").setObject(line)
+ # Perpendicular for the lines which already have result
+ for i in range (0, 3):
+ if self.__isPERP[i]:
continue
- aLine = ModelAPI.objectToFeature(aLinesList.object(i))
- aLineResult = aLine.lastResult()
- if aLineResult is None:
+ aLine_A = ModelAPI.objectToFeature(aLinesList.object(i))
+ aLineResult_A = aLine_A.lastResult()
+ if aLineResult_A is None:
+ continue
+ aLine_B = ModelAPI.objectToFeature(aLinesList.object(i+1))
+ aLineResult_B = aLine_B.lastResult()
+ if aLineResult_B is None:
continue
- aHVName = "SketchConstraintHorizontal"
- if i % 2 == 1:
- aHVName = "SketchConstraintVertical"
- aHVConstraint = self.__sketch.addFeature(aHVName)
- aRefAttrA = aHVConstraint.refattr("ConstraintEntityA")
- aRefAttrA.setObject(aLine.lastResult())
- self.__isHV[i] = True
+ aHVConstraint = self.__sketch.addFeature("SketchConstraintPerpendicular")
+ refattrA = aHVConstraint.refattr("ConstraintEntityA")
+ refattrA.setObject(aLine_A.lastResult())
+ refattrB = aHVConstraint.refattr("ConstraintEntityB")
+ refattrB.setObject(aLine_B.lastResult())
+ self.__isPERP[i] = True
def attributeChanged(self, theID):
- if theID == self.START_ID() or theID == self.END_ID():
+ if theID == self.START_ID() or theID == self.END_ID() or theID == self.CENTER_ID() or theID == self.CENTER_REF_ID() or theID == self.CORNER_ID():
# Search the sketch containing this rectangle
self.__sketch = None
aRefs = self.data().refsToMe();
aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
- if aStartPoint.isInitialized() and aEndPoint.isInitialized():
+ aCenter = self.getPointByRef(self.attribute(self.CENTER_ID()), self.refattr(self.CENTER_REF_ID()))
+ aCorner = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.CORNER_ID()))
+ if (aStartPoint.isInitialized() and aEndPoint.isInitialized()) or (aCenter is not None and aCorner.isInitialized()):
self.updateLines()
else:
self.updateStartPoint()
aLine = ModelAPI.objectToFeature(aLinesList.object(i))
aLine.data().boolean("Auxiliary").setValue(anAuxiliary)
+ def getReferencePoint(self, theRef):
+ if theRef.isObject() and theRef.object() is not None:
+ feature = ModelAPI.ModelAPI_Feature.feature(theRef.object())
+ if feature.getKind() == "SketchPoint":
+ return feature.attribute("PointCoordinates")
+ else:
+ return theRef.attr()
+ return None
+
+ def getPointByRef(self, thePoint, theRef):
+ attr = thePoint
+ if theRef.isInitialized():
+ refPnt = self.getReferencePoint(theRef)
+ if refPnt is not None:
+ attr = refPnt
+ if attr is None or not attr.isInitialized():
+ return None
+ return GeomDataAPI.geomDataAPI_Point2D(attr).pnt()
def updateLines(self):
# Retrieving list of already created lines
aLinesList = self.reflist(self.LINES_LIST_ID())
- aNbLines = aLinesList.size()
- aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
- aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
- aX = [aStartPoint.x(), aStartPoint.x(), aEndPoint.x(), aEndPoint.x()]
- aY = [aStartPoint.y(), aEndPoint.y(), aEndPoint.y(), aStartPoint.y()]
+ aNbLines = min(aLinesList.size(), 4)
+ if self.string(self.RECTANGLE_TYPE_ID()).value() == self.RECTANGLE_CENTERED_ID():
+ aCenter = self.getPointByRef(self.attribute(self.CENTER_ID()), self.refattr(self.CENTER_REF_ID()))
+ aCorner = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.CORNER_ID()))
+ aStartX = 2.0 * aCenter.x() - aCorner.x()
+ aStartY = 2.0 * aCenter.y() - aCorner.y()
+ aX = [aStartX, aStartX, aCorner.x(), aCorner.x()]
+ aY = [aStartY, aCorner.y(), aCorner.y(), aStartY]
+ else:
+ aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
+ aEndPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.END_ID()))
+ aX = [aStartPoint.x(), aStartPoint.x(), aEndPoint.x(), aEndPoint.x()]
+ aY = [aStartPoint.y(), aEndPoint.y(), aEndPoint.y(), aStartPoint.y()]
anAuxiliary = self.data().boolean(self.AUXILIARY_ID()).value()
+ # do not recalculate the rectrangle after each update
+ wasBlocked = []
+ for i in range (0, aLinesList.size()):
+ wasBlocked.append(aLinesList.object(i).data().blockSendAttributeUpdated(True))
+
# Update coordinates of rectangle lines
for i in range (0, aNbLines):
aLine = ModelAPI.objectToFeature(aLinesList.object(i))
aLineEnd.setValue(aX[i], aY[i])
aLine.data().boolean("Auxiliary").setValue(anAuxiliary)
+ # Update auxiliary diagonals
+ if self.string(self.RECTANGLE_TYPE_ID()).value() == self.RECTANGLE_CENTERED_ID():
+ for i in range (aNbLines, aLinesList.size()):
+ aLine = ModelAPI.objectToFeature(aLinesList.object(i))
+ aLineStart = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+ aLineEnd = GeomDataAPI.geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+ aLineStart.setValue(aX[i-aNbLines-1], aY[i-aNbLines-1])
+ aLineEnd.setValue(aX[i-aNbLines+1], aY[i-aNbLines+1])
+ aLine.data().boolean("Auxiliary").setValue(True)
+
+ # update the rectangle
+ for i in range (0, aLinesList.size()):
+ aLinesList.object(i).data().blockSendAttributeUpdated(wasBlocked[i], True)
+
def updateStartPoint(self):
# Retrieving list of already created lines
aLinesList = self.reflist(self.LINES_LIST_ID())
aNbLines = aLinesList.size()
aStartPoint = GeomDataAPI.geomDataAPI_Point2D(self.attribute(self.START_ID()))
- aX = aStartPoint.x()
- aY = aStartPoint.y()
+ if aStartPoint.isInitialized:
+ aX = aStartPoint.x()
+ aY = aStartPoint.y()
+ else:
+ aCenter = self.getPointByRef(self.attribute(self.CENTER_ID()), self.refattr(self.CENTER_REF_ID()))
+ aX = aCenter.x()
+ aY = aCenter.y()
# Update coordinates of rectangle lines
for i in range (0, aNbLines):