X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Sketch.cpp;h=debbfbb336b6bb47607c08e4212cf0a1661a95b7;hb=f98f887290d4e2b4bd6618389911e82b6b9674f3;hp=f243c86c77aa0da8ca83cdd4beb837b5b2afb54f;hpb=3baa523772616910e6fb91a52306e7cb2d9e9468;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp old mode 100644 new mode 100755 index f243c86c7..debbfbb33 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -9,16 +9,14 @@ #include #include -#include #include #include -#include -#include -#include -#include +#include +#include #include +#include #include #include #include @@ -26,9 +24,14 @@ #include #include #include +#include #include #include +#include +#include + +#include #include @@ -43,15 +46,20 @@ SketchPlugin_Sketch::SketchPlugin_Sketch() void SketchPlugin_Sketch::initAttributes() { - data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::type()); - data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::type()); - data()->addAttribute(SketchPlugin_Sketch::DIRY_ID(), GeomDataAPI_Dir::type()); - data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::type()); - data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::type()); + data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::typeId()); + data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::typeId()); + data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::typeId()); + data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::typeId()); // the selected face, base for the sketcher plane, not obligatory - data()->addAttribute(SketchPlugin_Feature::EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + data()->addAttribute(SketchPlugin_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), SketchPlugin_SketchEntity::EXTERNAL_ID()); + data()->addAttribute(SketchPlugin_Sketch::SOLVER_ERROR(), ModelAPI_AttributeString::typeId()); ModelAPI_Session::get()->validators()->registerNotObligatory( - getKind(), SketchPlugin_Feature::EXTERNAL_ID()); + getKind(), SketchPlugin_Sketch::SOLVER_ERROR()); + data()->addAttribute(SketchPlugin_Sketch::SOLVER_DOF(), ModelAPI_AttributeString::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), SketchPlugin_Sketch::SOLVER_DOF()); } void SketchPlugin_Sketch::execute() @@ -65,13 +73,11 @@ void SketchPlugin_Sketch::execute() data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); std::shared_ptr aDirX = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - std::shared_ptr aDirY = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); std::shared_ptr aNorm = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::NORM_ID())); std::list aFeatures = aRefList->list(); - if (aFeatures.empty()) + if (aFeatures.empty()) // actually, this must be avoided by the validators return; std::list::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end(); @@ -83,13 +89,13 @@ void SketchPlugin_Sketch::execute() if (!aFeature->sketch()) // on load document the back references are missed aFeature->setSketch(this); // do not include the external edges into the result - if (aFeature->data()->attribute(SketchPlugin_Feature::EXTERNAL_ID())) { - if (aFeature->data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value()) + if (aFeature->data()->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())) { + if (aFeature->data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->value()) continue; } // do not include the construction entities in the result - if (aFeature->data()->attribute(SketchPlugin_Feature::CONSTRUCTION_ID())) { - if (aFeature->data()->boolean(SketchPlugin_Feature::CONSTRUCTION_ID())->value()) + if (aFeature->data()->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID())) { + if (aFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) continue; } @@ -107,22 +113,13 @@ void SketchPlugin_Sketch::execute() } } - if (aFeaturesPreview.empty()) - return; - // Collect all edges as one big wire std::shared_ptr aBigWire(new GeomAPI_PlanarEdges); std::list >::const_iterator aShapeIt = aFeaturesPreview.begin(); for (; aShapeIt != aFeaturesPreview.end(); ++aShapeIt) { aBigWire->addEdge(*aShapeIt); } - aBigWire->setOrigin(anOrigin->pnt()); - aBigWire->setDirX(aDirX->dir()); - aBigWire->setDirY(aDirY->dir()); - aBigWire->setNorm(aNorm->dir()); - -// GeomAlgoAPI_SketchBuilder::createFaces(anOrigin->pnt(), aDirX->dir(), aDirY->dir(), aNorm->dir(), -// aFeaturesPreview, aLoops, aWires); + aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aNorm->dir()); std::shared_ptr aConstr = document()->createConstruction(data()); aConstr->setShape(aBigWire); setResult(aConstr); @@ -130,51 +127,70 @@ void SketchPlugin_Sketch::execute() std::shared_ptr SketchPlugin_Sketch::addFeature(std::string theID) { - std::shared_ptr aNew = document()->addFeature(theID); + std::shared_ptr aNew = document()->addFeature(theID, false); if (aNew) { - std::dynamic_pointer_cast(aNew)->setSketch(this); + // the sketch cannot be specified for the macro-features defined in python + // like SketchRectangle, so we need to check the type of new feature + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(aNew); + if (aSketchFeature) + aSketchFeature->setSketch(this); data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->append(aNew); } + // set as current also after it becomes sub to set correctly enabled for other sketch subs + document()->setCurrentFeature(aNew, false); return aNew; } void SketchPlugin_Sketch::removeFeature(std::shared_ptr theFeature) { - if (!data().get()) // sketch is already removed (case on undo of sketch), sync is not needed + if (!data()->isValid()) // sketch is already removed (case on undo of sketch), sync is not needed return; - list aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list(); - list::iterator aSubIt = aSubs.begin(), aLastIt = aSubs.end(); - bool isRemoved = false; - bool aHasEmtpyFeature = false; - for(; aSubIt != aLastIt && !isRemoved; aSubIt++) { - std::shared_ptr aFeature = std::dynamic_pointer_cast(*aSubIt); - if (aFeature.get() != NULL && aFeature == theFeature) { - data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->remove(aFeature); - isRemoved = true; - } - else if (aFeature.get() == NULL) - aHasEmtpyFeature = true; + AttributeRefListPtr aList = reflist(SketchPlugin_Sketch::FEATURES_ID()); + // if the object is last, remove it from the list (needed to skip empty transaction on edit of sketch feature) + if (aList->object(aList->size(true) - 1, true) == theFeature) { + aList->remove(theFeature); + } else { + // to keep the persistent sub-elements indexing, do not remove elements from list, + // but substitute by nulls + aList->substitute(theFeature, ObjectPtr()); } - // if the object is not found in the sketch sub-elements, that means that the object is removed already. - // Find the first empty element and remove it - if (!isRemoved && aHasEmtpyFeature) - data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->remove(ObjectPtr()); } -int SketchPlugin_Sketch::numberOfSubs() const +int SketchPlugin_Sketch::numberOfSubs(bool forTree) const { - return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(); + if (forTree) + return 0; + return data()->reflist(FEATURES_ID())->size(false); } -std::shared_ptr SketchPlugin_Sketch::subFeature(const int theIndex) const +std::shared_ptr SketchPlugin_Sketch::subFeature( + const int theIndex, bool forTree) { - ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex); - return std::dynamic_pointer_cast(anObj); + if (forTree) + return FeaturePtr(); + + ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex, false); + FeaturePtr aRes = std::dynamic_pointer_cast(anObj); + return aRes; } int SketchPlugin_Sketch::subFeatureId(const int theIndex) const { - return subFeature(theIndex)->data()->featureId(); + std::shared_ptr aRefList = std::dynamic_pointer_cast< + ModelAPI_AttributeRefList>(data()->attribute(SketchPlugin_Sketch::FEATURES_ID())); + std::list aFeatures = aRefList->list(); + std::list::const_iterator anIt = aFeatures.begin(); + int aResultIndex = 1; // number of the counted (created) features, started from 1 + int aFeatureIndex = -1; // number of the not-empty features in the list + for (; anIt != aFeatures.end(); anIt++) { + if (anIt->get()) + aFeatureIndex++; + if (aFeatureIndex == theIndex) + break; + aResultIndex++; + } + return aResultIndex; } bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const @@ -187,84 +203,16 @@ bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const aFeature = document()->feature(aRes); } if (aFeature) { - list aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list(); - for(list::iterator aSubIt = aSubs.begin(); aSubIt != aSubs.end(); aSubIt++) { - if (*aSubIt == aFeature) - return true; - } + return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->isInList(aFeature); } return false; } -std::shared_ptr SketchPlugin_Sketch::to3D(const double theX, const double theY) -{ - std::shared_ptr aC = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - std::shared_ptr aX = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - std::shared_ptr aY = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); - - std::shared_ptr aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX)) - ->added(aY->dir()->xyz()->multiplied(theY)); - - return std::shared_ptr(new GeomAPI_Pnt(aSum)); -} - -std::shared_ptr SketchPlugin_Sketch::to2D( - const std::shared_ptr& thePnt) -{ - std::shared_ptr aC = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - std::shared_ptr aX = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - std::shared_ptr aY = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); - return thePnt->to2D(aC->pnt(), aX->dir(), aY->dir()); -} - - -bool SketchPlugin_Sketch::isPlaneSet() -{ - std::shared_ptr aNormal = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::NORM_ID())); - - return aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0); -} - -std::shared_ptr SketchPlugin_Sketch::plane() -{ - std::shared_ptr anOrigin = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - std::shared_ptr aNorm = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::NORM_ID())); - - if (!anOrigin || !aNorm) - return std::shared_ptr(); - - return std::shared_ptr(new GeomAPI_Pln(anOrigin->pnt(), aNorm->dir())); -} - -void SketchPlugin_Sketch::erase() -{ - std::shared_ptr aRefList = std::dynamic_pointer_cast< - ModelAPI_AttributeRefList>(data()->attribute(SketchPlugin_Sketch::FEATURES_ID())); - std::list aFeatures = aRefList->list(); - std::list::const_iterator anIt = aFeatures.begin(); - for (; anIt != aFeatures.end(); anIt++) { - FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); - if (aFeature) { - // subs are referenced from sketch, but must be removed for sure, so not checkings - document()->removeFeature(aFeature); - } - } - ModelAPI_CompositeFeature::erase(); -} void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { - if (theID == SketchPlugin_Feature::EXTERNAL_ID()) { + if (theID == SketchPlugin_SketchEntity::EXTERNAL_ID()) { std::shared_ptr aSelection = - data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value(); + data()->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->value(); if (aSelection) { // update arguments due to the selection value // update the sketch plane std::shared_ptr aPlane = GeomAlgoAPI_FaceBuilder::plane(aSelection); @@ -279,8 +227,8 @@ void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero)); std::shared_ptr anOrigPnt(new GeomAPI_Pnt(aCoords)); // X axis is preferable to be dirX on the sketch - static const double tol = 1.e-7; - bool isX = fabs(anA - 1.0) < tol && fabs(aB) < tol && fabs(aC) < tol; + static const double tol = 0.1; // here can not be very small value to avoid very close to X normal axis (issue 595) + bool isX = fabs(anA) - 1.0 < tol && fabs(aB) < tol && fabs(aC) < tol; std::shared_ptr aTempDir( isX ? new GeomAPI_Dir(0, 1, 0) : new GeomAPI_Dir(1, 0, 0)); std::shared_ptr aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir))); @@ -296,11 +244,84 @@ void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { std::shared_ptr aDirX = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::DIRX_ID())); aDirX->setValue(aXDir); - std::shared_ptr aDirY = std::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); - aDirY->setValue(aYDir); std::shared_ptr aDir = aPlane->direction(); } } + } else if (theID == NORM_ID() || theID == DIRX_ID() || theID == ORIGIN_ID()) { + // send all sub-elements are also updated: all entities become created on different plane + static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + std::list aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list(); + std::list::iterator aSub = aSubs.begin(); + for(; aSub != aSubs.end(); aSub++) { + if (aSub->get()) + ModelAPI_EventCreator::get()->sendUpdated(*aSub, anUpdateEvent); + } + } +} + +void SketchPlugin_Sketch::createPoint2DResult(ModelAPI_Feature* theFeature, + SketchPlugin_Sketch* theSketch, + const std::string& theAttributeID, const int theIndex) +{ + std::shared_ptr aPoint = std::dynamic_pointer_cast( + theFeature->attribute(theAttributeID)); + + if (!aPoint || !aPoint->isInitialized()) + return; + + std::shared_ptr aCenter(theSketch->to3D(aPoint->x(), aPoint->y())); + //std::cout<<"Execute circle "<x()<<" "<y()<<" "<z()< aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); + std::shared_ptr aResult = theFeature->document()->createConstruction( + theFeature->data(), theIndex); + aResult->setShape(aCenterPointShape); + aResult->setIsInHistory(false); + + theFeature->setResult(aResult, theIndex); +} + +FeaturePtr SketchPlugin_Sketch::addUniqueNamedCopiedFeature(FeaturePtr theFeature, + SketchPlugin_Sketch* theSketch, + const bool theIsCopy) +{ + FeaturePtr aNewFeature = theSketch->addFeature(theFeature->getKind()); + // addFeature generates a unique name for the feature, it caches the name + std::string aUniqueFeatureName = aNewFeature->data()->name(); + // all attribute values are copied\pasted to the new feature, name is not an exception + theFeature->data()->copyTo(aNewFeature->data()); + // external state should not be copied as a new object is an object of the current sketch + if (theFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID()).get()) + theFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->setValue(ResultPtr(), + GeomShapePtr()); + aNewFeature->data()->setName(aUniqueFeatureName); + // text expressions could block setValue of some attributes + SketchPlugin_Tools::clearExpressions(aNewFeature); + // Set copy attribute + AttributeBooleanPtr anAttr = aNewFeature->data()->boolean(SketchPlugin_SketchEntity::COPY_ID()); + if(anAttr.get()) { + anAttr->setValue(theIsCopy); } + + return aNewFeature; +} + +std::shared_ptr SketchPlugin_Sketch::plane(SketchPlugin_Sketch* theSketch) +{ + std::shared_ptr aData = theSketch->data(); + + std::shared_ptr anOrigin = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + std::shared_ptr aDirX = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::DIRX_ID())); + std::shared_ptr aNorm = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Sketch::NORM_ID())); + + return std::shared_ptr(new GeomAPI_Ax3(anOrigin->pnt(), aDirX->dir(), aNorm->dir())); +} + +void SketchPlugin_Sketch::exchangeIDs( + std::shared_ptr theFeature1, std::shared_ptr theFeature2) +{ + reflist(SketchPlugin_Sketch::FEATURES_ID())->exchange(theFeature1, theFeature2); }