X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Sketch.cpp;h=7b993c2161e0ad1d3daa39ea59f25188c5490430;hb=6d1d824304c048a69924a836c4e6fa74d301b95e;hp=d0ebbbf8e0957c752c1cfb19c5ceafe627efc57f;hpb=29083ee3765ce3f564eb4fa6c93620084acfb067;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index d0ebbbf8e..7b993c216 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + // File: SketchPlugin_Sketch.cxx // Created: 27 Mar 2014 // Author: Mikhail PONIKAROV @@ -9,11 +11,12 @@ #include #include -#include -#include +#include + +#include -#include -#include +#include +#include #include #include @@ -21,11 +24,20 @@ #include #include #include +#include +#include +#include #include +#include +#include +#include + +#include -#include +#include +#include #include using namespace std; @@ -36,27 +48,28 @@ 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_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId()); + ModelAPI_Session::get()->validators()->registerNotObligatory( + getKind(), SketchPlugin_SketchEntity::EXTERNAL_ID()); } void SketchPlugin_Sketch::execute() { if (!data()->isValid()) return; - boost::shared_ptr aRefList = boost::dynamic_pointer_cast< + std::shared_ptr aRefList = std::dynamic_pointer_cast< ModelAPI_AttributeRefList>(data()->attribute(SketchPlugin_Sketch::FEATURES_ID())); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( + std::shared_ptr anOrigin = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aDirX = boost::dynamic_pointer_cast( + std::shared_ptr aDirX = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aDirY = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); - boost::shared_ptr aNorm = boost::dynamic_pointer_cast( + std::shared_ptr aNorm = std::dynamic_pointer_cast( data()->attribute(SketchPlugin_Sketch::NORM_ID())); std::list aFeatures = aRefList->list(); @@ -64,19 +77,31 @@ void SketchPlugin_Sketch::execute() return; std::list::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end(); - boost::shared_ptr aFeature; - std::list > aFeaturesPreview; + std::shared_ptr aFeature; + std::list > aFeaturesPreview; for (; anIt != aLast; anIt++) { - aFeature = boost::dynamic_pointer_cast(*anIt); + aFeature = std::dynamic_pointer_cast(*anIt); if (aFeature) { + 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_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_SketchEntity::AUXILIARY_ID())) { + if (aFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) + continue; + } - const std::list >& aRes = aFeature->results(); - std::list >::const_iterator aResIter = aRes.cbegin(); + const std::list >& aRes = aFeature->results(); + std::list >::const_iterator aResIter = aRes.cbegin(); for (; aResIter != aRes.cend(); aResIter++) { - boost::shared_ptr aConstr = boost::dynamic_pointer_cast< + std::shared_ptr aConstr = std::dynamic_pointer_cast< ModelAPI_ResultConstruction>(*aResIter); if (aConstr) { - boost::shared_ptr aShape = aConstr->shape(); + std::shared_ptr aShape = aConstr->shape(); if (aShape) aFeaturesPreview.push_back(aShape); } @@ -88,137 +113,216 @@ void SketchPlugin_Sketch::execute() return; // Collect all edges as one big wire - boost::shared_ptr aBigWire(new GeomAPI_Wire); - std::list >::const_iterator aShapeIt = aFeaturesPreview.begin(); + 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); - boost::shared_ptr aConstr = document()->createConstruction(data()); + aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aNorm->dir()); + std::shared_ptr aConstr = document()->createConstruction(data()); aConstr->setShape(aBigWire); setResult(aConstr); } -boost::shared_ptr SketchPlugin_Sketch::addFeature(std::string theID) +std::shared_ptr SketchPlugin_Sketch::addFeature(std::string theID) { - boost::shared_ptr aNew = document()->addFeature(theID); + std::shared_ptr aNew = document()->addFeature(theID, false); if (aNew) { - boost::dynamic_pointer_cast(aNew)->setSketch(this); + std::dynamic_pointer_cast(aNew)->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; } -int SketchPlugin_Sketch::numberOfSubs() const +void SketchPlugin_Sketch::removeFeature(std::shared_ptr theFeature) { - return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(); -} - -boost::shared_ptr SketchPlugin_Sketch::subFeature(const int theIndex) const -{ - ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex); - return boost::dynamic_pointer_cast(anObj); + if (!data()->isValid()) // sketch is already removed (case on undo of sketch), sync is not needed + return; + // to keep the persistent sub-elements indexing, do not remove elements from list, + // but substitute by nulls + reflist(SketchPlugin_Sketch::FEATURES_ID())->substitute(theFeature, ObjectPtr()); + + std::map >::iterator aSubIter = mySubs.begin(); + for(; aSubIter != mySubs.end(); aSubIter++) { + if (aSubIter->second == theFeature) { + mySubs.erase(aSubIter); + break; + } + } } -int SketchPlugin_Sketch::subFeatureId(const int theIndex) const +int SketchPlugin_Sketch::numberOfSubs(bool forTree) const { - return subFeature(theIndex)->data()->featureId(); + if (forTree) + return 0; + return data()->reflist(FEATURES_ID())->size(false); } -boost::shared_ptr SketchPlugin_Sketch::to3D(const double theX, const double theY) +std::shared_ptr SketchPlugin_Sketch::subFeature( + const int theIndex, bool forTree) { - boost::shared_ptr aC = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aX = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRX_ID())); - boost::shared_ptr aY = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::DIRY_ID())); + if (forTree) + return FeaturePtr(); - boost::shared_ptr aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX)) - ->added(aY->dir()->xyz()->multiplied(theY)); + if (mySubs.find(theIndex) != mySubs.end()) + return mySubs[theIndex]; - return boost::shared_ptr(new GeomAPI_Pnt(aSum)); + ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex, false); + FeaturePtr aRes = std::dynamic_pointer_cast(anObj); + mySubs[theIndex] = aRes; + return aRes; } -bool SketchPlugin_Sketch::isPlaneSet() +int SketchPlugin_Sketch::subFeatureId(const int theIndex) const { - boost::shared_ptr aNormal = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::NORM_ID())); - - return aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0); + 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; } -boost::shared_ptr SketchPlugin_Sketch::plane() +bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const { - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aNorm = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::NORM_ID())); + // check is this feature of result + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (!aFeature) { + ResultPtr aRes = std::dynamic_pointer_cast(theObject); + if (aRes) + aFeature = document()->feature(aRes); + } + if (aFeature) { + return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->isInList(aFeature); + } + return false; +} - if (!anOrigin || !aNorm) - return boost::shared_ptr(); - return boost::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 addPlane(double theX, double theY, double theZ, - std::list >& theShapes) -{ - boost::shared_ptr anOrigin(new GeomAPI_Pnt(0, 0, 0)); - boost::shared_ptr aNormal(new GeomAPI_Dir(theX, theY, theZ)); - double aSize = Config_PropManager::integer("Sketch planes", "Size of planes", PLANE_SIZE); - boost::shared_ptr aFace = GeomAlgoAPI_FaceBuilder::square(anOrigin, aNormal, - aSize); - theShapes.push_back(aFace); +void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { + if (theID == SketchPlugin_SketchEntity::EXTERNAL_ID()) { + std::shared_ptr aSelection = + 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); + if (aPlane) { + double anA, aB, aC, aD; + aPlane->coefficients(anA, aB, aC, aD); + + // calculate attributes of the sketch + std::shared_ptr aNormDir(new GeomAPI_Dir(anA, aB, aC)); + std::shared_ptr aCoords = aNormDir->xyz(); + std::shared_ptr aZero(new GeomAPI_XYZ(0, 0, 0)); + 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 = 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))); + std::shared_ptr aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir))); + + // update position of the sketch + std::shared_ptr anOrigin = std::dynamic_pointer_cast + (data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); + anOrigin->setValue(anOrigPnt); + std::shared_ptr aNormal = std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Sketch::NORM_ID())); + aNormal->setValue(aNormDir); + std::shared_ptr aDirX = std::dynamic_pointer_cast( + data()->attribute(SketchPlugin_Sketch::DIRX_ID())); + aDirX->setValue(aXDir); + std::shared_ptr aDir = aPlane->direction(); + } + } + } else if (theID == SketchPlugin_Sketch::NORM_ID() || theID == SketchPlugin_Sketch::DIRX_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); + } + } } -AISObjectPtr SketchPlugin_Sketch::getAISObject(AISObjectPtr thePrevious) +void SketchPlugin_Sketch::createPoint2DResult(ModelAPI_Feature* theFeature, + SketchPlugin_Sketch* theSketch, + const std::string& theAttributeID, const int theIndex) { - boost::shared_ptr aNorm = boost::dynamic_pointer_cast( - data()->attribute(SketchPlugin_Sketch::NORM_ID())); + std::shared_ptr aPoint = std::dynamic_pointer_cast( + theFeature->attribute(theAttributeID)); - if (!aNorm || (aNorm->x() == 0 && aNorm->y() == 0 && aNorm->z() == 0)) { - AISObjectPtr aAIS = thePrevious; - if (!aAIS) { - std::list > aFaces; + if (!aPoint || !aPoint->isInitialized()) + return; - addPlane(1, 0, 0, aFaces); // YZ plane - addPlane(0, 1, 0, aFaces); // XZ plane - addPlane(0, 0, 1, aFaces); // XY plane - boost::shared_ptr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aFaces); - aAIS = AISObjectPtr(new GeomAPI_AISObject()); - aAIS->createShape(aCompound); + 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); - std::vector aRGB = Config_PropManager::color("Sketch planes", "planes_color", - SKETCH_PLANE_COLOR); - aAIS->setColor(aRGB[0], aRGB[1], aRGB[2]); + theFeature->setResult(aResult, theIndex); +} - aAIS->setWidth(Config_PropManager::integer("Sketch planes", "planes_thickness", - SKETCH_WIDTH)); - } - return aAIS; - } - return AISObjectPtr(); +FeaturePtr SketchPlugin_Sketch::addUniqueNamedCopiedFeature(FeaturePtr theFeature, + SketchPlugin_Sketch* theSketch) +{ + 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()); + // as a name for the feature, the generated unique name is set + aNewFeature->data()->setName(aUniqueFeatureName); + // text expressions could block setValue of some attributes + clearExpressions(aNewFeature); + + return aNewFeature; } -void SketchPlugin_Sketch::erase() +std::shared_ptr SketchPlugin_Sketch::plane(SketchPlugin_Sketch* theSketch) { - boost::shared_ptr aRefList = boost::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 = boost::dynamic_pointer_cast(*anIt); - if (aFeature) { - // subs are referenced from sketch, but must be removed for sure, so not checkings - document()->removeFeature(aFeature, false); - } - } - ModelAPI_CompositeFeature::erase(); + 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())); }