return mySelf;
}
+#define CLEAR_STREAM(theStream) { \
+ std::ostringstream anOther; \
+ swap(theStream, anOther); \
+ }
+
void ModelHighAPI_Dumper::clear(bool bufferOnly)
{
- myDumpBuffer = std::ostringstream();
+ CLEAR_STREAM(myDumpBuffer);
myDumpBuffer << std::setprecision(16);
clearNotDumped();
if (!bufferOnly) {
- myFullDump = std::ostringstream();
+ CLEAR_STREAM(myFullDump);
myFullDump << std::setprecision(16);
myNames.clear();
myNotDumpedEntities.clear();
}
-const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity)
+const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, bool theSaveNotDumped)
{
EntityNameMap::const_iterator aFound = myNames.find(theEntity);
if (aFound != myNames.end())
}
myNames[theEntity] = std::pair<std::string, bool>(aName, isUserDefined);
- myNotDumpedEntities.insert(theEntity);
+ if (theSaveNotDumped)
+ myNotDumpedEntities.insert(theEntity);
return myNames[theEntity].first;
}
bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc)
{
bool isOk = true;
- // dump all features
std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
- for (; aFeatIt != aFeatures.end(); ++aFeatIt) {
+ // firstly, dump all parameters
+ for (; aFeatIt != aFeatures.end(); ++ aFeatIt)
+ dumpParameter(*aFeatIt);
+ // dump all other features
+ for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) {
CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
if (aCompFeat) // iteratively process composite features
isOk = process(aCompFeat) && isOk;
bool isOk = true;
// dump all sub-features;
int aNbSubs = theComposite->numberOfSubs();
+//////////////////////////////////////
+ std::list<ObjectPtr> aList = theComposite->reflist("Features")->list();
+//////////////////////////////////////
for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
FeaturePtr aFeature = theComposite->subFeature(anIndex);
if (isDumped(aFeature))
myDumpBuffer << "]";
} else {
// clear buffer and store list "as is"
- myDumpBuffer = std::ostringstream();
+ CLEAR_STREAM(myDumpBuffer);
*this << theRefList;
// save buffer and clear it again
std::string aDumpedList = myDumpBuffer.str();
- myDumpBuffer = std::ostringstream();
+ CLEAR_STREAM(myDumpBuffer);
// obtain name of list
FeaturePtr anOwner = ModelAPI_Feature::feature(theRefList->owner());
std::string aListName = name(anOwner) + "_objects";
#include "ModelHighAPI.h"
+#include <list>
#include <map>
#include <memory>
#include <set>
const std::string& theObject = std::string());
/// Returns name of specified entity
+ /// \param theEntity [in] named entity
+ /// \param theSaveNotDumped [in] if \c true, the entity should be stored as not dumped (will be dumped automatically)
+ /// \return name of the entity
MODELHIGHAPI_EXPORT
- const std::string& name(const EntityPtr& theEntity);
+ const std::string& name(const EntityPtr& theEntity, bool theSaveNotDumped = true);
/// Returns name of parent composite feature for specified entity
MODELHIGHAPI_EXPORT
const std::string& parentName(const FeaturePtr& theFeature);
+ /// Dump parameter feature only
+ virtual void dumpParameter(const FeaturePtr& theFeature) = 0;
/// Dump given feature
virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
#include <TopExp_Explorer.hxx>
#include <ios>
+#include <cmath>
+
+#define PRECISION 7
+#define TOLERANCE (1.e-7)
ModelHighAPI_FeatureStore::ModelHighAPI_FeatureStore(FeaturePtr theFeature) {
storeData(theFeature->data(), myAttrs);
return "";
}
+static void dumpArray(std::ostringstream& theOutput, const double theArray[], int theSize)
+{
+ for (int i = 0; i < theSize; ++i) {
+ if (i > 0)
+ theOutput << " ";
+ theOutput << std::fixed << setprecision(PRECISION)
+ << (fabs(theArray[i]) < TOLERANCE ? 0.0 : theArray[i]);
+ }
+}
+
std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) {
static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
FeaturePtr aFeatOwner = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttr->owner());
aResult<<anAttr->text();
} else if (aType == ModelAPI_AttributeDouble::typeId()) {
AttributeDoublePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttr);
- if (anAttr->text().empty())
- aResult<<std::fixed<<setprecision(7)<<anAttr->value();
- else
+ if (anAttr->text().empty()) {
+ double aVal = anAttr->value();
+ dumpArray(aResult, &aVal, 1);
+ } else
aResult<<anAttr->text();
} else if (aType == ModelAPI_AttributeBoolean::typeId()) {
AttributeBooleanPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(theAttr);
aResult<<anAttr->value(a)<<" ";
} else if (aType == GeomDataAPI_Point::typeId()) {
AttributePointPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttr);
- aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
+ double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+ dumpArray(aResult, aValues, 3);
} else if (aType == GeomDataAPI_Dir::typeId()) {
AttributeDirPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
- aResult<<anAttr->x()<<" "<<anAttr->y()<<" "<<anAttr->z();
+ double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()};
+ dumpArray(aResult, aValues, 3);
} else if (aType == GeomDataAPI_Point2D::typeId()) {
AttributePoint2DPtr anAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
- aResult<<anAttr->x()<<" "<<anAttr->y()<<" ";
+ double aValues[2] = {anAttr->x(), anAttr->y()};
+ dumpArray(aResult, aValues, 2);
} else {
aResult<<"__unknownattribute__";
}
// output the main characteristics
aResult<<"Volume: "<<setprecision(2)<<GeomAlgoAPI_ShapeTools::volume(theShape)<<std::endl;
std::shared_ptr<GeomAPI_Pnt> aCenter = GeomAlgoAPI_ShapeTools::centreOfMass(theShape);
- aResult<<"Center of mass: "<<std::fixed<<setprecision(7)
+ aResult<<"Center of mass: "<<std::fixed<<setprecision(PRECISION)
<<aCenter->x()<<" "<<aCenter->y()<<" "<<aCenter->z()<<std::endl;
return aResult.str();
}
if (initialize()) {
fillAttribute(theName, name());
fillAttribute(theExpression, expression());
- fillAttribute(theComment, comment());
+ if (!theComment.empty())
+ fillAttribute(theComment, comment());
execute();
}
{
FeaturePtr aBase = feature();
const std::string& aDocName = theDumper.name(aBase->document());
- const std::string& aParamName = theDumper.name(aBase);
+ const std::string& aParamName = theDumper.name(aBase, false);
AttributeStringPtr anExpr = aBase->string(ParametersPlugin_Parameter::EXPRESSION_ID());
AttributeStringPtr aComment = aBase->string(ParametersPlugin_Parameter::COMMENT_ID());
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
aRadiusAttr = aSketchCircle.real("CircleRadius")
- anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
- aRadiusAttr.setText("x1")
+ anCircleCentr.setValue(10., 20.)
+ aRadiusAttr.setValue(10.)
self.aSession.finishOperation()
self.anCircleCentr = anCircleCentr
self.aRadiusAttr = aRadiusAttr
+ # constraints to fix circle position and radius
+ self.aSession.startOperation()
+ # fix X coordinate
+ aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+ refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+ refattrA.setAttr(anCircleCentr)
+ refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+ anOY = aSketchFeature.addFeature("SketchLine")
+ aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+ anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+ aStartPoint.setValue(0., 0.)
+ anEndPoint.SetValue(0., 100.)
+ anOY.selection("External").selectSubShape("EDGE", "OY")
+ refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+ value = aDistanceConstraint1.real("ConstraintValue")
+ value.setText("x1 + 10.0")
+ aDistanceConstraint1.execute();
+ # fix Y coordinate
+ aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+ refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+ refattrA.setAttr(anCircleCentr)
+ refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+ anOX = aSketchFeature.addFeature("SketchLine")
+ aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+ anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+ aStartPoint.setValue(0., 0.)
+ anEndPoint.SetValue(100., 0.)
+ anOX.selection("External").selectSubShape("EDGE", "OX")
+ refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+ value = aDistanceConstraint2.real("ConstraintValue")
+ value.setText("x1 + 20.0")
+ aDistanceConstraint2.execute();
+ # fix radius
+ aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+ refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+ refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+ aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+ aRadiusConstrAttr.setText("x1")
+ aRadiusConstraint.execute()
+ self.aSession.finishOperation()
+
self.assertEqual(self.anCircleCentr.x(), 160.)
self.assertEqual(self.anCircleCentr.y(), 170.)
self.assertEqual(aRadiusAttr.value(), 150.)
#=========================================================================
# Use parameters to set radius of a circle :
# 1. Create a circle (250., 250), r = 25.
-# 2. Set a 'cr1' as text value of radius attribute
+# 2. Create a radius constraint and set 'cr1' as text value of constraint
#=========================================================================
aSession.startOperation()
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
aSession.finishOperation()
# Apply parameter
aSession.startOperation()
-aRadiusAttr.setText("cr1")
+aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+aRadiusConstrAttr.setText("cr1")
+aRadiusConstraint.execute()
aSession.finishOperation()
assert(aRadiusAttr.value() == 100.)
#=========================================================================
aSketchCircle = aSketchFeature.addFeature("SketchCircle")
anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
aRadiusAttr = aSketchCircle.real("CircleRadius")
- anCircleCentr.setText("x1 + 10.0", "x1 + 20.0")
- aRadiusAttr.setText("x1")
+ anCircleCentr.setValue(10., 20.)
+ aRadiusAttr.setValue(10.)
self.aSession.finishOperation()
self.anCircleCentr = anCircleCentr
self.aRadiusAttr = aRadiusAttr
+ # constraints to fix circle position and radius
+ self.aSession.startOperation()
+ # fix X coordinate
+ aDistanceConstraint1 = aSketchFeature.addFeature("SketchConstraintDistance")
+ refattrA = aDistanceConstraint1.refattr("ConstraintEntityA")
+ refattrA.setAttr(anCircleCentr)
+ refattrB = aDistanceConstraint1.refattr("ConstraintEntityB")
+ anOY = aSketchFeature.addFeature("SketchLine")
+ aStartPoint = geomDataAPI_Point2D(anOY.attribute("StartPoint"))
+ anEndPoint = geomDataAPI_Point2D(anOY.attribute("EndPoint"))
+ aStartPoint.setValue(0., 0.)
+ anEndPoint.SetValue(0., 100.)
+ anOY.selection("External").selectSubShape("EDGE", "OY")
+ refattrB.setObject(modelAPI_ResultConstruction(anOY.firstResult()))
+ valueX = aDistanceConstraint1.real("ConstraintValue")
+ valueX.setText("x1 + 10.0")
+ aDistanceConstraint1.execute();
+ # fix Y coordinate
+ aDistanceConstraint2 = aSketchFeature.addFeature("SketchConstraintDistance")
+ refattrA = aDistanceConstraint2.refattr("ConstraintEntityA")
+ refattrA.setAttr(anCircleCentr)
+ refattrB = aDistanceConstraint2.refattr("ConstraintEntityB")
+ anOX = aSketchFeature.addFeature("SketchLine")
+ aStartPoint = geomDataAPI_Point2D(anOX.attribute("StartPoint"))
+ anEndPoint = geomDataAPI_Point2D(anOX.attribute("EndPoint"))
+ aStartPoint.setValue(0., 0.)
+ anEndPoint.SetValue(100., 0.)
+ anOX.selection("External").selectSubShape("EDGE", "OX")
+ refattrB.setObject(modelAPI_ResultConstruction(anOX.firstResult()))
+ valueY = aDistanceConstraint2.real("ConstraintValue")
+ valueY.setText("x1 + 20.0")
+ aDistanceConstraint2.execute();
+ # fix radius
+ aRadiusConstraint = aSketchFeature.addFeature("SketchConstraintRadius")
+ refattrA = aRadiusConstraint.refattr("ConstraintEntityA")
+ refattrA.setObject(modelAPI_ResultConstruction(aSketchCircle.lastResult()))
+ aRadiusConstrAttr = aRadiusConstraint.real("ConstraintValue")
+ aRadiusConstrAttr.setText("x1")
+ aRadiusConstraint.execute()
+ self.aSession.finishOperation()
+
+ self.aCircleCenterX = valueX
+ self.aCircleCenterY = valueY
+ sel.aCircleRadius = aRadiusConstraintAttr
+
self.assertEqual(self.anCircleCentr.x(), 160.)
self.assertEqual(self.anCircleCentr.y(), 170.)
self.assertEqual(aRadiusAttr.value(), 150.)
aParam = self.dtParams["x2"]
self.assertEqual(aParam.string("expression").value(), "a1 + y1 + 100.0")
# Check rename in the feature
- self.assertEqual(self.anCircleCentr.textX(), "a1 + 10.0")
- self.assertEqual(self.anCircleCentr.textY(), "a1 + 20.0")
- self.assertEqual(self.aRadiusAttr.text(), "a1")
+ self.assertEqual(self.aCircleCenterX.text(), "a1 + 10.0")
+ self.assertEqual(self.aCircleCenterY.text(), "a1 + 20.0")
+ self.assertEqual(self.aCircleRadius.text(), "a1")
+ # Check values
+ self.assertEqual(self.anCircleCentr.x(), 160.)
+ self.assertEqual(self.anCircleCentr.y(), 170.)
+ self.assertEqual(self.aRadiusAttr.value(), 150.)
def test_rename_not_unique(self):
# Rename to not unique name
aParam = self.dtParams["x2"]
self.assertEqual(aParam.string("expression").value(), "x1 + y1 + 100.0")
# Check rename in the feature (Expected: not renamed)
- self.assertEqual(self.anCircleCentr.textX(), "x1 + 10.0")
- self.assertEqual(self.anCircleCentr.textY(), "x1 + 20.0")
- self.assertEqual(self.aRadiusAttr.text(), "x1")
+ self.assertEqual(self.aCircleCenterX.text(), "x1 + 10.0")
+ self.assertEqual(self.aCircleCenterY.text(), "x1 + 20.0")
+ self.assertEqual(self.aCircleRadius.text(), "x1")
+ # Check values
+ self.assertEqual(self.anCircleCentr.x(), 160.)
+ self.assertEqual(self.anCircleCentr.y(), 170.)
+ self.assertEqual(self.aRadiusAttr.value(), 150.)
if __name__ == '__main__':
unittest.main()
if aFeatureKind in self.myFeatures:
# Dump only feature created by user (in history).
# For all other features, just keep their name.
- if theForce or aFeatureKind == "Parameter" or theFeature.isInHistory():
+ if theForce or theFeature.isInHistory():
self.myFeatures[aFeatureKind](theFeature).dump(self)
else:
self.name(theFeature)
# In case of theFeature is not a constraint, it will not be dumped.
self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self)
+ ## Dump all parameters
+ def dumpParameter(self, theFeature):
+ aFeatureKind = theFeature.getKind()
+ if aFeatureKind == "Parameter" and aFeatureKind in self.myFeatures:
+ self.myFeatures[aFeatureKind](theFeature).dump(self)
+
## Return getter for specified attribute
def attributeGetter(self, theFeature, theAttrName):
aFeatureKind = theFeature.getKind()