// the define to check the activated object as a sub-feature by argument of
// the operation feature. E.g. rectangle feature(operation), line(in argument) to be not activated
-//#define DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
+#define DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
#ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
#include <ModelAPI_AttributeRefList.h>
#endif
return true;
}
#ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
- FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObj);
- std::list<AttributePtr> anAttributes = aFeature->data()->attributes(
- ModelAPI_AttributeRefList::typeId());
- std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
- bool aFoundObject = false;
- for (; anIt != aLast && !aFoundObject; anIt++) {
- std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
- std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
- for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFoundObject; i++) {
- ObjectPtr anObject = aCurSelList->object(i);
- FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
- if (aFeature.get()) {
- aFoundObject = anObjectFeature == aFeature;
+ if (aFeature->isMacro()) {
+ // macro feature may refers to sub-features, which also should be deactivated when the operation
+ // is active, e.g. rectangle'lines.
+ FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObj);
+ std::list<AttributePtr> anAttributes = aFeature->data()->attributes(
+ ModelAPI_AttributeRefList::typeId());
+ std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
+ bool aFoundObject = false;
+ for (; anIt != aLast && !aFoundObject; anIt++) {
+ std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
+ for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFoundObject; i++) {
+ ObjectPtr anObject = aCurSelList->object(i);
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ if (aFeature.get()) {
+ aFoundObject = anObjectFeature == aFeature;
+ }
}
}
+ return aFoundObject;
}
- return aFoundObject;
#endif
}
return false;
return ModelAPI_Session::get()->moduleDocument();
}
-/*std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::getFeaturePoint(FeaturePtr theFeature,
- double theX, double theY)
-{
- std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
- new GeomAPI_Pnt2d(theX, theY));
- std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes =
- theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
- std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
- aLast = anAttiributes.end();
- std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
- for (; anIt != aLast && !aFPoint; anIt++) {
- std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = std::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(*anIt);
- if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())
- aFPoint = aCurPoint;
- }
-
- return aFPoint;
-}*/
-
void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue,
const std::string& theAttribute)
{
}*/
+std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInArgumentFeatures(
+ const FeaturePtr& theFeature, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+ std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+
+ // may be feature is not updated yet, execute is not performed and references features
+ // are not created. Case: rectangle macro feature
+ ModuleBase_ModelWidget::updateObject(theFeature);
+
+ std::list<AttributePtr> anAttributes = theFeature->data()->attributes(
+ ModelAPI_AttributeRefList::typeId());
+ std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
+ for (; anIt != aLast && !aFeaturePoint.get(); anIt++) {
+ std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
+ for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFeaturePoint.get(); i++) {
+ ObjectPtr anObject = aCurSelList->object(i);
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
+ if (aFeature.get())
+ aFeaturePoint = PartSet_Tools::findFirstEqualPoint(aFeature, thePoint);
+ }
+ }
+ return aFeaturePoint;
+}
+
+std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPoint(const FeaturePtr& theFeature,
+ const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+ std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
+
+ // find the given point in the feature attributes
+ std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes =
+ theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
+ aLast = anAttiributes.end();
+ for (; anIt != aLast && !aFPoint; anIt++) {
+ std::shared_ptr<GeomDataAPI_Point2D> aCurPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
+ if (aCurPoint && (aCurPoint->pnt()->distance(thePoint) < Precision::Confusion())) {
+ aFPoint = aCurPoint;
+ break;
+ }
+ }
+ return aFPoint;
+}
+
void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature,
const std::string& theAttribute, double theClickedX,
double theClickedY)
{
+ if (!theFeature.get())
+ return;
+
+ std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
+ new GeomAPI_Pnt2d(theClickedX, theClickedY));
+
// find a feature point by the selection mode
- //std::shared_ptr<GeomDataAPI_Point2D> aPoint = featurePoint(theMode);
- std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint = std::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
+ std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+ if (theFeature->isMacro()) {
+ // the macro feature will be removed after the operation is stopped, so we need to build
+ // coicidence to possible sub-features
+ aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(theFeature, aClickedPoint);
+ }
+ else {
+ aFeaturePoint = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
+ }
if (!aFeaturePoint)
return;
std::list<ObjectPtr> aFeatures = aRefList->list();
std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes;
- std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
- new GeomAPI_Pnt2d(theClickedX, theClickedY));
for (; anIt != aLast; anIt++) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
if (!aFeature.get() || theFeature == aFeature)
continue;
- // find the given point in the feature attributes
- anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
- std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
- aLast = anAttiributes.end();
- std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
- for (; anIt != aLast && !aFPoint; anIt++) {
- std::shared_ptr<GeomDataAPI_Point2D> aCurPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
- if (aCurPoint && (aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())) {
- aFPoint = aCurPoint;
- break;
- }
- }
+ std::shared_ptr<GeomDataAPI_Point2D> aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature,
+ aClickedPoint);
if (aFPoint)
PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint);
}
std::shared_ptr<GeomDataAPI_Point2D> thePoint1,
std::shared_ptr<GeomDataAPI_Point2D> thePoint2);
+ /// Finds in the feature's sub-features first Point2D attribute with the given point coordinates
+ /// \param theFeature a feature with sub-feature attributes
+ /// \param thePoint a point to provided searched coordinates
+ /// \return found point or null
+ static std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInArgumentFeatures(
+ const FeaturePtr& theFeature, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
+ /// Finds in the feature first Point2D attribute with the given point coordinates
+ /// \param theFeature a feature with point attributes
+ /// \param thePoint a point to provided searched coordinates
+ /// \return found point or null
+ static std::shared_ptr<GeomDataAPI_Point2D> findFirstEqualPoint(const FeaturePtr& theFeature,
+ const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
/// Creates constrains of the current
/// \param theSketch a sketch feature
/// \param theFeature a source feature
void PartSet_WidgetPoint2D::setConstraintWith(const ObjectPtr& theObject)
{
+ std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+ if (feature()->isMacro()) {
+ AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
+ std::shared_ptr<GeomDataAPI_Point2D> anAttrPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
+ if (anAttrPoint.get()) {
+ // the macro feature will be removed after the operation is stopped, so we need to build
+ // coicidence to possible sub-features
+ aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(feature(),
+ anAttrPoint->pnt());
+ }
+ }
+ else {
+ AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
+ aFeaturePoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
+ }
+ if (!aFeaturePoint.get())
+ return;
+
// Create point-edge coincedence
FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
- AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
- std::shared_ptr<GeomDataAPI_Point2D> aThisPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aThisAttr);
- aRef1->setAttr(aThisPoint);
+
+ aRef1->setAttr(aFeaturePoint);
std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
if (theEvent->button() != Qt::LeftButton)
return;
- bool isCoincidenceEnabled = MyFeaturesForCoincedence.contains(myFeature->getKind().c_str());
-
ModuleBase_ISelection* aSelection = myWorkshop->selection();
Handle(V3d_View) aView = theWnd->v3dView();
// TODO: This fragment doesn't work because bug in OCC Viewer. It can be used after fixing.
aSPFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(aSelectedFeature);
if ((!aSPFeature && !aShape.IsNull()) ||
(aSPFeature.get() && aSPFeature->isExternal())) {
- ResultPtr aFixedObject;
- if (isCoincidenceEnabled) {
- anExternal = true;
- aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
- if (!aFixedObject.get())
- aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
- }
+ ResultPtr aFixedObject;
+ anExternal = true;
+ aFixedObject = PartSet_Tools::findFixedObjectByExternal(aShape, aObject, mySketch);
+ if (!aFixedObject.get())
+ aFixedObject = PartSet_Tools::createFixedObjectByExternal(aShape, aObject, mySketch);
double aX, aY;
if (getPoint2d(aView, aShape, aX, aY) && isFeatureContainsPoint(myFeature, aX, aY)) {
// do not create a constraint to the point, which already used by the feature
bool isAuxiliaryFeature = false;
if (getPoint2d(aView, aShape, aX, aY)) {
setPoint(aX, aY);
+ feature()->execute();
PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
}
else if (aShape.ShapeType() == TopAbs_EDGE) {
- if (isCoincidenceEnabled) {
- setConstraintWith(aObject);
- setValueState(Stored); // in case of edge selection, Apply state should also be updated
-
- FeaturePtr anObjectFeature = ModelAPI_Feature::feature(aObject);
- std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID();
- AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
- anObjectFeature->data()->attribute(anAuxiliaryAttribute));
- if (anAuxiliaryAttr.get())
- isAuxiliaryFeature = anAuxiliaryAttr->value();
- }
+ setConstraintWith(aObject);
+ setValueState(Stored); // in case of edge selection, Apply state should also be updated
+
+ FeaturePtr anObjectFeature = ModelAPI_Feature::feature(aObject);
+ std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID();
+ AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+ anObjectFeature->data()->attribute(anAuxiliaryAttribute));
+ if (anAuxiliaryAttr.get())
+ isAuxiliaryFeature = anAuxiliaryAttr->value();
}
// it is important to perform updateObject() in order to the current value is
// processed by Sketch Solver. Test case: line is created from a previous point