std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
std::list<AttributePtr> aRefsToFeature;
getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
-
+#ifdef DEBUG_TRIM
+ std::cout << "---- getRefAttributes ----" << std::endl;
+ std::map<AttributePtr, std::list<AttributePtr> >::const_iterator
+ aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end();
+ std::cout << std::endl << "References to attributes of base feature [" <<
+ aBaseRefAttributes.size() << "]" << std::endl;
+ for (; aRefIt != aRefLast; aRefIt++) {
+ AttributePtr aBaseAttr = aRefIt->first;
+ std::list<AttributePtr> aRefAttributes = aRefIt->second;
+ std::string aRefsInfo;
+ std::list<AttributePtr>::const_iterator aRefAttrIt = aRefAttributes.begin(),
+ aRefAttrLast = aRefAttributes.end();
+ for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) {
+ if (!aRefsInfo.empty())
+ aRefsInfo.append(",");
+ AttributePtr aRAttr = *aRefAttrIt;
+ aRefsInfo.append(aRAttr->id());
+ FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner());
+ aRefsInfo.append("(" + aRFeature->name() + ") ");
+ }
+ std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aBaseAttr);
+ std::cout << aPointAttr->id().c_str() <<
+ ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl;
+ }
+ std::cout << std::endl;
+ std::cout << std::endl << "References to base feature [" <<
+ aRefsToFeature.size() << "]" << std::endl;
+ std::list<AttributePtr>::const_iterator aRefAttrIt = aRefsToFeature.begin(),
+ aRefAttrLast = aRefsToFeature.end();
+ std::string aRefsInfo;
+ for (; aRefAttrIt != aRefAttrLast; aRefAttrIt++) {
+ if (!aRefsInfo.empty())
+ aRefsInfo.append(",");
+ AttributePtr aRAttr = *aRefAttrIt;
+ aRefsInfo.append(aRAttr->id());
+ FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner());
+ aRefsInfo.append("(" + aRFeature->name() + ") ");
+ }
+ std::cout << "[" << aRefsToFeature.size() << "] " << aRefsInfo << std::endl;
+ std::cout << "---- getRefAttributes:end ----" << std::endl;
+#endif
// coincidence to result points
// find coincidences to the base object, it should be used when attribute is found
// in myObjectToPoints
- std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
- getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
+ //std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
+ //getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
std::set<AttributePoint2DPtr> aFurtherCoincidences;
std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
}
else if (aKind == SketchPlugin_Line::ID()) {
- trimLine(aStartShapePoint2d, aLastShapePoint2d,
+ trimLine(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
aFurtherCoincidences, aModifiedAttributes);
}
else if (aKind == SketchPlugin_Arc::ID()) {
- trimArc(aStartShapePoint2d, aLastShapePoint2d,
+ trimArc(aStartShapePoint2d, aLastShapePoint2d, aBaseRefAttributes,
aFurtherCoincidences, aModifiedAttributes);
}
std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
#ifdef DEBUG_TRIM
- std::cout << "<compare Points> => "
+ std::cout << "<compare Points> => " << std::endl
<< "aPoint2d: [" << aPoint2d->x() << ", " << aPoint2d->y() << "]" << std::endl;
if (aStartShapePoint2d.get())
std::cout << "Start Point: [" << aStartShapePoint2d->x() << ", " << aStartShapePoint2d->y()
break;
}
}
- /*const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
- for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
- anAttrIt != anAttributes.end(); anAttrIt++) {
- AttributePtr anAttribute = *anAttrIt;
- if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
- {
- FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
- AttributePtr anOtherAttribute;
- if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
- anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
- else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
- anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
- else
- continue;
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
- (anOtherAttribute);
- if (aRefAttr.get())
- aRefAttr->setAttr(aPointAttribute);
- }
- }
- */
const std::list<ObjectPtr>& anObjects = anInfo.second;
for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
anObjectIt != anObjects.end(); anObjectIt++) {
aLast = aRefsToFeature.end();
anIt != aLast; anIt++) {
AttributePtr anAttribute = *anIt;
+
+ //if (replaceCoincidenceAttribute(anAttribute, aModifiedAttributes))
+ // continue;
+
if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
continue;
}
}
+ updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
+
// Wait all constraints being created, then send update events
static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
if (isUpdateFlushed)
Events_Loop::loop()->setFlushed(anUpdateEvent, false);
- updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
-
// delete constraints
-#ifdef DEBUG_TRIM
- std::cout << "remove features and references:" << std::endl;
- std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
- aDLast = aFeaturesToDelete.end();
- for (; aDIt != aDLast; aDIt++) {
- //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
- //std::cout << std::endl;
- }
-#endif
ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
if (aPoint2d->isEqual(aRefPnt2d)) {
AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
theAttribute);
- /*if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_A())
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
- else if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_B())
- aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));*/
if (aRefAttr.get()) {
aRefAttr->setAttr(aPointAttribute);
aFoundPoint = true;
}
}
}
- /*AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
- if (!aRefAttr.get())
- return false;
+ return aFoundPoint;
+}
- if (aRefAttr.get())
- aRefAttr->setObject(aReplacingResult);//continue;
- else {
- //AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
- AttributeReferencePtr aReferenceAttr =
- std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
- }*/
+bool SketchPlugin_Trim::replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
+ const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+{
+ FeaturePtr aCoincidenceFeature = ModelAPI_Feature::feature(theCoincidenceAttribute->owner());
+ if (aCoincidenceFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+ return false;
- return aFoundPoint;
+ AttributeRefAttrPtr aCAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aCAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aCoincidenceFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ AttributePtr aCAttrRefA = aCAttrA->attr();
+ AttributePtr aCAttrRefB = aCAttrB->attr();
+
+ bool isProcessed = false;
+ for (std::set<std::pair<AttributePtr, AttributePtr>>::const_iterator
+ anIt = theModifiedAttributes.begin(); anIt != theModifiedAttributes.end(); anIt++) {
+ AttributePtr anAttributeBefore = anIt->first;
+ if (anAttributeBefore == aCAttrRefA) {
+ aCAttrA->setAttr(anIt->second);
+ isProcessed = true;
+ }
+ if (anAttributeBefore == aCAttrRefB) {
+ aCAttrB->setAttr(anIt->second);
+ isProcessed = true;
+ }
+ }
+ return isProcessed;
}
bool SketchPlugin_Trim::isMacro() const
}
}
-void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
+/*void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
{
const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
}
}
-}
+}*/
void SketchPlugin_Trim::updateRefAttConstraints(
const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
aRLast = aRefAttributes.end();
AttributePtr aNewAttribute = anIt->second;
- for (; aRefIt != aRLast; aRefIt++) {
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
- if (aRefAttr.get()) {
- if (aNewAttribute.get())
- aRefAttr->setAttr(aNewAttribute);
- else
- theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
-#ifdef DEBUG_TRIM
- //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
- //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
-#endif
+ if (aNewAttribute.get()) {
+ for (; aRefIt != aRLast; aRefIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ if (aRefAttr.get()) {
+ aRefAttr->setAttr(aNewAttribute);
+ }
}
}
}
}
+void SketchPlugin_Trim::removeReferencesToAttribute(const AttributePtr& theAttribute,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes)
+{
+ /// not found in references
+ if (theBaseRefAttributes.find(theAttribute) == theBaseRefAttributes.end())
+ return;
+
+ std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(theAttribute);
+ std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
+ aRLast = aRefAttributes.end();
+
+ std::set<FeaturePtr> aFeaturesToDelete;
+ for (; aRefIt != aRLast; aRefIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ if (aRefAttr.get()) {
+ aFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
+ }
+ }
+
+ // delete constraints
+ ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+}
+
void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
- std::set<AttributePoint2DPtr>& thePoints,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+ std::set<AttributePoint2DPtr>& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
// Check the base objects are initialized.
else
aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
+ // it is important to delete references before the feature modification because
+ // if deletion will be after the feature modification, solver returns the feature back
+ removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute),
+ theBaseRefAttributes);
+
fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
- theModifiedAttributes.insert(
- std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
+ //theModifiedAttributes.insert(
+ // std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aBaseFeature->attribute(aModifiedAttribute)));
}
void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
- const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
- std::set<AttributePoint2DPtr>& thePoints,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+ std::set<AttributePoint2DPtr>& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
// Check the base objects are initialized.
#ifdef DEBUG_TRIM
std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
if (aStartShapePoint.get())
- std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
+ std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " <<
aStartShapePoint->y() << "]" << std::endl;
- std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
+ std::cout << "Start arc attribute point: [" << aStartArcPoint->x() << ", " <<
aStartArcPoint->y() << "]" << std::endl;
if (aLastShapePoint.get())
- std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
+ std::cout << "Last shape point: [" << aLastShapePoint->x() << ", " <<
aLastShapePoint->y() << "]" << std::endl;
- std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
+ std::cout << "Last arc attribute point: [" << aLastArcPoint->x() << ", " <<
aLastArcPoint->y() << "]" << std::endl;
#endif
else
aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
+ removeReferencesToAttribute(aBaseFeature->attribute(aModifiedAttribute),
+ theBaseRefAttributes);
+
fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
- theModifiedAttributes.insert(
- std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aBaseFeature->attribute(aModifiedAttribute)));
createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+
+ std::cout << "Created arc on points:" << std::endl;
+ std::cout << "Start shape point: [" << aStartShapePoint->x() << ", " <<
+ aStartShapePoint->y() << "]" << std::endl;
+
}
}
aModifiedAttribute->setValue(thePoint);
#ifdef DEBUG_TRIM
- std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
- << thePoint->y() << "]" << std::endl;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theModifiedAttribute->owner());
+ std::cout << "<fillPointAttribute[" << aFeature->data()->name() << ": " <<
+ theModifiedAttribute->id() <<
+ "]> => Pnt2d - [" << thePoint->x() << ", " << thePoint->y() << "]" << std::endl;
#endif
}
}
const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
{
+#ifdef DEBUG_TRIM
+ std::cout << "---- createLineFeature ---" << std::endl;
+#endif
+
FeaturePtr aFeature;
SketchPlugin_Sketch* aSketch = sketch();
if (!aSketch || !theBaseFeature.get())
aFeature->execute(); // to obtain result
+#ifdef DEBUG_TRIM
+ std::cout << "---- createLineFeature:end ---" << std::endl;
+#endif
+
return aFeature;
}
if (aCenterAttributeId.empty())
return aFeature;
+#ifdef DEBUG_TRIM
+ std::cout << "---- createArcFeature ---" << std::endl;
+#endif
+
aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
// update fillet arc: make the arc correct for sure, so, it is not needed to process
// the "attribute updated"
//aFeature->execute(); // to obtain result
aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
+ #ifdef DEBUG_TRIM
+ std::cout << "---- createArcFeature:end ---" << std::endl;
+ #endif
+
return aFeature;
}
bool setCoincidenceToAttribute(const AttributePtr& theAttribute,
const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+ bool replaceCoincidenceAttribute(const AttributePtr& theCoincidenceAttribute,
+ const std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+
typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
/// by the coincident attribute
/// \param theObject an investigated object
/// \param theCoincidencesToBaseFeature a container of list of referenced attributes
- void getCoincidencesToObject(const std::shared_ptr<ModelAPI_Object>& theObject,
- std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
+ //void getCoincidencesToObject(const std::shared_ptr<ModelAPI_Object>& theObject,
+ // std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
/// Move constraints from attribute of base feature to attribute after modification
/// \param theBaseRefAttributes container of references to the attributes of base feature
const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
+ /// Remove references constraints from attribute of base feature refer to the given attribute
+ /// \param theAttribute an attribute
+ /// \param theModifiedAttributes modifiable container of attributes
+ void removeReferencesToAttribute(const AttributePtr& theAttribute,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes);
+
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
+ /// \param theBaseRefAttributes container of references to the attributes of base feature
/// \param thePoints a list of points where coincidences will be build
/// \param theModifiedAttributes a container of attribute on base
/// feature to attribute on new feature
void trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
void trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+ std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
- /// \param theSplitFeature a result split feature
- /// \param theBeforeFeature a feature between start point and the 1st point of split feature
- /// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
FeaturePtr trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,