}
} else if (aType == ModelAPI_AttributeInteger::typeId()) {
AttributeIntegerPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttr);
+ // do not dump a type of ConstraintAngle, because it can be changed due dumping
+ if (anAttr->id() == "AngleType") {
+ return "";
+ }
if (anAttr->text().empty())
aResult<<anAttr->value();
else
aResult<<anAttr->text();
} else if (aType == ModelAPI_AttributeDouble::typeId()) {
AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
+ if (anAttr->id() == "ConstraintValue") {
+ // do not dump a value of constraint if it is ConstraintAngle,
+ // because this value depends on the angle type
+ FeaturePtr anOwner = ModelAPI_Feature::feature(anAttr->owner());
+ if (anOwner && anOwner->getKind() == "SketchConstraintAngle")
+ return "";
+ }
int aPrecision = PRECISION;
// Special case - precision for the arc angle. It is calculated with tolerance 1e-4,
// so the value has only 4 correct digits
aResult<<anAttr->text();
} else if (aType == ModelAPI_AttributeBoolean::typeId()) {
AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
+ // do not dump internal flags of ConstraintAngle
+ if (anAttr->id() == "AngleReversedLine1" || anAttr->id() == "AngleReversedLine2") {
+ return "";
+ }
aResult<<anAttr->value();
} else if (aType == ModelAPI_AttributeString::typeId()) {
AttributeStringPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeString>(theAttr);
SketchAPI_Arc.h
SketchAPI_Circle.h
SketchAPI_Constraint.h
+ SketchAPI_ConstraintAngle.h
SketchAPI_IntersectionPoint.h
SketchAPI_Line.h
SketchAPI_MacroArc.h
SketchAPI_Arc.cpp
SketchAPI_Circle.cpp
SketchAPI_Constraint.cpp
+ SketchAPI_ConstraintAngle.cpp
SketchAPI_IntersectionPoint.cpp
SketchAPI_Line.cpp
SketchAPI_MacroArc.cpp
%shared_ptr(SketchAPI_Circle)
%shared_ptr(SketchAPI_MacroCircle)
%shared_ptr(SketchAPI_Constraint)
+%shared_ptr(SketchAPI_ConstraintAngle)
%shared_ptr(SketchAPI_IntersectionPoint)
%shared_ptr(SketchAPI_Line)
%shared_ptr(SketchAPI_Mirror)
%include "SketchAPI_Rotation.h"
%include "SketchAPI_Sketch.h"
%include "SketchAPI_Constraint.h"
+%include "SketchAPI_ConstraintAngle.h"
#include <ModelHighAPI_Tools.h>
#include <SketchPlugin_Constraint.h>
-#include <SketchPlugin_ConstraintAngle.h>
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_ConstraintCollinear.h>
#include <SketchPlugin_ConstraintDistance.h>
static const std::string COINCIDENCE_SETTER("setCoincident");
return COINCIDENCE_SETTER;
}
- if (theType == SketchPlugin_ConstraintAngle::ID()) {
- static const std::string ANGLE_SETTER("setAngle");
- return ANGLE_SETTER;
- }
if (theType == SketchPlugin_ConstraintCollinear::ID()) {
static const std::string COLLINEAR_SETTER("setCollinear");
return COLLINEAR_SETTER;
return std::string();
}
+bool SketchAPI_Constraint::areAllAttributesDumped(ModelHighAPI_Dumper& theDumper) const
+{
+ bool areAttributesDumped = true;
+ FeaturePtr aBase = feature();
+ for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
+ AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+ if (aRefAttr && aRefAttr->isInitialized())
+ areAttributesDumped = theDumper.isDumped(aRefAttr);
+ }
+ if (!areAttributesDumped)
+ theDumper.postpone(aBase);
+ return areAttributesDumped;
+}
+
void SketchAPI_Constraint::dump(ModelHighAPI_Dumper& theDumper) const
{
FeaturePtr aBase = feature();
return;
}
- // Check all attributes are already dumped. If not, store the constraint as postponed.
- bool areAttributesDumped = true;
- for (int i = 0; i < CONSTRAINT_ATTR_SIZE && areAttributesDumped; ++i) {
- AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
- if (aRefAttr && aRefAttr->isInitialized())
- areAttributesDumped = theDumper.isDumped(aRefAttr);
- }
- if (!areAttributesDumped) {
- theDumper.postpone(aBase);
+ // postpone constraint until all its attributes be dumped
+ if (!areAllAttributesDumped(theDumper))
return;
- }
-
- bool isAngle = aBase->getKind() == SketchPlugin_ConstraintAngle::ID();
- std::string aSetterSuffix;
- if (isAngle)
- aSetterSuffix = angleTypeToString(aBase->integer(
- SketchPlugin_ConstraintAngle::TYPE_ID())->value());
const std::string& aSketchName = theDumper.parentName(aBase);
- theDumper << aBase << " = " << aSketchName << "." << aSetter << aSetterSuffix << "(";
+ theDumper << aBase << " = " << aSketchName << "." << aSetter << "(";
bool isFirstAttr = true;
for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
}
AttributeDoublePtr aValueAttr;
- if (isAngle)
- aValueAttr = aBase->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
- else if (aBase->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
- aBase->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
+ if (aBase->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
+ aBase->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
aValueAttr = aBase->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID());
else
aValueAttr = aBase->real(SketchPlugin_Constraint::VALUE());
/// Dump wrapped feature
SKETCHAPI_EXPORT
virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
+protected:
+ // Check all attributes of constraint are already dumped.
+ // If not, store the constraint as postponed.
+ bool areAllAttributesDumped(ModelHighAPI_Dumper& theDumper) const;
};
#endif
--- /dev/null
+// Copyright (C) 2019-20xx 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "SketchAPI_ConstraintAngle.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+#include <GeomAPI_Angle2d.h>
+#include <GeomAPI_Lin2d.h>
+
+#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_Line.h>
+
+#include <cmath>
+
+SketchAPI_ConstraintAngle::SketchAPI_ConstraintAngle(
+ const std::shared_ptr<ModelAPI_Feature> & theFeature)
+: SketchAPI_Constraint(theFeature)
+{
+ ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
+ if (aConstraint)
+ initialize();
+}
+
+static FeaturePtr getFeatureLine(DataPtr theData, const std::string& theAttribute)
+{
+ FeaturePtr aLine;
+ if (!theData.get() || !theData->isValid()) /// essential check as it is called in openGl thread)
+ return aLine;
+
+ std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theData->attribute(theAttribute));
+ if (anAttr) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anAttr->object());
+ if (aFeature && aFeature->getKind() == SketchPlugin_Line::ID()) {
+ return aFeature;
+ }
+ }
+ return aLine;
+}
+
+static void calculatePossibleValuesOfAngle(FeaturePtr theFeature,
+ double& theAngleDirect, double& theAngleComplementary, double& theAngleBackward)
+{
+ std::shared_ptr<ModelAPI_Data> aData = theFeature->data();
+ FeaturePtr aLineA = getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+ FeaturePtr aLineB = getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+
+ std::shared_ptr<GeomDataAPI_Point2D> aStartA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineA->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aEndA = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineA->attribute(SketchPlugin_Line::END_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aStartB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineB->attribute(SketchPlugin_Line::START_ID()));
+ std::shared_ptr<GeomDataAPI_Point2D> aEndB = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aLineB->attribute(SketchPlugin_Line::END_ID()));
+
+ std::shared_ptr<GeomAPI_Angle2d> anAng(new GeomAPI_Angle2d(
+ aStartA->pnt(), aEndA->pnt(), aStartB->pnt(), aEndB->pnt()));
+ theAngleDirect = anAng->angleDegree();
+ theAngleBackward = 360.0 - theAngleDirect;
+
+ if (theAngleDirect > 180.0)
+ theAngleComplementary = theAngleDirect - 180.0;
+ else
+ theAngleComplementary = 180.0 - theAngleDirect;
+}
+
+static std::string angleTypeToString(FeaturePtr theFeature)
+{
+ static const double TOLERANCE = 1.e-7;
+ double anAngleDirect, anAngleComplmentary, anAngleBackward;
+ calculatePossibleValuesOfAngle(theFeature, anAngleDirect, anAngleComplmentary, anAngleBackward);
+
+ AttributeDoublePtr aValueAttr = theFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+
+ std::string aType;
+ if (fabs(aValueAttr->value() - anAngleDirect) < TOLERANCE) {
+ // Nothing to do.
+ // This case is empty and going the first to check the direct angle before the others.
+ }
+ else if (fabs(aValueAttr->value() - anAngleComplmentary) < TOLERANCE)
+ aType = "Complementary";
+ else if (fabs(aValueAttr->value() - anAngleBackward) < TOLERANCE)
+ aType = "Backward";
+ return aType;
+}
+
+void SketchAPI_ConstraintAngle::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ // postpone constraint until all its attributes be dumped
+ if (!areAllAttributesDumped(theDumper))
+ return;
+
+ // calculate angle value as it was just applied to the attributes
+ FeaturePtr aBase = feature();
+ std::string aSetterSuffix = angleTypeToString(aBase);
+
+ const std::string& aSketchName = theDumper.parentName(aBase);
+ theDumper << aBase << " = " << aSketchName << "." << "setAngle" << aSetterSuffix << "(";
+
+ bool isFirstAttr = true;
+ for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+ AttributeRefAttrPtr aRefAttr = aBase->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
+ if (aRefAttr && aRefAttr->isInitialized()) {
+ theDumper << (isFirstAttr ? "" : ", ") << aRefAttr;
+ isFirstAttr = false;
+ }
+ }
+
+ AttributeDoublePtr aValueAttr = aBase->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
+ if (aValueAttr && aValueAttr->isInitialized())
+ theDumper << ", " << aValueAttr;
+
+ theDumper << ")" << std::endl;
+}
--- /dev/null
+// Copyright (C) 2019-20xx 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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef SRC_SKETCHAPI_SKETCHAPI_CONSTRAINTANGLE_H_
+#define SRC_SKETCHAPI_SKETCHAPI_CONSTRAINTANGLE_H_
+
+#include "SketchAPI_Constraint.h"
+
+class ModelHighAPI_Double;
+
+/**\class SketchAPI_ConstraintAngle
+ * \ingroup CPPHighAPI
+ * \brief Interface for ConstraintAngle feature
+ */
+class SketchAPI_ConstraintAngle : public SketchAPI_Constraint
+{
+public:
+ /// Constructor without values
+ SKETCHAPI_EXPORT
+ explicit SketchAPI_ConstraintAngle(const std::shared_ptr<ModelAPI_Feature> & theFeature);
+
+ static std::string ID()
+ {
+ static const std::string MY_SKETCH_CONSTRAINT_ID = "SketchConstraintAngle";
+ return MY_SKETCH_CONSTRAINT_ID;
+ }
+ virtual std::string getID() { return ID(); }
+
+ /// Dump wrapped feature
+ SKETCHAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+#endif
#include "SketchAPI_Circle.h"
#include "SketchAPI_MacroCircle.h"
#include "SketchAPI_Constraint.h"
+ #include "SketchAPI_ConstraintAngle.h"
#include "SketchAPI_IntersectionPoint.h"
#include "SketchAPI_Line.h"
#include "SketchAPI_Mirror.h"
Test2741.py
Test2810.py
Test2824.py
+ Test2860.py
TestArcBehavior.py
TestConstraintAngle.py
TestConstraintCoincidence.py
--- /dev/null
+## Copyright (C) 2018-20xx 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
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ Test2860.py
+ Test case for issue #2650 "setAngleComplementary becomes setAngle in BARCOM"
+ Test case for issue #2860 "Error in python dump reload because of setAngleComplementary"
+"""
+
+from salome.shaper import model
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-9.326798599059195, -0.7578903795715272, 33.09960827213365, 41.66851649162133)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 60)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "OY"), False)
+SketchLine_2 = SketchProjection_1.createdFeature()
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_2.result(), 45)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchLine_1.endPoint(), 5)
+model.do()
+model.end()
+
+assert(model.checkPythonDump())