From: dbv Date: Tue, 3 Nov 2015 11:22:51 +0000 (+0300) Subject: Fillet creation fixes X-Git-Tag: V_2.0.0_alfa1~36 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a4e96a62c87a4b63969cb6a2c7438ba23fa61f1b;p=modules%2Fshaper.git Fillet creation fixes --- diff --git a/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp b/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp index 25d2daf2a..e094b12a7 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp @@ -57,9 +57,12 @@ void SketchPlugin_ConstraintFillet::initAttributes() data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId()); data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId()); + // This attribute used to store base edges + data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId()); data()->addAttribute(PREVIOUS_VALUE, ModelAPI_AttributeDouble::typeId()); // 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()); data()->attribute(PREVIOUS_VALUE)->setInitialized(); std::dynamic_pointer_cast(data()->attribute(PREVIOUS_VALUE))->setValue(0.0); } @@ -89,62 +92,82 @@ void SketchPlugin_ConstraintFillet::execute() aData->attribute(SketchPlugin_Constraint::ENTITY_B())); bool needNewObjects = aRefListOfFillet->size() == 0; + AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::ENTITY_C())); + // Obtain base features - AttributePtr anAttrBase = aBaseA->attr(); - const std::set& aRefsList = anAttrBase->owner()->data()->refsToMe(); - std::set::const_iterator aIt; - FeaturePtr aCoincident; - for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { - std::shared_ptr aAttr = (*aIt); - FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); - if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { - AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast( - aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A())); - AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast( - aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B())); - if(anAttrRefA.get() && !anAttrRefA->isObject()) { - AttributePtr anAttrA = anAttrRefA->attr(); - if(anAttrBase == anAttrA) { - aCoincident = aConstrFeature; - break; + FeaturePtr anOldFeatureA, anOldFeatureB; + if(needNewObjects) { + AttributePtr anAttrBase = aBaseA->attr(); + const std::set& aRefsList = anAttrBase->owner()->data()->refsToMe(); + std::set::const_iterator aIt; + FeaturePtr aCoincident; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast( + aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A())); + AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast( + aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B())); + if(anAttrRefA.get() && !anAttrRefA->isObject()) { + AttributePtr anAttrA = anAttrRefA->attr(); + if(anAttrBase == anAttrA) { + aCoincident = aConstrFeature; + break; + } + } + if(anAttrRefA.get() && !anAttrRefB->isObject()) { + AttributePtr anAttrB = anAttrRefB->attr(); + if(anAttrBase == anAttrB) { + aCoincident = aConstrFeature; + break; + } } } - if(anAttrRefA.get() && !anAttrRefB->isObject()) { - AttributePtr anAttrB = anAttrRefB->attr(); - if(anAttrBase == anAttrB) { - aCoincident = aConstrFeature; - break; + } + + if(!aCoincident.get()) { + setError("No coincident edges at selected vertex"); + return; + } + + std::set aCoinsideLines; + SketchPlugin_Tools::findCoincidences(aCoincident, + SketchPlugin_ConstraintCoincidence::ENTITY_A(), + aCoinsideLines); + SketchPlugin_Tools::findCoincidences(aCoincident, + SketchPlugin_ConstraintCoincidence::ENTITY_B(), + aCoinsideLines); + + // Remove auxilary lines + if(aCoinsideLines.size() > 2) { + std::set aNewLines; + for(std::set::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) { + if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) { + aNewLines.insert(*anIt); } } + aCoinsideLines = aNewLines; } - } - if(!aCoincident.get()) { - setError("No coincident edges at selected vertex"); - return; - } - std::set aCoinsideLines; - SketchPlugin_Tools::findCoincidences(aCoincident, - SketchPlugin_ConstraintCoincidence::ENTITY_A(), - aCoinsideLines); - SketchPlugin_Tools::findCoincidences(aCoincident, - SketchPlugin_ConstraintCoincidence::ENTITY_B(), - aCoinsideLines); - if(aCoinsideLines.size() != 2) { - setError("At selected vertex should be two coincident lines"); - return; - } + if(aCoinsideLines.size() != 2) { + setError("At selected vertex should be two coincident lines"); + return; + } - std::set::iterator aLinesIt = aCoinsideLines.begin(); - FeaturePtr anOldFeatureA = *aLinesIt; - if(!anOldFeatureA) { - setError("One of the edges is empty"); - return; + std::set::iterator aLinesIt = aCoinsideLines.begin(); + anOldFeatureA = *aLinesIt++; + anOldFeatureB = *aLinesIt; + } else { + std::list aNewFeatList = aRefListOfBaseLines->list(); + std::list::iterator aFeatIt = aNewFeatList.begin(); + anOldFeatureA = ModelAPI_Feature::feature(*aFeatIt++); + anOldFeatureB = ModelAPI_Feature::feature(*aFeatIt++); } - aLinesIt++; - FeaturePtr anOldFeatureB = *aLinesIt; - if(!anOldFeatureB) { + + if(!anOldFeatureA.get() || !anOldFeatureB.get()) { setError("One of the edges is empty"); return; } @@ -187,6 +210,7 @@ void SketchPlugin_ConstraintFillet::execute() aRefListOfFillet->remove(aNewFeatureA); aRefListOfFillet->remove(aNewFeatureB); aRefListOfFillet->remove(aNewArc); + aRefListOfBaseLines->clear(); return; } aFeatAttributes[2*i] = aStartAttr; @@ -276,6 +300,10 @@ void SketchPlugin_ConstraintFillet::execute() aRefListOfFillet->append(aNewFeatureB->lastResult()); aRefListOfFillet->append(aNewArc->lastResult()); + // attach base lines to the list + aRefListOfBaseLines->append(anOldFeatureA); + aRefListOfBaseLines->append(anOldFeatureB); + myProducedFeatures.push_back(aNewFeatureA); myProducedFeatures.push_back(aNewFeatureB); myProducedFeatures.push_back(aNewArc); diff --git a/src/SketchPlugin/SketchPlugin_Tools.cpp b/src/SketchPlugin/SketchPlugin_Tools.cpp index 297649e62..82c5a3f93 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.cpp +++ b/src/SketchPlugin/SketchPlugin_Tools.cpp @@ -9,8 +9,9 @@ #include #include #include -#include #include +#include +#include namespace SketchPlugin_Tools { @@ -60,7 +61,7 @@ void clearExpressions(FeaturePtr theFeature) } } -std::shared_ptr getCoincidencePoint(FeaturePtr theStartCoin) +std::shared_ptr getCoincidencePoint(const FeaturePtr theStartCoin) { std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_A()); @@ -69,26 +70,29 @@ std::shared_ptr getCoincidencePoint(FeaturePtr theStartCoin) return aPnt; } -void findCoincidences(FeaturePtr theStartCoin, - std::string theAttr, +void findCoincidences(const FeaturePtr theStartCoin, + const std::string& theAttr, std::set& theList) { AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr); - if (!aPnt) return; + if(!aPnt) { + return; + } FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object()); - if (theList.find(aObj) == theList.end()) { + if(theList.find(aObj) == theList.end()) { std::shared_ptr aOrig = getCoincidencePoint(theStartCoin); - if (aOrig.get() == NULL) + if(aOrig.get() == NULL) { return; + } theList.insert(aObj); const std::set& aRefsList = aObj->data()->refsToMe(); std::set::const_iterator aIt; - for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + for(aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { std::shared_ptr aAttr = (*aIt); FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); - if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + if(aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { std::shared_ptr aPnt = getCoincidencePoint(aConstrFeature); - if (aPnt.get() && aOrig->isEqual(aPnt)) { + if(aPnt.get() && aOrig->isEqual(aPnt)) { findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList); findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList); } diff --git a/src/SketchPlugin/SketchPlugin_Tools.h b/src/SketchPlugin/SketchPlugin_Tools.h index 9123cab7a..9637b5d09 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.h +++ b/src/SketchPlugin/SketchPlugin_Tools.h @@ -18,14 +18,14 @@ void clearExpressions(FeaturePtr theFeature); /// \return coincidence point /// \param[in] theStartCoin coincidence feature -std::shared_ptr getCoincidencePoint(FeaturePtr theStartCoin); +std::shared_ptr getCoincidencePoint(const FeaturePtr theStartCoin); /// Finds lines coincident at point /// \param[in] theStartCoin coincidence feature /// \param[in] theAttr attribute name /// \param[out] theList list of lines -void findCoincidences(FeaturePtr theStartCoin, - std::string theAttr, +void findCoincidences(const FeaturePtr theStartCoin, + const std::string& theAttr, std::set& theList); }; // namespace SketchPlugin_Tools diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 9c8dd5809..ee7121371 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -408,10 +408,18 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut } AttributeRefAttrPtr aBase = std::dynamic_pointer_cast(theAttribute); - if (aBase->isObject()) { + if(aBase->isObject()) { return false; } + // If we alredy have some result then all ok + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + AttributePtr aBaseLinesAttribute = aFeature->attribute(SketchPlugin_Constraint::ENTITY_C()); + AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast(aBaseLinesAttribute); + if(aRefListOfBaseLines->list().size() == 2) { + return true; + } + AttributePtr anAttrBase = aBase->attr(); const std::set& aRefsList = anAttrBase->owner()->data()->refsToMe(); std::set::const_iterator aIt; @@ -452,9 +460,45 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut SketchPlugin_Tools::findCoincidences(aCoincident, SketchPlugin_ConstraintCoincidence::ENTITY_B(), aCoinsideLines); + if(aCoinsideLines.size() < 2) { + return false; + } + + // Remove auxilary lines + if(aCoinsideLines.size() > 2) { + std::set aNewLines; + for(std::set::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) { + if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) { + aNewLines.insert(*anIt); + } + } + aCoinsideLines = aNewLines; + } + if(aCoinsideLines.size() != 2) { return false; } + // Check that lines not collinear + std::set::iterator anIt = aCoinsideLines.begin(); + FeaturePtr aFirstFeature = *anIt++; + FeaturePtr aSecondFeature = *anIt; + if(aFirstFeature->getKind() == SketchPlugin_Line::ID() && aSecondFeature->getKind() == SketchPlugin_Line::ID()) { + std::string aStartAttr = SketchPlugin_Line::START_ID(); + std::string anEndAttr = SketchPlugin_Line::END_ID(); + std::shared_ptr aFirstStartPnt, aFirstEndPnt, aSecondStartPnt, aSecondEndPnt; + aFirstStartPnt = std::dynamic_pointer_cast(aFirstFeature->attribute(aStartAttr))->pnt(); + aFirstEndPnt = std::dynamic_pointer_cast(aFirstFeature->attribute(anEndAttr))->pnt(); + aSecondStartPnt = std::dynamic_pointer_cast(aSecondFeature->attribute(aStartAttr))->pnt(); + aSecondEndPnt = std::dynamic_pointer_cast(aSecondFeature->attribute(anEndAttr))->pnt(); + double aCheck1 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondStartPnt->y() - aFirstStartPnt->y()) - + (aSecondStartPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y())); + double aCheck2 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondEndPnt->y() - aFirstStartPnt->y()) - + (aSecondEndPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y())); + if(aCheck1 < 1.e-7 && aCheck2 < 1.e-7) { + return false; + } + } + return true; }