aRemove.push_back(aFeature);
}
else {
- AttributeSelectionPtr anExtAttr = aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+ AttributeSelectionPtr anExtAttr =
+ aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
ResultPtr anExternal = anExtAttr ? anExtAttr->context() : ResultPtr();
if (anExternal) {
FeaturePtr anExtFeature = ModelAPI_Feature::feature(anExternal);
SketchPlugin_IntersectionPoint::INCLUDE_INTO_RESULT())->value();
}
+ aFeature->boolean(SketchPlugin_SketchEntity::COPY_ID())->setValue(false);
aFeature->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(
!isIncludedToSketchResult);
}
}
}
for (std::list<FeaturePtr>::iterator anIt = aRemove.begin(); anIt != aRemove.end(); ++anIt)
- removeFeature(*anIt);
+ document()->removeFeature(*anIt);
return true;
}
theAttributes.clear();
myPrevValue = 0.0;
+
+ myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP());
}
void SketchSolver_ConstraintDistance::adjustConstraint()
myIsSigned = false;
}
+
+void SketchSolver_ConstraintDistance::notify(const FeaturePtr& theFeature,
+ PlaneGCSSolver_Update*)
+{
+ if (getType() == CONSTRAINT_PT_LINE_DISTANCE && myIsSigned &&
+ theFeature->getKind() == SketchPlugin_Sketch::ID()) {
+ // the sketch plane was updated, recalculate auxiliary constraints
+ removeConstraintsKeepingSign();
+ addConstraintsToKeepSign();
+ myIsSigned = true; // reset it, due to changing by removeConstraintsKeepingSign()
+ }
+}
/// \brief Remove constraint
virtual bool remove();
+ /// \brief Notify this object about the feature is changed somewhere
+ virtual void notify(const FeaturePtr& theFeature, PlaneGCSSolver_Update*);
+
protected:
/// \brief Generate list of attributes of constraint in order useful for constraints
/// \param[out] theValue numerical characteristic of constraint (e.g. distance)
// ========================================================
SketchSolver_Group::SketchSolver_Group(const CompositeFeaturePtr& theWorkplane)
- : mySketch(theWorkplane),
- myPrevResult(PlaneGCSSolver_Solver::STATUS_UNKNOWN),
+ : myPrevResult(PlaneGCSSolver_Solver::STATUS_UNKNOWN),
myDOF(-1),
myIsEventsBlocked(false),
myMultiConstraintUpdateStack(0)
{
mySketchSolver = SolverPtr(new PlaneGCSSolver_Solver);
myStorage = StoragePtr(new PlaneGCSSolver_Storage(mySketchSolver));
+ updateSketch(theWorkplane);
}
SketchSolver_Group::~SketchSolver_Group()
return true;
}
+bool SketchSolver_Group::updateSketch(CompositeFeaturePtr theSketch)
+{
+ static const double THE_TOLERANCE = 1.e-7;
+ bool isChanged = theSketch != mySketch;
+
+ AttributePointPtr anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+ theSketch->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+ AttributeDirPtr aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ theSketch->attribute(SketchPlugin_Sketch::NORM_ID()));
+ AttributeDirPtr aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ theSketch->attribute(SketchPlugin_Sketch::DIRX_ID()));
+
+ isChanged = isChanged
+ || (mySketchOrigin && anOrigin->pnt()->distance(mySketchOrigin) > THE_TOLERANCE)
+ || (mySketchNormal && aNorm->xyz()->distance(mySketchNormal->xyz()) > THE_TOLERANCE)
+ || (mySketchXDir && aDirX->xyz()->distance(mySketchXDir->xyz()) > THE_TOLERANCE);
+
+ if (isChanged) {
+ mySketch = theSketch;
+ mySketchOrigin = anOrigin->pnt();
+ mySketchNormal = aNorm->dir();
+ mySketchXDir = aDirX->dir();
+
+ myStorage->notify(theSketch);
+ }
+ return true;
+}
+
bool SketchSolver_Group::updateFeature(FeaturePtr theFeature)
{
return myStorage->update(theFeature);
#include <memory>
#include <map>
+class GeomAPI_Dir;
+class GeomAPI_Pnt;
class GeomAPI_Pnt2d;
typedef std::map<ConstraintPtr, SolverConstraintPtr> ConstraintConstraintMap;
*/
bool changeConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
+ /** \brief Updates the sketch feature
+ */
+ bool updateSketch(CompositeFeaturePtr theSketch);
+
/** \brief Updates the data corresponding the specified feature
* \param[in] theFeature the feature to be updated
*/
private:
CompositeFeaturePtr mySketch; ///< Sketch for this group
+ std::shared_ptr<GeomAPI_Pnt> mySketchOrigin;
+ std::shared_ptr<GeomAPI_Dir> mySketchNormal;
+ std::shared_ptr<GeomAPI_Dir> mySketchXDir;
+
ConstraintConstraintMap myConstraints; ///< List of constraints
std::set<SolverConstraintPtr> myTempConstraints; ///< List of temporary constraints
}
static void featuresOrderedByType(const std::set<ObjectPtr>& theOriginalFeatures,
- IndexedFeatureMap& theOrderedFeatures)
+ IndexedFeatureMap& theOrderedFeatures,
+ CompositeFeaturePtr& theSketch)
{
int aFeatureIndex = 0;
int aConstraintIndex = (int)theOriginalFeatures.size();
for (; aFeatIter != theOriginalFeatures.end(); aFeatIter++) {
std::shared_ptr<SketchPlugin_Feature> aFeature =
std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
- if (aFeature && !aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) {
- std::shared_ptr<SketchPlugin_Constraint> aConstraint =
- std::dynamic_pointer_cast<SketchPlugin_Constraint>(aFeature);
- if (aConstraint)
- theOrderedFeatures[++aConstraintIndex] = aFeature;
- else
- theOrderedFeatures[++aFeatureIndex] = aFeature;
+ if (aFeature) {
+ if (!aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) {
+ std::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ std::dynamic_pointer_cast<SketchPlugin_Constraint>(aFeature);
+ if (aConstraint)
+ theOrderedFeatures[++aConstraintIndex] = aFeature;
+ else
+ theOrderedFeatures[++aFeatureIndex] = aFeature;
+ }
+ }
+ else {
+ std::shared_ptr<SketchPlugin_Sketch> aSketch =
+ std::dynamic_pointer_cast<SketchPlugin_Sketch>(*aFeatIter);
+ if (aSketch)
+ theSketch = aSketch;
}
}
}
// update sketch features only
const std::set<ObjectPtr>& aFeatures = anUpdateMsg->objects();
IndexedFeatureMap anOrderedFeatures;
+ CompositeFeaturePtr aSketchFeature;
// try to keep order as features were created if there are several created features: #2229
if (theMessage->eventID() == aCreatedEvent && aFeatures.size() > 1) {
featuresOrderedByCreation(aFeatures, anOrderedFeatures);
} else { // order is not important, just process features before constraints
- featuresOrderedByType(aFeatures, anOrderedFeatures);
+ featuresOrderedByType(aFeatures, anOrderedFeatures, aSketchFeature);
}
IndexedFeatureMap::iterator aFeat;
for (aFeat = anOrderedFeatures.begin(); aFeat != anOrderedFeatures.end(); aFeat++) {
updateFeature(aFeat->second);
}
+ updateSketch(aSketchFeature);
} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
std::shared_ptr<ModelAPI_ObjectMovedMessage> aMoveMsg =
Events_Loop::loop()->flush(anUpdateEvent);
}
+// ============================================================================
+// Function: updateSketch
+// Purpose: update sketch plane in appropriate group
+// ============================================================================
+bool SketchSolver_Manager::updateSketch(const CompositeFeaturePtr& theSketch)
+{
+ if (!theSketch)
+ return true;
+
+ bool isOk = true;
+ std::list<SketchGroupPtr>::const_iterator aGroupIt;
+ for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); ++aGroupIt)
+ if ((*aGroupIt)->getWorkplane() == theSketch) {
+ (*aGroupIt)->updateSketch(theSketch);
+ break;
+ }
+ return isOk;
+}
+
// ============================================================================
// Function: updateFeature
// Purpose: create/update constraint or feature in appropriate group
class GeomAPI_Pnt2d;
class GeomDataAPI_Point2D;
+class ModelAPI_CompositeFeature;
class SketchPlugin_Constraint;
/** \class SketchSolver_Manager
*/
bool updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature);
+ /** \brief Updates the sketch and related constraints, if the sketch plane is changed
+ * \param[in] theSketch sketch to be updated
+ * \return \c true if the sketch plane is changed
+ */
+ bool updateSketch(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch);
+
/** \brief Move feature
* \param[in] theMovedFeature dragged sketch feature
* \param[in] theFromPoint original position of the feature