X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_ConstraintFillet.cpp;h=40c4a83b379a1f6f035552196c7ebf1ffa97877c;hb=e6ab88ed62727ed0f267e133de8965c886d98d78;hp=afbd1407a6e63cbc3e4280135d707e016462ea20;hpb=a603fd1fc9d188d41bbbcfe9dbbc14a146ec4b85;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp b/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp index afbd1407a..40c4a83b3 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp @@ -62,7 +62,8 @@ static std::set getCoincides(const FeaturePtr& theConstraintCoincide SketchPlugin_ConstraintFillet::SketchPlugin_ConstraintFillet() : myListOfPointsChangedInCode(false), myRadiusChangedByUser(false), - myRadiusChangedInCode(true) + myRadiusChangedInCode(false), + myRadiusInitialized(false) { } @@ -70,13 +71,6 @@ void SketchPlugin_ConstraintFillet::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttrList::typeId()); - AttributePtr aResultEdgesRefList = data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId()); // Used to store result edges. - AttributePtr aBasePointsRefAttrList = data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefAttrList::typeId()); // Used to store base points. - // Initialize attribute not applicable for user. - ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B()); - ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C()); - aResultEdgesRefList->setIsArgument(false); - aBasePointsRefAttrList->setIsArgument(false); } void SketchPlugin_ConstraintFillet::execute() @@ -95,20 +89,17 @@ void SketchPlugin_ConstraintFillet::execute() double aFilletRadius = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Constraint::VALUE()))->value(); - // Check the fillet result edges is not initialized yet. - AttributeRefListPtr aResultEdgesRefList = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Constraint::ENTITY_B())); - bool anIsNeedNewObjects = aResultEdgesRefList->size() == 0; - // 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); - for(int anIndex = 0; anIndex < aPointsRefList->size(); ++anIndex) { - std::shared_ptr aFilletPoint2d = - std::dynamic_pointer_cast(aPointsRefList->attribute(anIndex)); + for(std::set::iterator aPointsIter = myNewPoints.begin(); + aPointsIter != myNewPoints.end(); + ++aPointsIter) { + AttributePtr aPointAttr = *aPointsIter; + std::shared_ptr aFilletPoint2d = std::dynamic_pointer_cast(aPointAttr); if(!aFilletPoint2d.get()) { setError("Error: One of the selected points is empty."); return; @@ -116,12 +107,17 @@ void SketchPlugin_ConstraintFillet::execute() std::shared_ptr aFilletPnt2d = aFilletPoint2d->pnt(); // Obtain base lines for fillet. + bool anIsNeedNewObjects = true; + FilletFeatures aFilletFeatures; + std::map::iterator aPrevPointsIter = myPointFeaturesMap.find(aPointAttr); + if(aPrevPointsIter != myPointFeaturesMap.end()) { + anIsNeedNewObjects = false; + aFilletFeatures = aPrevPointsIter->second; + } FeaturePtr aBaseEdgeA, aBaseEdgeB; - if(myBaseEdges.size() > (unsigned int)(anIndex * 2)) { - std::list::iterator anIter = myBaseEdges.begin(); - std::advance(anIter, anIndex * 2); - aBaseEdgeA = *anIter++; - aBaseEdgeB = *anIter; + if(!anIsNeedNewObjects) { + aBaseEdgeA = aFilletFeatures.baseEdgesState.front().first; + aBaseEdgeB = aFilletFeatures.baseEdgesState.back().first; } else { // Obtain constraint coincidence for the fillet point. FeaturePtr aConstraintCoincidence; @@ -166,6 +162,11 @@ void SketchPlugin_ConstraintFillet::execute() std::set::iterator aLinesIt = aCoincides.begin(); aBaseEdgeA = *aLinesIt++; aBaseEdgeB = *aLinesIt; + + std::pair aBasePairA = std::make_pair(aBaseEdgeA, aBaseEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()); + std::pair aBasePairB = std::make_pair(aBaseEdgeB, aBaseEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()); + aFilletFeatures.baseEdgesState.push_back(aBasePairA); + aFilletFeatures.baseEdgesState.push_back(aBasePairB); } if(!aBaseEdgeA.get() || !aBaseEdgeB.get()) { @@ -175,16 +176,23 @@ void SketchPlugin_ConstraintFillet::execute() // Create new edges and arc if needed. FeaturePtr aResultEdgeA, aResultEdgeB, aResultArc; - if(anIsNeedNewObjects) { + if(!anIsNeedNewObjects) { + // Obtain features from the list. + std::list::iterator aResultEdgesIt = aFilletFeatures.resultEdges.begin(); + aResultEdgeA = *aResultEdgesIt++; + aResultEdgeB = *aResultEdgesIt++; + aResultArc = *aResultEdgesIt; + } else { // Copy edges and create arc. aResultEdgeA = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeA, sketch()); + aResultEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false); aResultEdgeB = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(aBaseEdgeB, sketch()); + aResultEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false); aResultArc = sketch()->addFeature(SketchPlugin_Arc::ID()); - } else { - // Obtain features from the list. - aResultEdgeA = ModelAPI_Feature::feature(aResultEdgesRefList->object(anIndex * 3)); - aResultEdgeB = ModelAPI_Feature::feature(aResultEdgesRefList->object(anIndex * 3 + 1)); - aResultArc = ModelAPI_Feature::feature(aResultEdgesRefList->object(anIndex * 3 + 2)); + + aFilletFeatures.resultEdges.push_back(aResultEdgeA); + aFilletFeatures.resultEdges.push_back(aResultEdgeB); + aFilletFeatures.resultEdges.push_back(aResultArc); } // Calculate arc attributes @@ -204,7 +212,6 @@ void SketchPlugin_ConstraintFillet::execute() aStartAttr = SketchPlugin_Arc::START_ID(); aEndAttr = SketchPlugin_Arc::END_ID(); } else { // wrong argument - aResultEdgesRefList->clear(); setError("Error: One of the points has wrong coincide feature"); return; } @@ -290,15 +297,6 @@ void SketchPlugin_ConstraintFillet::execute() aResultArc->execute(); if(anIsNeedNewObjects) { - // attach new arc to the list - aResultEdgesRefList->append(aResultEdgeA->lastResult()); - aResultEdgesRefList->append(aResultEdgeB->lastResult()); - aResultEdgesRefList->append(aResultArc->lastResult()); - - myProducedFeatures.push_back(aResultEdgeA); - myProducedFeatures.push_back(aResultEdgeB); - myProducedFeatures.push_back(aResultArc); - // Create list of additional constraints: // 1. Coincidence of boundary points of features (copied lines/arcs) and fillet arc // 1.1. coincidence @@ -313,7 +311,7 @@ void SketchPlugin_ConstraintFillet::execute() aRefAttr->setAttr(aResultFeatures[aFeatInd]->attribute(aFeatAttributes[anAttrInd])); recalculateAttributes(aResultArc, SketchPlugin_Arc::START_ID(), aResultFeatures[aFeatInd], aFeatAttributes[anAttrInd]); aConstraint->execute(); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent); // 1.2. coincidence aConstraint = sketch()->addFeature(SketchPlugin_ConstraintCoincidence::ID()); @@ -327,7 +325,7 @@ void SketchPlugin_ConstraintFillet::execute() aRefAttr->setAttr(aResultFeatures[aFeatInd]->attribute(aFeatAttributes[anAttrInd])); recalculateAttributes(aResultArc, SketchPlugin_Arc::END_ID(), aResultFeatures[aFeatInd], aFeatAttributes[anAttrInd]); aConstraint->execute(); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent); // 2. Fillet arc radius //aConstraint = sketch()->addFeature(SketchPlugin_ConstraintRadius::ID()); @@ -353,7 +351,7 @@ void SketchPlugin_ConstraintFillet::execute() bool isArc = aResultFeatures[i]->getKind() == SketchPlugin_Arc::ID(); aRefAttr->setObject(isArc ? aResultFeatures[i]->lastResult() : aResultFeatures[i]->firstResult()); aConstraint->execute(); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent); } // 4. Coincidence of free boundaries of base and copied features @@ -366,7 +364,7 @@ void SketchPlugin_ConstraintFillet::execute() aRefAttr = std::dynamic_pointer_cast( aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); aRefAttr->setAttr(aResultFeatures[i]->attribute(aFeatAttributes[anAttrInd])); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); } // 4.1. Additional tangency constraints when the fillet is based on arcs. // It is used to verify the created arc will be placed on a source. @@ -381,7 +379,7 @@ void SketchPlugin_ConstraintFillet::execute() aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); aRefAttr->setObject(aResultFeatures[i]->lastResult()); aConstraint->execute(); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); ModelAPI_EventCreator::get()->sendUpdated(aConstraint, anUpdateEvent); } // 5. Tangent points should be placed on the base features @@ -394,17 +392,18 @@ void SketchPlugin_ConstraintFillet::execute() aRefAttr = std::dynamic_pointer_cast( aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); aRefAttr->setObject(aBaseFeatures[i]->lastResult()); - myProducedFeatures.push_back(aConstraint); + aFilletFeatures.resultConstraints.push_back(aConstraint); } // make base features auxiliary aBaseEdgeA->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true); aBaseEdgeB->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(true); - myBaseEdges.push_back(aBaseEdgeA); - myBaseEdges.push_back(aBaseEdgeB); // exchange the naming IDs of newly created and old line that become auxiliary sketch()->exchangeIDs(aBaseEdgeA, aResultEdgeA); sketch()->exchangeIDs(aBaseEdgeB, aResultEdgeB); + + // store point and features in the map. + myPointFeaturesMap[aPointAttr] = aFilletFeatures; } else { // Update radius value int aNbSubs = sketch()->numberOfSubs(); @@ -441,37 +440,19 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) return; } - // Clear the list of fillet entities. - AttributeRefListPtr aResultEdgesRefList = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::ENTITY_B())); - aResultEdgesRefList->clear(); - - // Clear the list of base points. - AttributeRefAttrListPtr aBasePointsRefAttrList = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Constraint::ENTITY_C())); - aBasePointsRefAttrList->clear(); - - // Clear auxiliary flag on initial objects. - std::list::const_iterator aFeatureIt; - for(aFeatureIt = myBaseEdges.cbegin(); aFeatureIt != myBaseEdges.cend(); ++aFeatureIt) { - (*aFeatureIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false); - } - myBaseEdges.clear(); + // Clear results. + clearResults(); - // Remove all produced objects and constraints. - DocumentPtr aDoc = sketch()->document(); - for(aFeatureIt = myProducedFeatures.cbegin(); aFeatureIt != myProducedFeatures.cend(); ++aFeatureIt) { - aDoc->removeFeature(*aFeatureIt); - } - myProducedFeatures.clear(); + // Clear list of new points. + myNewPoints.clear(); // Get list of points for fillets and current radius. AttributeRefAttrListPtr aRefListOfFilletPoints = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributeDoublePtr aRadiusAttribute = real(SketchPlugin_Constraint::VALUE()); + AttributeDoublePtr aRadiusAttribute = real(VALUE()); int aListSize = aRefListOfFilletPoints->size(); if(aListSize == 0 && !myRadiusChangedByUser) { - // If list is empty just reset radius to zero (if it was not changed by user). + // If list is empty reset radius to zero (if it was not changed by user). myRadiusChangedInCode = true; aRadiusAttribute->setValue(0); myRadiusChangedInCode = false; @@ -482,18 +463,19 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) double aMinimumRadius = 0; std::list> aSelectedPointsList = aRefListOfFilletPoints->list(); std::list>::iterator anIter = aSelectedPointsList.begin(); - std::set aBasePoints; + std::set aPointsToSkeep; for(int anIndex = 0; anIndex < aListSize; anIndex++, anIter++) { AttributePtr aFilletPointAttr = (*anIter).second; std::shared_ptr aFilletPoint2D = std::dynamic_pointer_cast(aFilletPointAttr); if(!aFilletPoint2D.get()) { + myNewPoints.clear(); setError("Error: One of the selected points is invalid."); return; } // If point or coincident point is already in list remove it from attribute. - if(aBasePoints.find(aFilletPointAttr) != aBasePoints.end()) { + if(aPointsToSkeep.find(aFilletPointAttr) != aPointsToSkeep.end()) { myListOfPointsChangedInCode = true; aRefListOfFilletPoints->remove(aFilletPointAttr); myListOfPointsChangedInCode = false; @@ -529,6 +511,7 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) } if(!aConstraintCoincidence.get()) { + myNewPoints.clear(); setError("Error: No coincident edges at one of the selected points."); return; } @@ -554,20 +537,20 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) std::shared_ptr aPoint2D = std::dynamic_pointer_cast(anAttr); if(aPoint2D.get() && aFilletPnt2d->isEqual(aPoint2D->pnt())) { - aBasePoints.insert(anAttr); + aPointsToSkeep.insert(anAttr); } } else if(aFeatureKind == SketchPlugin_Line::ID()) { AttributePtr anAttrStart = (*anIt)->attribute(SketchPlugin_Line::START_ID()); std::shared_ptr aPointStart2D = std::dynamic_pointer_cast(anAttrStart); if(aPointStart2D.get() && aFilletPnt2d->isEqual(aPointStart2D->pnt())) { - aBasePoints.insert(anAttrStart); + aPointsToSkeep.insert(anAttrStart); } AttributePtr anAttrEnd = (*anIt)->attribute(SketchPlugin_Line::END_ID()); std::shared_ptr aPointEnd2D = std::dynamic_pointer_cast(anAttrEnd); if(aPointEnd2D.get() && aFilletPnt2d->isEqual(aPointEnd2D->pnt())) { - aBasePoints.insert(anAttrEnd); + aPointsToSkeep.insert(anAttrEnd); } aNewSetOfCoincides.insert(*anIt); } else if(aFeatureKind == SketchPlugin_Arc::ID() ) { @@ -575,13 +558,13 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) std::shared_ptr aPointStart2D = std::dynamic_pointer_cast(anAttrStart); if(aPointStart2D.get() && aFilletPnt2d->isEqual(aPointStart2D->pnt())) { - aBasePoints.insert(anAttrStart); + aPointsToSkeep.insert(anAttrStart); } AttributePtr anAttrEnd = (*anIt)->attribute(SketchPlugin_Arc::END_ID()); std::shared_ptr aPointEnd2D = std::dynamic_pointer_cast(anAttrEnd); if(aPointEnd2D.get() && aFilletPnt2d->isEqual(aPointEnd2D->pnt())) { - aBasePoints.insert(anAttrEnd); + aPointsToSkeep.insert(anAttrEnd); } aNewSetOfCoincides.insert(*anIt); } @@ -600,13 +583,14 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) } if(aCoincides.size() != 2) { + myNewPoints.clear(); setError("Error: One of the selected points does not have two suitable edges for fillet."); return; } // Store base point for fillet. - aBasePoints.insert(aFilletPointAttr); - aBasePointsRefAttrList->append(aFilletPointAttr); + aPointsToSkeep.insert(aFilletPointAttr); + myNewPoints.insert(aFilletPointAttr); // Get base lines for fillet. FeaturePtr anOldFeatureA, anOldFeatureB; @@ -638,9 +622,12 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID) } } else if(theID == SketchPlugin_Constraint::VALUE()) { - if(!myRadiusChangedInCode) { + if(myRadiusInitialized && !myRadiusChangedInCode) { myRadiusChangedByUser = true; } + if(!myRadiusInitialized) { + myRadiusInitialized = true; + } } } @@ -659,6 +646,46 @@ bool SketchPlugin_ConstraintFillet::isMacro() const return true; } +void SketchPlugin_ConstraintFillet::clearResults() +{ + // Clear auxiliary flag on initial objects. + for(std::map::iterator aPointsIter = myPointFeaturesMap.begin(); + aPointsIter != myPointFeaturesMap.end();) { + const FilletFeatures& aFilletFeatures = aPointsIter->second; + std::list>::const_iterator aFeatureIt; + for(aFeatureIt = aFilletFeatures.baseEdgesState.cbegin(); + aFeatureIt != aFilletFeatures.baseEdgesState.cend(); + ++aFeatureIt) { + aFeatureIt->first->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(aFeatureIt->second); + } + ++aPointsIter; + } + + // And remove all produced features. + DocumentPtr aDoc = sketch()->document(); + for(std::map::iterator aPointsIter = myPointFeaturesMap.begin(); + aPointsIter != myPointFeaturesMap.end();) { + // Remove all produced constraints. + const FilletFeatures& aFilletFeatures = aPointsIter->second; + std::list::const_iterator aFeatureIt; + for(aFeatureIt = aFilletFeatures.resultConstraints.cbegin(); + aFeatureIt != aFilletFeatures.resultConstraints.cend(); + ++aFeatureIt) { + aDoc->removeFeature(*aFeatureIt); + } + + // Remove all result edges. + for(aFeatureIt = aFilletFeatures.resultEdges.cbegin(); + aFeatureIt != aFilletFeatures.resultEdges.cend(); + ++aFeatureIt) { + aDoc->removeFeature(*aFeatureIt); + } + + // Remove point from map. + myPointFeaturesMap.erase(aPointsIter++); + } +}; + // ========= Auxiliary functions ================= void recalculateAttributes(FeaturePtr theNewArc, const std::string& theNewArcAttribute,