- return std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(attribute(INVERSED_ID()))->value();
-}
-
-void SketchPlugin_Arc::tangencyArcConstraints()
-{
- if (!lastResult())
- return;
-
- std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_ID()));
- AttributeRefAttrPtr aTangPtAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- attribute(TANGENT_POINT_ID()));
- if (!aTangPtAttr->attr())
- return;
-
- FeaturePtr aFeature = ModelAPI_Feature::feature(aStartAttr->owner());
- ObjectPtr aThisArc = aFeature->lastResult();
- aFeature = ModelAPI_Feature::feature(aTangPtAttr->attr()->owner());
- ObjectPtr aTangFeature = aFeature->lastResult();
-
- // trying to find constraints to fix the tangency of the arc
- std::set<FeaturePtr> aCoincidence;
- std::set<FeaturePtr> aTangency;
-
- AttributeRefAttrPtr aRefAttrA, aRefAttrB;
- std::set<AttributePtr> aRefs = data()->refsToMe();
- const std::set<AttributePtr>& aRefsToResult = lastResult()->data()->refsToMe();
- aRefs.insert(aRefsToResult.begin(), aRefsToResult.end());
- std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
- for (; aRefIt != aRefs.end(); ++aRefIt) {
- FeaturePtr aConstrFeature = ModelAPI_Feature::feature((*aRefIt)->owner());
- if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
- if ((aRefAttrA && aRefAttrA->attr() == aStartAttr) ||
- (aRefAttrB && aRefAttrB->attr() == aStartAttr))
- aCoincidence.insert(aConstrFeature);
- }
- else if (aConstrFeature->getKind() == SketchPlugin_ConstraintTangent::ID()) {
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
- if ((aRefAttrA && aRefAttrA->object() == aThisArc) ||
- (aRefAttrB && aRefAttrB->object() == aThisArc))
- aTangency.insert(aConstrFeature);
- }
- }
- // search applicable pair of constraints
- bool isFound = false;
- FeaturePtr aPrevCoincidence, aPrevTangency;
- std::set<FeaturePtr>::const_iterator aCIt, aTIt;
- for (aCIt = aCoincidence.begin(); aCIt != aCoincidence.end() && !isFound; ++aCIt) {
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- (*aCIt)->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- (*aCIt)->attribute(SketchPlugin_Constraint::ENTITY_B()));
- AttributePtr anOtherPoint =
- aRefAttrA->attr() == aStartAttr ? aRefAttrB->attr() : aRefAttrA->attr();
- for (aTIt = aTangency.begin(); aTIt != aTangency.end() && !isFound; ++aTIt) {
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- (*aTIt)->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- (*aTIt)->attribute(SketchPlugin_Constraint::ENTITY_B()));
- ObjectPtr anOtherObject = aRefAttrA->object() == aThisArc ?
- aRefAttrB->object() : aRefAttrA->object();
- FeaturePtr anOtherFeature = ModelAPI_Feature::feature(anOtherObject);
- if (anOtherPoint->owner() == anOtherFeature) {
- isFound = true;
- aPrevCoincidence = *aCIt;
- aPrevTangency = *aTIt;
- }
- }
- }
-
- if (isFound) {
- // update previous constraints
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aPrevCoincidence->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aPrevCoincidence->attribute(SketchPlugin_Constraint::ENTITY_B()));
- if (aRefAttrA->attr() == aStartAttr)
- aRefAttrB->setAttr(aTangPtAttr->attr());
- else
- aRefAttrA->setAttr(aTangPtAttr->attr());
-
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aPrevTangency->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aPrevTangency->attribute(SketchPlugin_Constraint::ENTITY_B()));
- if (aRefAttrA->object() == aThisArc)
- aRefAttrB->setObject(aTangFeature);
- else
- aRefAttrA->setObject(aTangFeature);
- } else {
- // Wait all constraints being removed, then send update events
- static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
- bool isDeleteFlushed = Events_Loop::loop()->isFlushed(aDeleteEvent);
- if (isDeleteFlushed)
- Events_Loop::loop()->setFlushed(aDeleteEvent, false);
- // Remove all obtained constraints which use current arc, because
- // there is no information which of them were used to build tangency arc.
- DocumentPtr aDoc = sketch()->document();
- std::set<FeaturePtr> aFeaturesToBeRemoved;
- for (aCIt = aCoincidence.begin(); aCIt != aCoincidence.end(); ++aCIt)
- aFeaturesToBeRemoved.insert(*aCIt);
- for (aTIt = aTangency.begin(); aTIt != aTangency.end(); ++aTIt)
- aFeaturesToBeRemoved.insert(*aTIt);
- ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToBeRemoved);
- // Send events to update the sub-features by the solver.
- if (isDeleteFlushed)
- Events_Loop::loop()->setFlushed(aDeleteEvent, true);
- else
- Events_Loop::loop()->flush(aDeleteEvent);
-
- // Wait all constraints being created, then send update events
- static Events_ID aCreateEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
- bool isCreateFlushed = Events_Loop::loop()->isFlushed(aCreateEvent);
- if (isCreateFlushed)
- Events_Loop::loop()->setFlushed(aCreateEvent, false);
-
- // Create new constraints
- FeaturePtr aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID());
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
- aRefAttrA->setAttr(aStartAttr);
- aRefAttrB->setAttr(aTangPtAttr->attr());
- aConstraint->execute();
- ModelAPI_EventCreator::get()->sendUpdated(aConstraint, aCreateEvent);
-
- aConstraint = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID());
- aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
- aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
- aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
- aRefAttrA->setObject(aThisArc);
- aRefAttrB->setObject(aTangFeature);
- aConstraint->execute();
- ModelAPI_EventCreator::get()->sendUpdated(aConstraint, aCreateEvent);
-
- // Send events to update the sub-features by the solver.
- if(isCreateFlushed)
- Events_Loop::loop()->setFlushed(aCreateEvent, true);
- else
- Events_Loop::loop()->flush(aCreateEvent);
- }