}
}
+void ConstructionPlugin_Axis::createAxisByCylindricalFace()
+{
+ std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(CYLINDRICAL_FACE())->value();
+ // update arguments due to the selection value
+ if (aSelection && !aSelection->isNull() && aSelection->isFace()) {
+ std::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::cylinderAxis(aSelection);
+
+ ResultConstructionPtr aConstr = document()->createConstruction(data());
+ aConstr->setShape(anEdge);
+ setResult(aConstr);
+ }
+}
+
void ConstructionPlugin_Axis::execute()
{
AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD());
if (aMethodType == "AxisByPointsCase") {
createAxisByTwoPoints();
} else if (aMethodType == "AxisByCylindricalFaceCase") {
- #ifdef _DEBUG
- std::cout << "ConstructionPlugin_Axis::execute: " << "AxisByCylindricalFaceCase is not supported yet." << std::endl;
- #endif
+ createAxisByCylindricalFace();
}
}
bool ConstructionPlugin_Axis::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs,
- std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
+ std::shared_ptr<GeomAPI_ICustomPrs> theDefaultPrs)
{
bool isCustomized = theDefaultPrs.get() != NULL &&
theDefaultPrs->customisePresentation(theResult, thePrs, theDefaultPrs);
protected:
void createAxisByTwoPoints();
+ void createAxisByCylindricalFace();
};
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
#include <TopoDS.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Plane.hxx>
+#include <Geom_CylindricalSurface.hxx>
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
return aRes;
}
+std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::cylinderAxis(
+ std::shared_ptr<GeomAPI_Shape> theCylindricalFace)
+{
+ std::shared_ptr<GeomAPI_Edge> aResult;
+ const TopoDS_Shape& aShape = theCylindricalFace->impl<TopoDS_Shape>();
+ if (aShape.IsNull())
+ return aResult;
+ TopoDS_Face aFace = TopoDS::Face(aShape);
+ if (aFace.IsNull())
+ return aResult;
+ TopLoc_Location aLoc;
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
+ if (aSurf.IsNull())
+ return aResult;
+ Handle(Geom_CylindricalSurface) aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf);
+ if (aCyl.IsNull())
+ return aResult;
+ gp_Ax1 anAxis = aCyl->Axis();
+ gp_Pnt aStart(anAxis.Location().Transformed(aLoc.Transformation()));
+ // edge length is 100, "-" because cylinder of extrusion has negative direction with the cylinder
+ gp_Pnt anEnd(anAxis.Location().XYZ() - anAxis.Direction().XYZ() * 100.);
+ anEnd.Transform(aLoc.Transformation());
+
+ BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
+ std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
+ TopoDS_Edge anEdge = anEdgeBuilder.Edge();
+ aRes->setImpl(new TopoDS_Shape(anEdge));
+ return aRes;
+}
+
std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircle(
std::shared_ptr<GeomAPI_Pnt> theCenter, std::shared_ptr<GeomAPI_Dir> theNormal,
double theRadius)
public:
/// Creates linear edge by two points
static std::shared_ptr<GeomAPI_Edge> line(std::shared_ptr<GeomAPI_Pnt> theStart,
- std::shared_ptr<GeomAPI_Pnt> theEnd);
+ std::shared_ptr<GeomAPI_Pnt> theEnd);
+ /// Creates edge - axis of the given cylindrical face
+ static std::shared_ptr<GeomAPI_Edge> cylinderAxis(
+ std::shared_ptr<GeomAPI_Shape> theCylindricalFace);
/// Creates linear edge in a form of a circle by a point and a circle radius
static std::shared_ptr<GeomAPI_Edge> lineCircle(std::shared_ptr<GeomAPI_Pnt> theCenter,
break;
} else if (aGroup->Get() == ModelAPI_ResultGroup::group().c_str()) {
aNewBody = createGroup(theFeature->data(), aResIndex);
+ } else if (aGroup->Get() == ModelAPI_ResultParameter::group().c_str()) {
+ theFeature->attributeChanged("expression"); // just produce a value
+ break;
} else {
Events_Error::send(std::string("Unknown type of result is found in the document:") +
TCollection_AsciiString(aGroup->Get()).ToCString());
void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
{
ModuleBase_DoubleSpinBox::showEvent(theEvent);
- //setText(myTextValue);
+ if (hasVariable(myTextValue)) {
+ setText(myTextValue);
+ }
}
void ModuleBase_WidgetDoubleValue::reset()
{
- if (isComputedDefault()) {
+ if (isComputedDefault() || mySpinBox->hasVariable()) {
return;
//if (myFeature->compute(myAttributeID))
// restoreValue();
- }
- else {
+ } else {
bool isOk;
double aDefValue = QString::fromStdString(getDefaultValue()).toDouble(&isOk);
// reset the value just if there is a default value definition in the XML definition
std::string aTextRepr = aReal->text();
if (mySpinBox->hasVariable()) {
aTextRepr = mySpinBox->text().toStdString();
+ } else {
+ aTextRepr = "";
}
aReal->setText(aTextRepr);
updateObject(myFeature);
ParametersPlugin_Parameter::ParametersPlugin_Parameter()
{
myInterp = new ParametersPlugin_PyInterp();
+ myInterp->initialize();
}
ParametersPlugin_Parameter::~ParametersPlugin_Parameter()
double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, std::string& theError)
{
- myInterp->initialize();
+
std::list<std::string> anExprParams = myInterp->compile(theExpression);
// find expression's params in the model
std::list<std::string> aContext;
}
myInterp->extendLocalContext(aContext);
double result = myInterp->evaluate(theExpression, theError);
- myInterp->destroy();
+ myInterp->clearLocalContext();
return result;
}
}
}
+void ParametersPlugin_PyInterp::clearLocalContext()
+{
+ PyLockWrapper lck;
+ PyDict_Clear(_local_context);
+}
+
double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression, std::string& theError)
{
std::list<std::string> compile(const std::string&);
void extendLocalContext(const std::list<std::string>&);
+ void clearLocalContext();
double evaluate(const std::string&, std::string&);
protected:
try {
if (myStorage->hasDuplicatedConstraint())
aResult = SLVS_RESULT_INCONSISTENT;
- else
- aResult = myConstrSolver.solve();
+ else {
+ // To avoid overconstraint situation, we will remove temporary constraints one-by-one
+ // and try to find the case without overconstraint
+ int aNbTemp = (int)myTempConstraints.size();
+ while (true) {
+ aResult = myConstrSolver.solve();
+ if (aResult == SLVS_RESULT_OKAY || aNbTemp <= 0)
+ break;
+ aNbTemp = myStorage->removeFirstTemporaryConstraint();
+ myStorage->initializeSolver(myConstrSolver);
+ }
+ }
} catch (...) {
Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this);
return false;
myEquationsSystem.constraints = theSize;
}
else if (myEquationsSystem.constraints != theSize) {
- delete[] myEquationsSystem.constraint;
- myEquationsSystem.constraint = new Slvs_Constraint[theSize];
+ if (theSize > myEquationsSystem.constraints) {
+ delete[] myEquationsSystem.constraint;
+ myEquationsSystem.constraint = new Slvs_Constraint[theSize];
+ }
myEquationsSystem.constraints = theSize;
}
memcpy(myEquationsSystem.constraint, theConstraints, theSize * sizeof(Slvs_Constraint));
myTemporaryConstraints.clear();
}
+int SketchSolver_Storage::removeFirstTemporaryConstraint()
+{
+ if (myTemporaryConstraints.empty())
+ return 0;
+ removeConstraint(*myTemporaryConstraints.begin());
+ myTemporaryConstraints.erase(myTemporaryConstraints.begin());
+ return (int)myTemporaryConstraints.size();
+}
+
bool SketchSolver_Storage::isTemporary(const Slvs_hConstraint& theConstraintID) const
{
return myTemporaryConstraints.find(theConstraintID) != myTemporaryConstraints.end();
void addTemporaryConstraint(const Slvs_hConstraint& theConstraintID);
/// \brief Remove all transient constraints
void removeTemporaryConstraints();
+ /// \brief Remove first temporary constraint
+ /// \return Number of remaining temporary constraints
+ int removeFirstTemporaryConstraint();
/// \brief Checks the constraint is temporary
bool isTemporary(const Slvs_hConstraint& theConstraintID) const;