X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Sketch.cpp;h=984293083baf47154dfbad362417e2f1509ef07d;hb=9c42741053f277a2903c2385aea645dcad5ab784;hp=368f4452c23ef858864450e0cac50616fd3c1a2d;hpb=6a9eb86984ff6892c0dd95700ee6f37e5235c10e;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp old mode 100755 new mode 100644 index 368f4452c..984293083 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2020 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,18 +12,19 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include #include +#include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include +#include #include #include @@ -249,6 +251,35 @@ bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const } +static bool isOrigin(const GeomPointPtr& thePoint, const double theTolerance) +{ + return fabs(thePoint->x()) < theTolerance && + fabs(thePoint->y()) < theTolerance && + fabs(thePoint->z()) < theTolerance; +} + +static bool isCoordinateAxis(const GeomDirPtr& theDir, const double theTolerance) +{ + return fabs(theDir->x() - 1.0) < theTolerance || fabs(theDir->x() + 1.0) < theTolerance || + fabs(theDir->y() - 1.0) < theTolerance || fabs(theDir->y() + 1.0) < theTolerance || + fabs(theDir->z() - 1.0) < theTolerance || fabs(theDir->z() + 1.0) < theTolerance; +} + +static bool isCoordinatePlane(const GeomAx3Ptr& thePlane) +{ + static const double THE_TOLERANCE = 1.e-7; + if (!thePlane) + return false; + + GeomPointPtr anOrigin = thePlane->origin(); + GeomDirPtr aNormal = thePlane->normal(); + GeomDirPtr aDirX = thePlane->dirX(); + + return isOrigin(anOrigin, THE_TOLERANCE) && + isCoordinateAxis(aNormal, THE_TOLERANCE) && + isCoordinateAxis(aDirX, THE_TOLERANCE); +} + void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { if (theID == SketchPlugin_SketchEntity::EXTERNAL_ID()) { AttributeSelectionPtr aSelAttr = selection(SketchPlugin_SketchEntity::EXTERNAL_ID()); @@ -284,6 +315,7 @@ void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { std::shared_ptr aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir))); std::shared_ptr aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir))); + bool aWasBlocked = data()->blockSendAttributeUpdated(true); // update position of the sketch std::shared_ptr anOrigin = std::dynamic_pointer_cast (data()->attribute(SketchPlugin_Sketch::ORIGIN_ID())); @@ -294,19 +326,33 @@ 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 aDir = aPlane->direction(); + data()->blockSendAttributeUpdated(aWasBlocked, true); } } } } else if (theID == NORM_ID() || theID == DIRX_ID() || theID == ORIGIN_ID()) { + // check if current and previous sketch planes are coordinate planes and they are different + GeomAx3Ptr aCurPlane; + bool areCoordPlanes = false; + if (isPlaneSet()) { + aCurPlane = coordinatePlane(); + areCoordPlanes = isCoordinatePlane(aCurPlane) && isCoordinatePlane(myPlane); + } + // 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()) + if (aSub->get()) { + if (areCoordPlanes) + updateCoordinateAxis(*aSub, aCurPlane); + ModelAPI_EventCreator::get()->sendUpdated(*aSub, anUpdateEvent); + } } + if (aCurPlane) + myPlane = aCurPlane; } } @@ -332,13 +378,42 @@ void SketchPlugin_Sketch::createPoint2DResult(ModelAPI_Feature* theFeature, theFeature->setResult(aResult, theIndex); } +void SketchPlugin_Sketch::createLine2DResult(ModelAPI_Feature* theFeature, + SketchPlugin_Sketch* theSketch, + const std::string& theStartAttrID, + const std::string& theEndAttrID, + const int theIndex) +{ + std::shared_ptr aStartAttr = + std::dynamic_pointer_cast(theFeature->attribute(theStartAttrID)); + std::shared_ptr anEndAttr = + std::dynamic_pointer_cast(theFeature->attribute(theEndAttrID)); + + if (!aStartAttr || !aStartAttr->isInitialized() || + !anEndAttr || !anEndAttr->isInitialized()) + return; + + std::shared_ptr aStart(theSketch->to3D(aStartAttr->x(), aStartAttr->y())); + std::shared_ptr anEnd(theSketch->to3D(anEndAttr->x(), anEndAttr->y())); + //std::cout<<"Execute line "<x()<<" "<y()<<" "<z()<<" - " + // <x()<<" "<y()<<" "<z()< anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd); + // store the result + std::shared_ptr aResult = + theFeature->document()->createConstruction(theFeature->data(), theIndex); + aResult->setShape(anEdge); + 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(); + std::wstring 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 @@ -368,11 +443,164 @@ std::shared_ptr SketchPlugin_Sketch::plane(SketchPlugin_Sketch* the 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())); + if (aNorm.get() && aNorm->isInitialized() && anOrigin.get() && anOrigin->isInitialized()) + return std::shared_ptr( + new GeomAPI_Ax3(anOrigin->pnt(), aDirX->dir(), aNorm->dir())); + + return std::shared_ptr(); +} + +bool SketchPlugin_Sketch::customAction(const std::string& theActionId) +{ + bool isOk = false; + if (theActionId == ACTION_REMOVE_EXTERNAL()) + isOk = removeLinksToExternal(); + else { + std::string aMsg = "Error: Feature \"%1\" does not support action \"%2\"."; + Events_InfoMessage("SketchPlugin_Sketch", aMsg).arg(getKind()).arg(theActionId).send(); + } + return isOk; +} + +static bool isExternalBased(const FeaturePtr theFeature) +{ + return theFeature->getKind() == SketchPlugin_Projection::ID() || + theFeature->getKind() == SketchPlugin_IntersectionPoint::ID(); +} + +bool SketchPlugin_Sketch::removeLinksToExternal() +{ + std::list aRemove; + std::list aSubs = reflist(FEATURES_ID())->list(); + for (std::list::iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (!aFeature) + continue; + if (isExternalBased(aFeature)) { + // mark feature as to be removed + aRemove.push_back(aFeature); + } + else { + AttributeSelectionPtr anExtAttr = + aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID()); + ResultPtr anExternal = anExtAttr ? anExtAttr->context() : ResultPtr(); + if (anExternal) { + FeaturePtr anExtFeature = ModelAPI_Feature::feature(anExternal); + if (anExtFeature && isExternalBased(anExtFeature)) { + // make result of projection/intersection as non-external, + aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID())->setValue( + ObjectPtr(), GeomShapePtr()); + // set feature auxiliary if the parent is not included into sketch result + bool isIncludedToSketchResult = false; + if (anExtFeature->getKind() == SketchPlugin_Projection::ID()) { + isIncludedToSketchResult = anExtFeature->boolean( + SketchPlugin_Projection::INCLUDE_INTO_RESULT())->value(); + } + if (anExtFeature->getKind() == SketchPlugin_IntersectionPoint::ID()) { + isIncludedToSketchResult = anExtFeature->boolean( + SketchPlugin_IntersectionPoint::INCLUDE_INTO_RESULT())->value(); + } + + aFeature->boolean(SketchPlugin_SketchEntity::COPY_ID())->setValue(false); + aFeature->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue( + !isIncludedToSketchResult); + } + } + } + } + for (std::list::iterator anIt = aRemove.begin(); anIt != aRemove.end(); ++anIt) + document()->removeFeature(*anIt); + return true; +} + + +static ObjectPtr findAxis(GeomShapePtr theAxisToCompare, + ObjectPtr theOX, + ObjectPtr theOY, + ObjectPtr theOZ) +{ + if (theAxisToCompare) { + ObjectPtr anAxes[] = { theOX, theOY, theOZ }; + for (int i = 0; i < 3; ++i) { + ResultPtr anAx = std::dynamic_pointer_cast(anAxes[i]); + if (anAx && theAxisToCompare->isEqual(anAx->shape())) + return anAxes[i]; + } + } + return ObjectPtr(); +} + +static ObjectPtr findAxis(ObjectPtr theAxisToCompare, + ObjectPtr theOX, + ObjectPtr theOY, + ObjectPtr theOZ) +{ + if (theAxisToCompare == theOX) + return theOX; + else if (theAxisToCompare == theOY) + return theOY; + else if (theAxisToCompare == theOZ) + return theOZ; + // nothing helped, search by shape + ResultPtr anAxis = std::dynamic_pointer_cast(theAxisToCompare); + return findAxis(anAxis ? anAxis->shape() : GeomShapePtr(), theOX, theOY, theOZ); +} + +GeomShapePtr axisOnNewPlane(ObjectPtr theAxis, GeomAx3Ptr theOldPlane, GeomAx3Ptr theNewPlane) +{ + ResultPtr anAxis = std::dynamic_pointer_cast(theAxis); + if (!anAxis) + return GeomShapePtr(); + + GeomEdgePtr anAxisEdge = anAxis->shape()->edge(); + GeomLinePtr anAxisLine = anAxisEdge->line(); + GeomDirPtr anAxisDir = anAxisLine->direction(); + + double aFirstParam, aLastParam; + anAxisEdge->getRange(aFirstParam, aLastParam); + + if (theOldPlane->dirX()->isParallel(anAxisDir)) + anAxisDir = theNewPlane->dirX(); + else if (theOldPlane->dirY()->isParallel(anAxisDir)) + anAxisDir = theNewPlane->dirY(); + else if (theOldPlane->normal()->isParallel(anAxisDir)) + anAxisDir = theNewPlane->normal(); + + GeomPointPtr aFirstPoint(new GeomAPI_Pnt(aFirstParam * anAxisDir->x(), + aFirstParam * anAxisDir->y(), + aFirstParam * anAxisDir->z())); + GeomPointPtr aLastPoint(new GeomAPI_Pnt(aLastParam * anAxisDir->x(), + aLastParam * anAxisDir->y(), + aLastParam * anAxisDir->z())); + return GeomAlgoAPI_EdgeBuilder::line(aFirstPoint, aLastPoint); } -void SketchPlugin_Sketch::exchangeIDs( - std::shared_ptr theFeature1, std::shared_ptr theFeature2) +void SketchPlugin_Sketch::updateCoordinateAxis(ObjectPtr theSub, GeomAx3Ptr thePlane) { - reflist(SketchPlugin_Sketch::FEATURES_ID())->exchange(theFeature1, theFeature2); + FeaturePtr aFeature = ModelAPI_Feature::feature(theSub); + if (!aFeature) + return; + + DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); + ObjectPtr anOX = aRootDoc->objectByName(ModelAPI_ResultConstruction::group(), L"OX"); + ObjectPtr anOY = aRootDoc->objectByName(ModelAPI_ResultConstruction::group(), L"OY"); + ObjectPtr anOZ = aRootDoc->objectByName(ModelAPI_ResultConstruction::group(), L"OZ"); + + AttributeSelectionPtr anExtFeature; + if (aFeature->getKind() == SketchPlugin_Projection::ID()) + anExtFeature = aFeature->selection(SketchPlugin_Projection::EXTERNAL_FEATURE_ID()); + else if (aFeature->getKind() == SketchPlugin_IntersectionPoint::ID()) + anExtFeature = aFeature->selection(SketchPlugin_IntersectionPoint::EXTERNAL_FEATURE_ID()); + else + return; + + ObjectPtr aContext = anExtFeature->context(); + GeomShapePtr aShape = anExtFeature->value(); + if (!aShape) { // selected object is a construction + ObjectPtr anAxis = findAxis(aContext, anOX, anOY, anOZ); + GeomShapePtr aNewAxis = axisOnNewPlane(anAxis, myPlane, thePlane); + anAxis = findAxis(aNewAxis, anOX, anOY, anOZ); + if (anAxis) + anExtFeature->setValue(anAxis, aShape); + } }