#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
+#include <gp_Elips.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <ModelAPI_Tools.h>
#include <ModelAPI_Session.h>
#include <Events_InfoMessage.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Vertex.h>
#include <TNaming_Selector.hxx>
#include <TNaming_NamedShape.hxx>
#include <TDF_ChildIDIterator.hxx>
#include <TopoDS_Iterator.hxx>
#include <TDF_ChildIDIterator.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Ellipse.hxx>
+#include <BRep_Builder.hxx>
//#define DEB_NAMING 1
#ifdef DEB_NAMING
TopoDS_Shape aSelShape = aSelection->Get();
aResult = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
aResult->setImpl(new TopoDS_Shape(aSelShape));
- return aResult;
} else { // for simple construction element: just shape of this construction element
std::shared_ptr<Model_ResultConstruction> aConstr =
std::dynamic_pointer_cast<Model_ResultConstruction>(context());
const TopoDS_Shape aConShape = aCont->shape()->impl<TopoDS_Shape>();
if (!aConShape.IsNull()) {
Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel());
- if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228
+ if (!aNS.IsNull()) {
aNS = TNaming_Tool::CurrentNamedShape(aNS);
- if (!aNS.IsNull()) {
+ if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228
TDF_Label aLab = aNS->Label();
while(aLab.Depth() != 7 && aLab.Depth() > 5)
aLab = aLab.Father();
##
import ModelHighAPI
-import GeomDataAPI
+from GeomDataAPI import *
+from ModelAPI import *
+import math
def addPolyline(sketch, *coords):
"""Add a poly-line to sketch.
return int(filter(str.isdigit, aSketch.string("SolverDOF").value()))
def distancePointPoint(thePoint1, thePoint2):
- aGeomPnt1 = thePoint1
- aGeomPnt2 = thePoint2
- if issubclass(type(thePoint1), GeomDataAPI.GeomDataAPI_Point2D):
- aGeomPnt1 = thePoint1.pnt()
- if issubclass(type(thePoint2), GeomDataAPI.GeomDataAPI_Point2D):
- aGeomPnt2 = thePoint2.pnt()
- return aGeomPnt1.distance(aGeomPnt2)
+ aPnt1 = toList(thePoint1)
+ aPnt2 = toList(thePoint2)
+ return math.hypot(aPnt1[0] - aPnt2[0], aPnt1[1] - aPnt2[1])
def signedDistancePointLine(thePoint, theLine):
aPoint = toList(thePoint)
"""
obtains last feature of given kind from the sketch
"""
- for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
- aSub = theSketch.subFeature(anIndex)
+ aSketch = featureToCompositeFeature(toSketchFeature(theSketch))
+ for anIndex in range(aSketch.numberOfSubs() - 1, -1, -1):
+ aSub = aSketch.subFeature(anIndex)
if (aSub.getKind() == theKind):
return aSub
+
+def toSketchFeature(theEntity):
+ """ Converts entity to sketch feature if possible
+ """
+ if issubclass(type(theEntity), ModelHighAPI.ModelHighAPI_Interface):
+ return theEntity.feature()
+ else:
+ return theEntity
+
+def toList(thePoint):
+ if issubclass(type(thePoint), list):
+ return thePoint
+ elif issubclass(type(thePoint), GeomDataAPI_Point2D):
+ return [thePoint.x(), thePoint.y()]
+ else:
+ aFeature = toSketchFeature(thePoint)
+ aPoint = geomDataAPI_Point2D(aFeature.attribute("PointCoordinates"))
+ return [aPoint.x(), aPoint.y()]
#include <GeomDataAPI_Point2D.h>
#include <SketchPlugin_Feature.h>
-#include <cmath>
-
-// Verify the points are equal
-static bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2);
-// Verify the entities are equal
-static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
-// Convert entity to the list of parameters
+/// \brief Get list of parameters of current entity
static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
myType = CONSTRAINT_FIXED;
}
-SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
- : SketchSolver_Constraint(),
- myBaseFeature(theFeature)
-{
- myType = CONSTRAINT_FIXED;
-}
-
void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
{
- if (myBaseFeature)
- myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
- if (myBaseConstraint)
- SketchSolver_Constraint::blockEvents(isBlocked);
+ SketchSolver_Constraint::blockEvents(isBlocked);
}
void SketchSolver_ConstraintFixed::process()
{
cleanErrorMsg();
- if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
+ if (!myBaseConstraint || !myStorage) {
// Not enough parameters are assigned
return;
}
- EntityWrapperPtr aBaseEntity;
- getAttributes(aBaseEntity, myFixedEntity);
- if (!aBaseEntity) {
- moveFeature(); // remove myFixed entity
+ EntityWrapperPtr aBaseEntity = entityToFix();
+ if (!aBaseEntity)
myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
- }
if (!myErrorMsg.empty())
return;
- fixFeature(aBaseEntity);
+ ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity);
+ myStorage->addConstraint(myBaseConstraint, aConstraint);
}
-void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
+ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
{
GCS::VEC_pD aParameters = toParameters(theFeature);
GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
}
- myConstraint = ConstraintWrapperPtr(
+ return ConstraintWrapperPtr(
new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
-
- if (myBaseConstraint)
- myStorage->addConstraint(myBaseConstraint, myConstraint);
- else
- myStorage->addTemporaryConstraint(myConstraint);
-}
-
-void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
- EntityWrapperPtr& theFixedEntity)
-{
- if (myBaseFeature) {
- // if the feature is copy, do not move it
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
- if (aSketchFeature && aSketchFeature->isCopy()) {
- myStorage->setNeedToResolve(true);
- return;
- }
-
- bool fixFullFeature = false;
- theBaseEntity = EntityWrapperPtr();
- theFixedEntity = EntityWrapperPtr();
-
- // The feature is fixed.
- PlaneGCSSolver_FeatureBuilder aBuilder;
- std::list<AttributePtr> aBaseAttr = myBaseFeature->data()->attributes(std::string());
- std::list<AttributePtr>::const_iterator anIt = aBaseAttr.begin();
- for (; anIt != aBaseAttr.end(); ++anIt) {
- EntityWrapperPtr anEntity = aBuilder.createAttribute(*anIt);
- EntityWrapperPtr aBaseEntity = myStorage->entity(*anIt);
- if (!anEntity || !aBaseEntity)
- continue;
-
- if (!fixFullFeature && anEntity->type() == ENTITY_POINT &&
- !isEqual(anEntity, aBaseEntity)) {
- if (theFixedEntity)
- fixFullFeature = true;
- theFixedEntity = anEntity;
- theBaseEntity = aBaseEntity;
- }
- }
-
- if (fixFullFeature) {
- theFixedEntity = aBuilder.createFeature(myBaseFeature);
- theBaseEntity = myStorage->entity(myBaseFeature);
- if (isEqual(theBaseEntity, theFixedEntity))
- theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
- }
-
- } else if (myBaseConstraint) {
- // Constraint Fixed is added by user.
- // Get the attribute of constraint (it should be alone in the list of constraints).
- EntityWrapperPtr aValue;
- std::vector<EntityWrapperPtr> anAttributes;
- SketchSolver_Constraint::getAttributes(aValue, anAttributes);
- std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
- for (; anIt != anAttributes.end(); ++anIt)
- if (*anIt)
- theBaseEntity = *anIt;
- } else
- myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
}
-void SketchSolver_ConstraintFixed::moveFeature()
+EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
{
- if (!myFixedEntity)
- return;
-
- GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
- for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
- myFixedValues[i] = *(aFixedParams[i]);
-
- // Remove fixed entity due to its parameters already copied into the constraint
- PlaneGCSSolver_EntityDestroyer aDestroyer;
- aDestroyer.remove(myFixedEntity);
- std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage)->removeParameters(
- aDestroyer.parametersToRemove());
-
- myFixedEntity = EntityWrapperPtr();
+ // Constraint Fixed is added by user.
+ // Get the attribute of constraint (it should be alone in the list of constraints).
+ EntityWrapperPtr aValue;
+ std::vector<EntityWrapperPtr> anAttributes;
+ SketchSolver_Constraint::getAttributes(aValue, anAttributes);
+ std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
+ for (; anIt != anAttributes.end(); ++anIt)
+ if (*anIt)
+ return *anIt;
+ return EntityWrapperPtr();
}
-// ==================== Auxiliary functions ===============================
+// ================== Auxiliary functions ==================
GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
{
GCS::VEC_pD aParameters;
return aParameters;
}
-
-bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2)
-{
- return fabs((*thePoint1.x) - (*thePoint2.x)) <= tolerance &&
- fabs((*thePoint1.y) - (*thePoint2.y)) <= tolerance;
-}
-
-bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
-{
- GCS::VEC_pD aParamList1 = toParameters(theEntity1);
- GCS::VEC_pD aParamList2 = toParameters(theEntity2);
-
- GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
- GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
- for (; anIt1 != aParamList1.end() && anIt2 != aParamList2.end(); ++anIt1, ++anIt2)
- if (fabs((**anIt1) - (**anIt2)) > tolerance)
- return false;
-
- return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();
-}
/** \class SketchSolver_ConstraintFixed
* \ingroup Plugins
* \brief Stores data of the Fixed constraint
- *
- * Fixed constraint may have NULL basic SketchPlugin constraint,
- * because the Fixed constraint may be temporary for correct moving of objects.
*/
class SketchSolver_ConstraintFixed : public SketchSolver_Constraint
{
public:
/// Creates constraint to manage the given constraint from plugin
SketchSolver_ConstraintFixed(ConstraintPtr theConstraint);
- /// Creates temporary constraint based on feature (useful while the feature is being moved)
- SketchSolver_ConstraintFixed(FeaturePtr theFeature);
/// \brief Block or unblock events from this constraint
virtual void blockEvents(bool isBlocked);
- /// \brief Set coordinates of fixed feature to the values where it has been dragged.
- /// Useful when the feature is being moved.
- void moveFeature();
-
protected:
/// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
virtual void process();
/// \brief Generate list of attributes of constraint in order useful for constraints
- /// \param[out] theBaseEntity the entity which coordinates should be fixed
- /// \param[out] theFixedEntity the entity containing fixed values
- virtual void getAttributes(EntityWrapperPtr& theBaseEntity,
- EntityWrapperPtr& theFixedEntity);
+ /// \param[out] theValue numerical characteristic of constraint (e.g. distance)
+ /// \param[out] theAttributes list of attributes to be filled
+ virtual void getAttributes(EntityWrapperPtr& , std::vector<EntityWrapperPtr>& )
+ {}
- /// \brief Fixed feature basing on its type
- /// \param theFeature [in] feature, converted to solver specific format
- virtual void fixFeature(EntityWrapperPtr theFeature);
+ /// \brief Obtain entity to be fixed
+ EntityWrapperPtr entityToFix();
-private:
- FeaturePtr myBaseFeature; ///< fixed feature (when it is set, myBaseConstraint should be NULL)
+ /// \brief Create Fixed constraint for the feature basing on its type
+ /// \param theFeature [in] feature, converted to solver specific format
+ /// \return Fixed constraint
+ ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature);
- ConstraintWrapperPtr myConstraint;
+protected:
std::vector<double> myFixedValues;
- EntityWrapperPtr myFixedEntity;
};
#endif
#include "SketchSolver_Error.h"
#include <Events_Loop.h>
+#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_Session.h>
return;
myIsComputed = true;
- if (theMessage->eventID() == aCreatedEvent
- || theMessage->eventID() == anUpdateEvent
- || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
+ if (theMessage->eventID() == aCreatedEvent || theMessage->eventID() == anUpdateEvent) {
std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
isUpdateFlushed = stopSendUpdate();
- isMovedEvt = theMessage->eventID()
- == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
-
- // Shows that the message has at least one feature applicable for solver
- bool hasProperFeature = false;
-
// update sketch features only
const std::set<ObjectPtr>& aFeatures = anUpdateMsg->objects();
// try to keep order as features were created if there are several created features: #2229
}
std::map<int, std::shared_ptr<SketchPlugin_Feature>>::iterator aFeat;
for(aFeat = anOrderedFeatures.begin(); aFeat != anOrderedFeatures.end(); aFeat++) {
- hasProperFeature = updateFeature(aFeat->second, isMovedEvt) || hasProperFeature;
+ updateFeature(aFeat->second);
}
} else { // order is not important
std::set<ObjectPtr>::iterator aFeatIter;
for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
std::shared_ptr<SketchPlugin_Feature> aFeature =
std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
- if (!aFeature || aFeature->isMacro())
- continue;
- hasProperFeature = updateFeature(aFeature, isMovedEvt) || hasProperFeature;
+ if (aFeature && !aFeature->isMacro())
+ updateFeature(aFeature);
}
}
- if (isMovedEvt && hasProperFeature)
- needToResolve = true;
+ } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
+ std::shared_ptr<ModelAPI_ObjectMovedMessage> aMoveMsg =
+ std::dynamic_pointer_cast<ModelAPI_ObjectMovedMessage>(theMessage);
+
+ ObjectPtr aMovedObject = aMoveMsg->movedObject();
+ std::shared_ptr<GeomDataAPI_Point2D> aMovedPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMoveMsg->movedAttribute());
+
+ const std::shared_ptr<GeomAPI_Pnt2d>& aFrom = aMoveMsg->originalPosition();
+ const std::shared_ptr<GeomAPI_Pnt2d>& aTo = aMoveMsg->currentPosition();
+
+ if (aMovedObject) {
+ FeaturePtr aMovedFeature = ModelAPI_Feature::feature(aMovedObject);
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(aMovedFeature);
+ if (aSketchFeature && !aSketchFeature->isMacro())
+ needToResolve = moveFeature(aSketchFeature, aFrom, aTo);
+ } else if (aMovedPoint)
+ needToResolve = moveAttribute(aMovedPoint, aFrom, aTo);
} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleteMsg =
// ============================================================================
// Function: updateFeature
-// Purpose: create/update the constraint or the feature and place it into appropriate group
+// Purpose: create/update constraint or feature in appropriate group
// ============================================================================
-bool SketchSolver_Manager::updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature,
- bool theMoved)
+bool SketchSolver_Manager::updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature)
{
// Check feature validity and find a group to place it.
// If the feature is not valid, the returned group will be empty.
bool isOk = false;
if (aConstraint)
isOk = aGroup->changeConstraint(aConstraint);
- else if (theMoved)
- isOk = aGroup->moveFeature(theFeature);
else
isOk = aGroup->updateFeature(theFeature);
return isOk;
/** \brief Adds or updates a constraint or an entity in the suitable group
* \param[in] theFeature sketch feature to be changed
- * \param[in] theMoved \c true if the feature has been moved in the viewer
* \return \c true if the feature changed successfully
*/
- bool updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature, bool theMoved = false);
+ bool updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature);
/** \brief Move feature
* \param[in] theMovedFeature dragged sketch feature