Events_Error::send(aFeatureError, this);
return;
}
+ // if result of Boolean operation is same as was before it means that Boolean operation has no sence
+ // and naming provides no result, so, generate an error in this case
+ if (anObject->isEqual(aFeature->shape())) {
+ std::string aFeatureError = "Boolean feature: operation was not performed";
+ Events_Error::send(aFeatureError, this);
+ return;
+ }
//LoadNamingDS
LoadNamingDS(aFeature, aResultBody, anObject, aTool, aType);
if (updateFeature(aComposite->subFeature(a)))
aMustbeUpdated = true;
}
- if (aMustbeUpdated) {
- for(int a = 0; a < aSubsNum; a++) {
- if (aComposite->subFeature(a) && aFactory->validate(aComposite->subFeature(a)))
- aComposite->subFeature(a)->execute();
- }
- }
}
// check all references: if referenced objects are updated, this object also must be updated
std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
}
}
+ //std::cout<<"Update feature "<<theFeature->getKind()<<" must be updated = "<<aMustbeUpdated<<std::endl;
// execute feature if it must be updated
if (aMustbeUpdated) {
if (boost::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
if (isAutomatic || (myJustCreatedOrUpdated.find(theFeature) != myJustCreatedOrUpdated.end()) ||
!theFeature->isPersistentResult() /* execute quick, not persistent results */)
{
+ //std::cout<<"Execute feature "<<theFeature->getKind()<<std::endl;
// before execution update the selection attributes if any
list<AttributePtr> aRefs =
theFeature->data()->attributes(ModelAPI_AttributeSelection::type());
aSel->value(a)->update();
}
}
+ // for sketch after update of plane (by update of selection attribute)
+ // but before execute, all sub-elements also must be updated (due to the plane changes)
+ if (aComposite) {
+ int aSubsNum = aComposite->numberOfSubs();
+ for(int a = 0; a < aSubsNum; a++) {
+ FeaturePtr aSub = aComposite->subFeature(a);
+ bool aWasModified = myUpdated[aSub];
+ myUpdated.erase(myUpdated.find(aSub)); // erase to update for sure (plane may be changed)
+ myInitial.insert(aSub);
+ updateFeature(aSub);
+ myUpdated[aSub] = aWasModified; // restore value
+ }
+ // re-execute after update: solver may update the previous values, so, shapes must be
+ // updated
+ for(int a = 0; a < aSubsNum; a++) {
+ if (aComposite->subFeature(a) && aFactory->validate(aComposite->subFeature(a)))
+ aComposite->subFeature(a)->execute();
+ }
+ }
+
// execute in try-catch to avoid internal problems of the feature
try {
theFeature->execute();
FeaturePtr theSketch,
const QList<ModuleBase_ViewerPrs>& theSelected,
const QList<ModuleBase_ViewerPrs>& theHighlighted)
+{
+ // firstly it finds the feature in the list of highlight
+ ObjectPtr aDeltaObject = nearestFeature(thePoint, theView, theSketch, theHighlighted);
+ if (!aDeltaObject)
+ // secondly it finds the feature in the list of selected objects
+ aDeltaObject = nearestFeature(thePoint, theView, theSketch, theSelected);
+
+ return aDeltaObject;
+}
+
+ObjectPtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView,
+ FeaturePtr theSketch,
+ const QList<ModuleBase_ViewerPrs>& thePresentations)
{
ObjectPtr aDeltaObject;
- // 1. find the object in the highlighted list
- if (theHighlighted.size() > 0) {
- aDeltaObject = theHighlighted.first().object();
- }
- // 2. find it in the selected list by the selected point
+
+ CompositeFeaturePtr aSketch =
+ boost::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
+ // 1. find it in the selected list by the selected point
if (!aDeltaObject) {
double aX, anY;
gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView);
FeaturePtr aFeature;
double aMinDelta = -1;
ModuleBase_ViewerPrs aPrs;
- foreach (ModuleBase_ViewerPrs aPrs, theSelected) {
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
if (!aPrs.object())
continue;
FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
SketchPlugin_Feature>(aFeature);
- if (!aSketchFeature)
+ if (!aSketchFeature || !aSketch->isSub(aSketchFeature))
continue;
double aDelta = aSketchFeature->distanceToPoint(
}
}
}
- // 3. if the object is not found, returns the first selected one
- if (!aDeltaObject && theSelected.size() > 0)
- aDeltaObject = theSelected.first().object();
-
+ // 2. if the object is not found, returns the first selected sketch feature
+ if (!aDeltaObject && thePresentations.size() > 0) {
+ // there can be some highlighted objects, e.g. a result of boolean operation and a sketch point
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
+ if (!aPrs.object())
+ continue;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
+ if (aFeature && aSketch->isSub(aFeature))
+ aDeltaObject = aPrs.object();
+ }
+ }
return aDeltaObject;
}
/// \param theY the output vertical coordinate of the point
static bool hasVertexShape(const ModuleBase_ViewerPrs& thePrs, FeaturePtr theSketch,
Handle_V3d_View theView, double& theX, double& theY);
+protected:
+ /// Returns an object that is under the mouse point. Firstly it checks the highlighting,
+ /// if it exists, the first object is returned. Secondly, there is an iteration on
+ /// the selected list to find the point. Thirdly, if the object is not found under the
+ /// the point, the first selected object is returned.
+ /// \param thePoint a screen point
+ /// \param theView a 3D view
+ /// \param theSketch the sketch feature
+ /// \param thePresentations the list of presentations
+ static ObjectPtr nearestFeature(QPoint thePoint, Handle_V3d_View theView, FeaturePtr theSketch,
+ const QList<ModuleBase_ViewerPrs>& thePresentations);
+
};
#endif
boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(RADIUS_ID()));
if (aCenterAttr->isInitialized() && aRadiusAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
+ //std::cout<<"Execute circle "<<aCenter->x()<<" "<<aCenter->y()<<" "<<aCenter->z()<<std::endl;
// make a visible point
boost::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
boost::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
if (aStartAttr->isInitialized() && anEndAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+ //std::cout<<"Execute line "<<aStart->x()<<" "<<aStart->y()<<" "<<aStart->z()<<" - "
+ // <<anEnd->x()<<" "<<anEnd->y()<<" "<<anEnd->z()<<std::endl;
// make linear edge
boost::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
// store the result
boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
if (kIsAttrChanged) {
+ /* now it is in updater
// the plane was changed, so reexecute sub-elements to update shapes (located in new plane)
ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
list<ObjectPtr> aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list();
aFeature->execute();
}
}
+ */
kIsAttrChanged = false;
}
}