From 534bc25eadaabad4e423ad7bd498550527087d26 Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 27 Mar 2017 16:59:25 +0300 Subject: [PATCH] Issue #2024: Redesign of circle and arc of circle (validate preselected object) Issue #2027: Sketcher Trim Feature (debug) --- src/GeomAPI/GeomAPI.i | 6 + src/GeomAlgoAPI/GeomAlgoAPI.i | 3 + src/ModelAPI/ModelAPI.i | 4 + src/ModelGeomAlgo/ModelGeomAlgo.i | 2 +- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp | 479 ++++++++++-------- src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h | 35 +- src/ModuleBase/ModuleBase_WidgetValidated.cpp | 16 +- src/ModuleBase/ModuleBase_WidgetValidated.h | 27 +- src/ModuleBase/ModuleBase_WidgetValidator.cpp | 24 +- src/ModuleBase/ModuleBase_WidgetValidator.h | 27 + src/PartSet/PartSet_WidgetPoint2d.cpp | 113 ++++- src/PartSet/PartSet_WidgetPoint2d.h | 21 +- src/SketchPlugin/SketchPlugin_Trim.cpp | 171 +++++-- src/SketchPlugin/SketchPlugin_Trim.h | 3 + src/SketchPlugin/Test/TestTrimArc.py | 180 ------- src/SketchPlugin/Test/TestTrimCircle.py | 191 ------- src/SketchPlugin/Test/TestTrimLine.py | 191 ------- 17 files changed, 625 insertions(+), 868 deletions(-) delete mode 100644 src/SketchPlugin/Test/TestTrimArc.py delete mode 100644 src/SketchPlugin/Test/TestTrimCircle.py delete mode 100644 src/SketchPlugin/Test/TestTrimLine.py diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index 02687c259..872232006 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -76,3 +76,9 @@ %include "GeomAPI_XYZ.h" %include "GeomAPI_Trsf.h" %include "GeomAPI_Wire.h" + +%include "std_list.i" +%include "std_set.i" + +%template(PointList) std::list >; +%template(PointSet) std::set >; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI.i b/src/GeomAlgoAPI/GeomAlgoAPI.i index 6ba7fc781..e79c011bd 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI.i +++ b/src/GeomAlgoAPI/GeomAlgoAPI.i @@ -2,6 +2,9 @@ %module GeomAlgoAPI %{ #include "GeomAlgoAPI_swig.h" + + // fix for SWIG v2.0.4 + #define SWIGPY_SLICE_ARG(obj) ((PySliceObject*)(obj)) %} // import other modules diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 7f3b0c19b..ab67ad2ae 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -10,6 +10,9 @@ %{ #include "ModelAPI_swig.h" + + // fix for SWIG v2.0.4 + #define SWIGPY_SLICE_ARG(obj) ((PySliceObject*)(obj)) %} // import other modules @@ -135,6 +138,7 @@ // std::list -> [] %template(StringList) std::list; %template(ObjectList) std::list >; +%template(FeatureList) std::list >; %template(ResultList) std::list >; %template(DocumentList) std::list >; // std::set -> [] diff --git a/src/ModelGeomAlgo/ModelGeomAlgo.i b/src/ModelGeomAlgo/ModelGeomAlgo.i index 93438c9df..e30b2d7c1 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo.i +++ b/src/ModelGeomAlgo/ModelGeomAlgo.i @@ -30,7 +30,7 @@ // shared pointers // For Point2D.method() -%shared_ptr(ModelAPI_Point2D) +%shared_ptr(ModelGeomAlgo_Point2D) // all supported interfaces %include "ModelGeomAlgo_Point2D.h" diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp index ab1d70119..70cd9cb72 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp @@ -31,104 +31,123 @@ #pragma warning(disable : 4996) // for sprintf #endif -namespace ModelGeomAlgo_Point2D { - std::shared_ptr getPointOfRefAttr(ModelAPI_Feature* theFeature, +std::shared_ptr ModelGeomAlgo_Point2D::getPointOfRefAttr( + ModelAPI_Feature* theFeature, const std::string& theAttribute, const std::string& theObjectFeatureKind, const std::string& theObjectFeatureAttribute) - { - std::shared_ptr aPointAttr; - - /// essential check as it is called in openGl thread - if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid()) - return std::shared_ptr(); - - FeaturePtr aFeature; - std::shared_ptr anAttr = std::dynamic_pointer_cast< - ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); - if(anAttr.get() && anAttr->isInitialized()) { - aFeature = ModelAPI_Feature::feature(anAttr->object()); - if (aFeature.get()) { - bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && - !theObjectFeatureAttribute.empty() && - aFeature->getKind() == theObjectFeatureKind; - if(aFeatureOfObjectKind) - aPointAttr = std::dynamic_pointer_cast( - aFeature->data()->attribute(theObjectFeatureAttribute)); - else if (anAttr->attr()) - aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); - } +{ + std::shared_ptr aPointAttr; + + /// essential check as it is called in openGl thread + if (!theFeature || !theFeature->data().get() || !theFeature->data()->isValid()) + return std::shared_ptr(); + + FeaturePtr aFeature; + std::shared_ptr anAttr = std::dynamic_pointer_cast< + ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute)); + if(anAttr.get() && anAttr->isInitialized()) { + aFeature = ModelAPI_Feature::feature(anAttr->object()); + if (aFeature.get()) { + bool aFeatureOfObjectKind = !theObjectFeatureKind.empty() && + !theObjectFeatureAttribute.empty() && + aFeature->getKind() == theObjectFeatureKind; + if(aFeatureOfObjectKind) + aPointAttr = std::dynamic_pointer_cast( + aFeature->data()->attribute(theObjectFeatureAttribute)); + else if (anAttr->attr()) + aPointAttr = std::dynamic_pointer_cast(anAttr->attr()); } - return aPointAttr; } + return aPointAttr; +} - void getPointsOfReference(const std::shared_ptr& theObject, +void ModelGeomAlgo_Point2D::getPointsOfReference( + const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind, const std::string& theObjectFeatureAttribute, const bool isSkipFeatureAttributes) - { - // find by feature - FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject); - - const std::set& aRefsList = theObject->data()->refsToMe(); - std::set::const_iterator aIt; - for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { - std::shared_ptr aAttr = (*aIt); - FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); - if (aRefFeature->getKind() == theReferenceFeatureKind) { - std::list anAttributes = - aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); - std::list::iterator anIter = anAttributes.begin(), aLast = anAttributes.end(); - bool isSkippedAttribute = false; - if (isSkipFeatureAttributes) { - for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) { - AttributeRefAttrPtr aRefAttribute = - std::dynamic_pointer_cast(*anIter); - if (aRefAttribute.get() && !aRefAttribute->isObject()) { - std::shared_ptr aPointAttr = - std::dynamic_pointer_cast(aRefAttribute->attr()); - FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner()); - isSkippedAttribute = aSourceFeature == anAttributeFeature; - } - } - } - if (isSkippedAttribute) - continue; +{ + // find by feature + FeaturePtr aSourceFeature = ModelAPI_Feature::feature(theObject); - // it searches the first point of AttributeRefAtt - std::shared_ptr aPointAttr; - for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) { + const std::set& aRefsList = theObject->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + std::shared_ptr aAttr = (*aIt); + FeaturePtr aRefFeature = std::dynamic_pointer_cast(aAttr->owner()); + if (aRefFeature->getKind() == theReferenceFeatureKind) { + std::list anAttributes = + aRefFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); + std::list::iterator anIter = anAttributes.begin(), aLast = anAttributes.end(); + bool isSkippedAttribute = false; + if (isSkipFeatureAttributes) { + for(anIter = anAttributes.begin(); anIter != aLast && !isSkippedAttribute; anIter++) { AttributeRefAttrPtr aRefAttribute = std::dynamic_pointer_cast(*anIter); - if (aRefAttribute.get()) { - aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(), - theObjectFeatureKind, theObjectFeatureAttribute); + if (aRefAttribute.get() && !aRefAttribute->isObject()) { + std::shared_ptr aPointAttr = + std::dynamic_pointer_cast(aRefAttribute->attr()); + FeaturePtr anAttributeFeature = ModelAPI_Feature::feature(aPointAttr->owner()); + isSkippedAttribute = aSourceFeature == anAttributeFeature; } } - if (aPointAttr.get()) { - theAttributes.insert(aPointAttr); + } + if (isSkippedAttribute) + continue; + + // it searches the first point of AttributeRefAtt + std::shared_ptr aPointAttr; + for(anIter = anAttributes.begin(); anIter != aLast && !aPointAttr.get(); anIter++) { + AttributeRefAttrPtr aRefAttribute = + std::dynamic_pointer_cast(*anIter); + if (aRefAttribute.get()) { + aPointAttr = getPointOfRefAttr(aRefFeature.get(), aRefAttribute->id(), + theObjectFeatureKind, theObjectFeatureAttribute); } } - } - // find by results - FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); - if (aFeature.get()) { - const std::list > aResults = aFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); - for (; aRIter != aResults.cend(); aRIter++) { - ResultPtr aResult = *aRIter; - getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind, - theObjectFeatureAttribute); + if (aPointAttr.get()) { + theAttributes.insert(aPointAttr); } } } + // find by results + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature.get()) { + const std::list > aResults = aFeature->results(); + std::list >::const_iterator aRIter = aResults.begin(); + for (; aRIter != aResults.cend(); aRIter++) { + ResultPtr aResult = *aRIter; + getPointsOfReference(aResult, theReferenceFeatureKind, theAttributes, theObjectFeatureKind, + theObjectFeatureAttribute); + } + } +} - void appendPoint(const std::shared_ptr& thePoint, +void appendPoint(const std::shared_ptr& thePoint, const std::shared_ptr& theResult, - PointToRefsMap& thePointToAttributeOrObject) - { + ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject) +{ + bool aPointFound = false; + FeaturePtr aPointFeature = ModelAPI_Feature::feature(theResult); + // check if the given point is already in the container in attribute list + for (ModelGeomAlgo_Point2D::PointToRefsMap::const_iterator + anIt = thePointToAttributeOrObject.begin(); + anIt != thePointToAttributeOrObject.end() && !aPointFound; anIt++) { + std::shared_ptr aPoint = anIt->first; + if (aPoint->isEqual(thePoint)) { + std::list > anAttributes = anIt->second.first; + for (std::list::const_iterator anAttrIt = anAttributes.begin(); + anAttrIt != anAttributes.end() && !aPointFound; anAttrIt++) { + AttributePtr anAttribute = *anAttrIt; + aPointFound = ModelAPI_Feature::feature(anAttribute->owner()) == aPointFeature; + } + } + } + + if (!aPointFound) { if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end()) thePointToAttributeOrObject.at(thePoint).second.push_back(theResult); else { @@ -138,100 +157,122 @@ namespace ModelGeomAlgo_Point2D { thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects); } } +} - void appendShapePoints(const GeomShapePtr& theShape, - const std::shared_ptr& theResult, - PointToRefsMap& thePointToAttributeOrObject) - { - if (!theShape.get()) - return; +void appendShapePoints(const GeomShapePtr& theShape, + const std::shared_ptr& theResult, + ModelGeomAlgo_Point2D::PointToRefsMap& thePointToAttributeOrObject) +{ + if (!theShape.get()) + return; - switch (theShape->shapeType()) { - case GeomAPI_Shape::VERTEX: { - std::shared_ptr aVertex = - std::shared_ptr(new GeomAPI_Vertex(theShape)); - std::shared_ptr aPnt = aVertex->point(); - appendPoint(aPnt, theResult, thePointToAttributeOrObject); - } - break; - case GeomAPI_Shape::EDGE: { - std::shared_ptr anEdge = - std::shared_ptr(new GeomAPI_Edge(theShape)); - appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject); - appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject); - } - break; - case GeomAPI_Shape::COMPOUND: { - for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) { - appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject); - } + switch (theShape->shapeType()) { + case GeomAPI_Shape::VERTEX: { + std::shared_ptr aVertex = + std::shared_ptr(new GeomAPI_Vertex(theShape)); + std::shared_ptr aPnt = aVertex->point(); + appendPoint(aPnt, theResult, thePointToAttributeOrObject); + } + break; + case GeomAPI_Shape::EDGE: { + std::shared_ptr anEdge = + std::shared_ptr(new GeomAPI_Edge(theShape)); + appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject); + appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject); + } + break; + case GeomAPI_Shape::COMPOUND: { + for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) { + appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject); } - break; - default: break; } + break; + default: break; } +} - void getPointsIntersectedShape(const std::shared_ptr& theBaseFeature, +void ModelGeomAlgo_Point2D::getPointsIntersectedShape(const std::shared_ptr& theBaseFeature, const std::list >& theFeatures, PointToRefsMap& thePointToAttributeOrObject) +{ + GeomShapePtr aFeatureShape; { - GeomShapePtr aFeatureShape; - { + std::set anEdgeShapes; + ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + if (anEdgeShapes.empty()) + return; + aFeatureShape = (*anEdgeShapes.begin())->shape(); + } + + std::list >::const_iterator anIt = theFeatures.begin(), + aLast = theFeatures.end(); + for (; anIt != aLast; anIt++) { + FeaturePtr aFeature = *anIt; + if (aFeature.get() == theBaseFeature.get()) + continue; + if (aFeature.get()) { std::set anEdgeShapes; - ModelGeomAlgo_Shape::shapesOfType(theBaseFeature, GeomAPI_Shape::EDGE, anEdgeShapes); + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); if (anEdgeShapes.empty()) - return; - aFeatureShape = (*anEdgeShapes.begin())->shape(); - } + ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::VERTEX, anEdgeShapes); - std::list >::const_iterator anIt = theFeatures.begin(), - aLast = theFeatures.end(); - for (; anIt != aLast; anIt++) { - FeaturePtr aFeature = *anIt; - if (aFeature.get() == theBaseFeature.get()) + if (anEdgeShapes.empty()) continue; - if (aFeature.get()) { - std::set anEdgeShapes; - ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes); - if (anEdgeShapes.empty()) - continue; - ResultPtr aResult = *anEdgeShapes.begin(); - GeomShapePtr aShape = aResult->shape(); - - GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape); - appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject); - } + ResultPtr aResult = *anEdgeShapes.begin(); + GeomShapePtr aShape = aResult->shape(); + + GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape); + appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject); } } +} + +std::list > ModelGeomAlgo_Point2D::getSetOfPntIntersectedShape( + const std::shared_ptr& theBaseFeature, + const std::list >& theFeatures) +{ + std::list > aPoints; + + PointToRefsMap aRefsMap; + getPointsIntersectedShape(theBaseFeature, theFeatures, aRefsMap); + + for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin(); + aPointIt != aRefsMap.end(); aPointIt++) + aPoints.push_back(aPointIt->first); + + return aPoints; +} - void getPointsInsideShape(const std::shared_ptr theBaseShape, +void ModelGeomAlgo_Point2D::getPointsInsideShape( + const std::shared_ptr theBaseShape, const std::set >& theAttributes, const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, const std::shared_ptr& theDirY, PointToRefsMap& thePointToAttributeOrObject) - { - std::set >::const_iterator anIt = theAttributes.begin(), - aLast = theAttributes.end(); - for (; anIt != aLast; anIt++) { - std::shared_ptr anAttribute = *anIt; - std::shared_ptr aPnt2d = anAttribute->pnt(); - std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); - std::shared_ptr aProjectedPoint; - if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { - if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end()) - thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute); - else { - std::list > anAttributes; - std::list > anObjects; - anAttributes.push_back(anAttribute); - thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects); - } +{ + std::set >::const_iterator anIt = theAttributes.begin(), + aLast = theAttributes.end(); + for (; anIt != aLast; anIt++) { + std::shared_ptr anAttribute = *anIt; + std::shared_ptr aPnt2d = anAttribute->pnt(); + std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); + std::shared_ptr aProjectedPoint; + if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { + if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end()) + thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute); + else { + std::list > anAttributes; + std::list > anObjects; + anAttributes.push_back(anAttribute); + thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects); } } } +} - void getPointsInsideShape_p(const std::shared_ptr theBaseShape, +void ModelGeomAlgo_Point2D::getPointsInsideShape_p( + const std::shared_ptr theBaseShape, const std::set >& theAttributes, const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, @@ -239,93 +280,95 @@ namespace ModelGeomAlgo_Point2D { std::list >& thePoints, std::map, std::shared_ptr >& theAttributeToPoint) - { - std::set >::const_iterator anIt = theAttributes.begin(), - aLast = theAttributes.end(); - for (; anIt != aLast; anIt++) { - std::shared_ptr anAttribute = *anIt; - std::shared_ptr aPnt2d = anAttribute->pnt(); - std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); - std::shared_ptr aProjectedPoint; - if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { - thePoints.push_back(aProjectedPoint); - theAttributeToPoint[anAttribute] = aProjectedPoint; - } +{ + std::set >::const_iterator anIt = theAttributes.begin(), + aLast = theAttributes.end(); + for (; anIt != aLast; anIt++) { + std::shared_ptr anAttribute = *anIt; + std::shared_ptr aPnt2d = anAttribute->pnt(); + std::shared_ptr aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY); + std::shared_ptr aProjectedPoint; + if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) { + thePoints.push_back(aProjectedPoint); + theAttributeToPoint[anAttribute] = aProjectedPoint; } } +} - bool isPointOnEdge(const std::shared_ptr theBaseShape, +bool ModelGeomAlgo_Point2D::isPointOnEdge(const std::shared_ptr theBaseShape, const std::shared_ptr& thePoint, std::shared_ptr& theProjectedPoint) - { - bool isInside = false; - if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { - std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); - if (anEdge->isLine()) { - std::shared_ptr aLine = anEdge->line(); - theProjectedPoint = aLine->project(thePoint); - } - else if (anEdge->isCircle() || anEdge->isArc()) { - std::shared_ptr aCircle = anEdge->circle(); - theProjectedPoint = aCircle->project(thePoint); - } - if (theProjectedPoint.get()) { - std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), - theProjectedPoint->y(), theProjectedPoint->z())); - isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); - } +{ + bool isInside = false; + if (theBaseShape->shapeType() == GeomAPI_Shape::EDGE) { + std::shared_ptr anEdge(new GeomAPI_Edge(theBaseShape)); + if (anEdge->isLine()) { + std::shared_ptr aLine = anEdge->line(); + theProjectedPoint = aLine->project(thePoint); + } + else if (anEdge->isCircle() || anEdge->isArc()) { + std::shared_ptr aCircle = anEdge->circle(); + theProjectedPoint = aCircle->project(thePoint); + } + if (theProjectedPoint.get()) { + std::shared_ptr aVertexShape(new GeomAPI_Vertex(theProjectedPoint->x(), + theProjectedPoint->y(), theProjectedPoint->z())); + isInside = GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aVertexShape, theBaseShape); } - return isInside; } + return isInside; +} - std::string doubleToString(double theValue) - { - std::string aValueStr; - char aBuf[50]; - int n = sprintf(aBuf, "%g", theValue); - aValueStr = std::string(aBuf); - return aValueStr; - } +std::string doubleToString(double theValue) +{ + std::string aValueStr; + char aBuf[50]; + int n = sprintf(aBuf, "%g", theValue); + aValueStr = std::string(aBuf); + return aValueStr; +} #ifdef _DEBUG - std::string getPontAttributesInfo(const std::shared_ptr& theFeature, - const std::set >& theAttributesOnly) - { - std::string anInfo; - - std::list anAttrs = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); - - for(; anIt != aLast; anIt++) { - AttributePtr anAttribute = *anIt; - if (anAttribute.get() && (theAttributesOnly.empty() || - theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) { - if (!anInfo.empty()) { - anInfo.append(", "); - anInfo.append("\n"); - } - anInfo.append(" " + getPointAttributeInfo(anAttribute)); - } +std::string ModelGeomAlgo_Point2D::getPontAttributesInfo( + const std::shared_ptr& theFeature, + const std::set >& theAttributesOnly) +{ + std::string anInfo; + + std::list anAttrs = theFeature->data()->attributes( + GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anIt = anAttrs.begin(), aLast = anAttrs.end(); + + for(; anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + if (anAttribute.get() && (theAttributesOnly.empty() || + theAttributesOnly.find(anAttribute) != theAttributesOnly.end())) { + if (!anInfo.empty()) { + anInfo.append(", "); + anInfo.append("\n"); + } + anInfo.append(" " + getPointAttributeInfo(anAttribute)); } - return anInfo; } + return anInfo; +} - std::string getPointAttributeInfo(const std::shared_ptr& theAttribute) - { - std::string anInfo; - std::string aValue = "not defined"; - std::string aType = theAttribute->attributeType(); - if (aType == GeomDataAPI_Point2D::typeId()) { - std::shared_ptr aPoint = - std::dynamic_pointer_cast(theAttribute); - if (aPoint.get() && aPoint->isInitialized()) { - aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ - doubleToString(aPoint->y()) + ")"); - } +std::string ModelGeomAlgo_Point2D::getPointAttributeInfo( + const std::shared_ptr& theAttribute) +{ + std::string anInfo; + std::string aValue = "not defined"; + std::string aType = theAttribute->attributeType(); + if (aType == GeomDataAPI_Point2D::typeId()) { + std::shared_ptr aPoint = + std::dynamic_pointer_cast(theAttribute); + if (aPoint.get() && aPoint->isInitialized()) { + aValue = std::string("(" + doubleToString(aPoint->x()) + ", "+ + doubleToString(aPoint->y()) + ")"); } - anInfo.append(theAttribute->id() + ": " + aValue); - - return anInfo; } + anInfo.append(theAttribute->id() + ": " + aValue); + + return anInfo; +} #endif -} // namespace ModelGeomAlgo_Point2D diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h index 6e717c10e..15826a20c 100755 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h @@ -24,8 +24,9 @@ class GeomDataAPI_Point2D; #include -namespace ModelGeomAlgo_Point2D { - +class ModelGeomAlgo_Point2D +{ +public: /// Searches Point2D attribute of reference of the attribute of given feature /// \param theFeature a feature to obtain AttributeRefAttr /// \param theAttribute a name of AttributeRefAttr on the given feature @@ -33,7 +34,7 @@ namespace ModelGeomAlgo_Point2D { /// \param theObjectFeatureAttribute a feature attribute in object that satisfies the search /// \param isSkipFeatureAttributes a boolean value if coincidences to the feature attributes /// \returns found point attribute or NULL - MODELGEOMALGO_EXPORT std::shared_ptr getPointOfRefAttr( + static MODELGEOMALGO_EXPORT std::shared_ptr getPointOfRefAttr( ModelAPI_Feature* theFeature, const std::string& theAttribute, const std::string& theObjectFeatureKind = "", @@ -50,7 +51,7 @@ namespace ModelGeomAlgo_Point2D { /// \param isSkipFeatureAttributes a boolean value if coincidences to the feature attributes /// should be skipped /// \returns found point attribute or NULL - MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr& theObject, + static MODELGEOMALGO_EXPORT void getPointsOfReference(const std::shared_ptr& theObject, const std::string& theReferenceFeatureKind, std::set >& theAttributes, const std::string& theObjectFeatureKind = "", @@ -66,11 +67,15 @@ namespace ModelGeomAlgo_Point2D { std::pair >, std::list > > > PointToRefsMap; - MODELGEOMALGO_EXPORT void getPointsIntersectedShape( + static MODELGEOMALGO_EXPORT void getPointsIntersectedShape( const std::shared_ptr& theBaseFeature, const std::list >& theFeatures, PointToRefsMap& thePointToAttributeOrObject); + static MODELGEOMALGO_EXPORT std::list > getSetOfPntIntersectedShape( + const std::shared_ptr& theBaseFeature, + const std::list >& theFeatures); + /// Removes attributes which points are out of the base shape /// \param theBaseShape a shape of check /// \param theAttributes a container of point 2D attributes @@ -79,7 +84,7 @@ namespace ModelGeomAlgo_Point2D { /// \param theDirY plane X direction to generate 3D point by 2D attribute point /// \param thePoints a container of 3D points belong to the shape /// \param theAttributeToPoint a container of attribute to point - MODELGEOMALGO_EXPORT void getPointsInsideShape( + static MODELGEOMALGO_EXPORT void getPointsInsideShape( const std::shared_ptr theBaseShape, const std::set >& theAttributes, const std::shared_ptr& theOrigin, @@ -95,7 +100,7 @@ namespace ModelGeomAlgo_Point2D { /// \param theDirY plane X direction to generate 3D point by 2D attribute point /// \param thePoints a container of 3D points belong to the shape /// \param theAttributeToPoint a container of attribute to point - MODELGEOMALGO_EXPORT void getPointsInsideShape_p( + static MODELGEOMALGO_EXPORT void getPointsInsideShape_p( const std::shared_ptr theBaseShape, const std::set >& theAttributes, const std::shared_ptr& theOrigin, @@ -104,31 +109,31 @@ namespace ModelGeomAlgo_Point2D { std::list >& thePoints, std::map, std::shared_ptr >& theAttributeToPoint); - /// Finds projected point to the given shape line /// \param theBaseShape a shape of check /// \param thePoint [in] a point to project /// \param theProjectedPoint [out] a projected point - MODELGEOMALGO_EXPORT bool isPointOnEdge(const std::shared_ptr theBaseShape, + static MODELGEOMALGO_EXPORT bool isPointOnEdge(const std::shared_ptr theBaseShape, const std::shared_ptr& thePoint, std::shared_ptr& theProjectedPoint); + #ifdef _DEBUG /// Return feature name, kind and point values united in a string info /// \param theFeature an investigated feature /// \param theAttributesOnly a container of necessary attributes, if empty, all /// \return string value - MODELGEOMALGO_EXPORT std::string getPontAttributesInfo( - const std::shared_ptr& theFeature, - const std::set >& theAttributesOnly); + static MODELGEOMALGO_EXPORT std::string getPontAttributesInfo( + const std::shared_ptr& theFeature, + const std::set >& theAttributesOnly); /// Return point attribute string info /// \param theAttribute an investigated attribute /// \return string value - MODELGEOMALGO_EXPORT std::string getPointAttributeInfo( - const std::shared_ptr& theAttribute); + static MODELGEOMALGO_EXPORT std::string getPointAttributeInfo( + const std::shared_ptr& theAttribute); #endif -} +}; #endif diff --git a/src/ModuleBase/ModuleBase_WidgetValidated.cpp b/src/ModuleBase/ModuleBase_WidgetValidated.cpp index 2b18811d7..b2c79c9ac 100644 --- a/src/ModuleBase/ModuleBase_WidgetValidated.cpp +++ b/src/ModuleBase/ModuleBase_WidgetValidated.cpp @@ -191,7 +191,7 @@ bool ModuleBase_WidgetValidated::isValidSelectionCustom(const ModuleBase_ViewerP } //******************************************************************** -bool ModuleBase_WidgetValidated::isValidAttribute(const AttributePtr& theAttribute) const +bool ModuleBase_WidgetValidated::isValidAttribute(const AttributePtr& theAttribute) { SessionPtr aMgr = ModelAPI_Session::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); @@ -233,9 +233,21 @@ void ModuleBase_WidgetValidated::blockAttribute(const AttributePtr& theAttribute bool& isFlushesActived, bool& isAttributeSetInitializedBlocked, bool& isAttributeSendUpdatedBlocked) +{ + blockFeatureAttribute(theAttribute, myFeature, theToBlock, isFlushesActived, + isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked); +} + +//******************************************************************** +void ModuleBase_WidgetValidated::blockFeatureAttribute(const AttributePtr& theAttribute, + const FeaturePtr& theFeature, + const bool& theToBlock, + bool& isFlushesActived, + bool& isAttributeSetInitializedBlocked, + bool& isAttributeSendUpdatedBlocked) { Events_Loop* aLoop = Events_Loop::loop(); - DataPtr aData = myFeature->data(); + DataPtr aData = theFeature->data(); if (theToBlock) { // blocks the flush signals to avoid the temporary objects visualization in the viewer // they should not be shown in order to do not lose highlight by erasing them diff --git a/src/ModuleBase/ModuleBase_WidgetValidated.h b/src/ModuleBase/ModuleBase_WidgetValidated.h index ac8eb89eb..15583f9f0 100644 --- a/src/ModuleBase/ModuleBase_WidgetValidated.h +++ b/src/ModuleBase/ModuleBase_WidgetValidated.h @@ -67,6 +67,27 @@ class MODULEBASE_EXPORT ModuleBase_WidgetValidated : public ModuleBase_ModelWidg /// \return boolean value bool isFilterActivated() const; + /// Block the model flush of update and intialization of attribute + /// \param theAttribute an attribute of blocking + /// \param theFeature a feature + /// \param theToBlock flag whether the model is blocked or unblocked + /// \param isFlushesActived out value if model is blocked, in value if model is unblocked + /// to be used to restore flush state when unblocked + /// \param isAttributeSetInitializedBlocked out value if model is blocked + /// in value if model is unblocked to be used to restore previous state when unblocked + /// \param isAttributeSendUpdatedBlocked out value if model signal is blocked + static void blockFeatureAttribute(const AttributePtr& theAttribute, + const FeaturePtr& theFeature, + const bool& theToBlock, + bool& isFlushesActived, + bool& isAttributeSetInitializedBlocked, + bool& isAttributeSendUpdatedBlocked); + + /// Checks the current attibute in all attribute validators + /// \param theAttribute an attribute to be validated + /// \return true if all validators return that the attribute is valid + static bool isValidAttribute(const AttributePtr& theAttribute); + protected: /// Checks whether all active viewer filters validate the presentation /// \param thePrs a selected presentation in the view @@ -131,12 +152,6 @@ protected: bool& isFlushesActived, bool& isAttributeSetInitializedBlocked, bool& isAttributeSendUpdatedBlocked); -private: - /// Checks the current attibute in all attribute validators - /// \param theAttribute an attribute to be validated - /// \return true if all validators return that the attribute is valid - bool isValidAttribute(const AttributePtr& theAttribute) const; - protected: /// Gets the validity state of the presentation in an internal map. /// Returns true if the valid state of value is stored diff --git a/src/ModuleBase/ModuleBase_WidgetValidator.cpp b/src/ModuleBase/ModuleBase_WidgetValidator.cpp index 35d8fca62..d6c9d9f0f 100755 --- a/src/ModuleBase/ModuleBase_WidgetValidator.cpp +++ b/src/ModuleBase/ModuleBase_WidgetValidator.cpp @@ -1,6 +1,8 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D #include +#include +#include #include #include @@ -9,12 +11,14 @@ ModuleBase_WidgetValidator::ModuleBase_WidgetValidator(ModuleBase_ModelWidget* theModelWidget, ModuleBase_IWorkshop* theWorkshop) -: myModelWidget(theModelWidget), myWorkshop(theWorkshop) +: myModelWidget(theModelWidget), myWorkshop(theWorkshop), myIsInValidate(false) { + myAttributeStore = new ModuleBase_WidgetSelectorStore(); } ModuleBase_WidgetValidator::~ModuleBase_WidgetValidator() { + delete myAttributeStore; } //******************************************************************** @@ -47,6 +51,24 @@ bool ModuleBase_WidgetValidator::activateFilters(const bool toActivate) return aHasSelectionFilter; } +void ModuleBase_WidgetValidator::storeAttributeValue(const AttributePtr& theAttribute) +{ + myIsInValidate = true; + myAttributeStore->storeAttributeValue(theAttribute, myWorkshop); +} + +void ModuleBase_WidgetValidator::restoreAttributeValue(const AttributePtr& theAttribute, + const bool theValid) +{ + myIsInValidate = false; + myAttributeStore->restoreAttributeValue(theAttribute, myWorkshop); +} + +bool ModuleBase_WidgetValidator::isValidAttribute(const AttributePtr& theAttribute) const +{ + return ModuleBase_WidgetValidated::isValidAttribute(theAttribute); +} + bool ModuleBase_WidgetValidator::isFilterActivated() const { bool isActivated = false; diff --git a/src/ModuleBase/ModuleBase_WidgetValidator.h b/src/ModuleBase/ModuleBase_WidgetValidator.h index ee8d6151b..d159fdad9 100755 --- a/src/ModuleBase/ModuleBase_WidgetValidator.h +++ b/src/ModuleBase/ModuleBase_WidgetValidator.h @@ -13,9 +13,12 @@ #include #include +class ModelAPI_Attribute; + class ModuleBase_ModelWidget; class ModuleBase_IWorkshop; class ModuleBase_ViewerPrs; +class ModuleBase_WidgetSelectorStore; /** * \ingroup GUI @@ -31,6 +34,9 @@ class MODULEBASE_EXPORT ModuleBase_WidgetValidator ModuleBase_IWorkshop* theWorkshop); virtual ~ModuleBase_WidgetValidator(); + /// Returns true if the validation is activated + bool isInValidate() const { return myIsInValidate; } + /// Checks all widget validator if the owner is valid. Firstly it checks custom widget validating, /// next, the attribute's validating. It trying on the give selection to current attribute by /// setting the value inside and calling validators. After this, the previous attribute value is @@ -44,6 +50,25 @@ class MODULEBASE_EXPORT ModuleBase_WidgetValidator /// \return true if the selection filter of the widget is activated in viewer context bool activateFilters(const bool toActivate); + /// Creates a backup of the current values of the attribute + /// It should be realized in the specific widget because of different + /// parameters of the current attribute + /// \param theAttribute an attribute to be stored + virtual void storeAttributeValue(const std::shared_ptr& theAttribute); + + /// Creates a backup of the current values of the attribute + /// It should be realized in the specific widget because of different + /// parameters of the current attribute + /// \param theAttribute an attribute to be restored + /// \param theValid a boolean flag, if restore happens for valid parameters + virtual void restoreAttributeValue(const std::shared_ptr& theAttribute, + const bool theValid); + + /// Checks the current attibute in all attribute validators + /// \param theAttribute an attribute to be validated + /// \return true if all validators return that the attribute is valid + bool isValidAttribute(const std::shared_ptr& theAttribute) const; + private: /// Returns true if the workshop validator filter has been already activated /// \return boolean value @@ -64,9 +89,11 @@ private: void storeValidState(const std::shared_ptr& theValue, const bool theValid); protected: + bool myIsInValidate; ///< cashed if the value is processed in validation /// Reference to workshop ModuleBase_ModelWidget* myModelWidget; ///< the current widget to be validated ModuleBase_IWorkshop* myWorkshop; ///< the active workshop + ModuleBase_WidgetSelectorStore* myAttributeStore; //< store/restore attribute values /// cash of valid selection presentations QList> myValidPrs; diff --git a/src/PartSet/PartSet_WidgetPoint2d.cpp b/src/PartSet/PartSet_WidgetPoint2d.cpp index cf095fe0c..d82e457a8 100644 --- a/src/PartSet/PartSet_WidgetPoint2d.cpp +++ b/src/PartSet/PartSet_WidgetPoint2d.cpp @@ -20,12 +20,14 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -158,7 +160,9 @@ bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr return true; AttributeRefAttrPtr aRefAttr = attributeRefAttr(); - if (!aRefAttr.get()) { + if (aRefAttr.get()) + return isValidSelectionForAttribute_(theValue, myFeature->attribute(attributeID())); + else { bool aFoundPoint = false; /// Avoid coincidence build to passed point. Coincidence is build later only if there are no /// reference attribute. @@ -185,6 +189,55 @@ bool PartSet_WidgetPoint2D::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr return true; } +//******************************************************************** +bool PartSet_WidgetPoint2D::isValidSelectionForAttribute_( + const ModuleBase_ViewerPrsPtr& theValue, + const AttributePtr& theAttribute) +{ + bool aValid = false; + + // stores the current values of the widget attribute + bool isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked; + + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttr, myFeature, true, + isFlushesActived, isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked); + myWidgetValidator->storeAttributeValue(aRefAttr); + + // saves the owner value to the widget attribute + aValid = setSelectionCustom(theValue); + if (aValid) + // checks the attribute validity + aValid = myWidgetValidator->isValidAttribute(theAttribute); + + // restores the current values of the widget attribute + myWidgetValidator->restoreAttributeValue(aRefAttr, aValid); + + ModuleBase_WidgetValidated::blockFeatureAttribute(aRefAttr, myFeature, false, isFlushesActived, + isAttributeSetInitializedBlocked, isAttributeSendUpdatedBlocked); + return aValid; +} + +bool PartSet_WidgetPoint2D::setSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) +{ + bool isDone = false; + GeomShapePtr aShape = theValue->shape(); + if (aShape.get() && !aShape->isNull()) { + Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); + double aX, aY; + const TopoDS_Shape& aTDShape = aShape->impl(); + if (getPoint2d(aView, aTDShape, aX, aY)) { + fillRefAttribute(aX, aY); + isDone = true; + } + else if (aTDShape.ShapeType() == TopAbs_EDGE) { + fillRefAttribute(theValue->object()); + isDone = true; + } + } + return isDone; +} + bool PartSet_WidgetPoint2D::resetCustom() { bool aDone = false; @@ -404,23 +457,25 @@ bool PartSet_WidgetPoint2D::getPoint2d(const Handle(V3d_View)& theView, bool PartSet_WidgetPoint2D::setConstraintToPoint(double theClickedX, double theClickedY) { - FeaturePtr aFeature = feature(); - std::string anAttribute = attributeID(); - - if (!aFeature.get()) - return false; - - std::shared_ptr aClickedPoint = std::shared_ptr( - new GeomAPI_Pnt2d(theClickedX, theClickedY)); - AttributePoint2DPtr aClickedFeaturePoint = findFirstEqualPointInSketch(mySketch, - aFeature, aClickedPoint); - if (!aClickedFeaturePoint.get()) - return false; - AttributeRefAttrPtr aRefAttr = attributeRefAttr(); if (aRefAttr.get()) - aRefAttr->setAttr(aClickedFeaturePoint); + fillRefAttribute(theClickedX, theClickedY); else { + FeaturePtr aFeature = feature(); + std::string anAttribute = attributeID(); + + if (!aFeature.get()) + return false; + + std::shared_ptr aClickedPoint = std::shared_ptr( + new GeomAPI_Pnt2d(theClickedX, theClickedY)); + AttributePoint2DPtr aClickedFeaturePoint = findFirstEqualPointInSketch(mySketch, + aFeature, aClickedPoint); + if (!aClickedFeaturePoint.get()) + return false; + + // aRefAttr->setAttr(aClickedFeaturePoint); + //else { // find a feature point by the selection mode AttributePoint2DPtr aFeaturePoint; if (aFeature->isMacro()) { @@ -444,7 +499,7 @@ bool PartSet_WidgetPoint2D::setConstraintToObject(const ObjectPtr& theObject) { AttributeRefAttrPtr aRefAttr = attributeRefAttr(); if (aRefAttr.get()) { - aRefAttr->setObject(theObject); + fillRefAttribute(theObject); } else { AttributePoint2DPtr aFeaturePoint; @@ -801,6 +856,32 @@ AttributeRefAttrPtr PartSet_WidgetPoint2D::attributeRefAttr() const return std::dynamic_pointer_cast(anAttributeRef); } +void PartSet_WidgetPoint2D::fillRefAttribute(double theClickedX, double theClickedY) +{ + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (!aRefAttr.get()) + return; + + FeaturePtr aFeature = feature(); + std::string anAttribute = attributeID(); + + if (aFeature.get()) { + std::shared_ptr aClickedPoint = std::shared_ptr( + new GeomAPI_Pnt2d(theClickedX, theClickedY)); + AttributePoint2DPtr aClickedFeaturePoint = findFirstEqualPointInSketch(mySketch, + aFeature, aClickedPoint); + if (aClickedFeaturePoint.get()) + aRefAttr->setAttr(aClickedFeaturePoint); + } +} + +void PartSet_WidgetPoint2D::fillRefAttribute(const ObjectPtr& theObject) +{ + AttributeRefAttrPtr aRefAttr = attributeRefAttr(); + if (aRefAttr.get()) + aRefAttr->setObject(theObject); +} + std::shared_ptr PartSet_WidgetPoint2D::findFirstEqualPointInArgumentFeatures( const FeaturePtr& theFeature, const std::shared_ptr& thePoint) { diff --git a/src/PartSet/PartSet_WidgetPoint2d.h b/src/PartSet/PartSet_WidgetPoint2d.h index 679813437..45841941a 100755 --- a/src/PartSet/PartSet_WidgetPoint2d.h +++ b/src/PartSet/PartSet_WidgetPoint2d.h @@ -1,4 +1,4 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D // File: PartSet_WidgetPoint2d.h // Created: 25 Apr 2014 @@ -58,6 +58,19 @@ Q_OBJECT /// \return a boolean value virtual bool isValidSelectionCustom(const std::shared_ptr& theValue); + /// Checks all attribute validators returns valid. It tries on the given selection + /// to current attribute by setting the value inside and calling validators. After this, + /// the previous attribute value is restored.The valid/invalid value is cashed. + /// \param theValue a selected presentation in the view + /// \param theAttribute the attribute + /// \return a boolean value + bool isValidSelectionForAttribute_(const std::shared_ptr& theValue, + const std::shared_ptr& theAttribute); + + /// Fills the attribute with the value of the selected owner + /// \param thePrs a selected owner + bool setSelectionCustom(const std::shared_ptr& theValue); + /// Set the given wrapped value to the current widget /// This value should be processed in the widget according to the needs /// \param theValues the wrapped widget values @@ -233,6 +246,12 @@ protected: /// \return found attribute or null std::shared_ptr attributeRefAttr() const; + /// Finds first equal point attribute in sketch and set it to reference attribute + /// \param theClickedX the horizontal coordnate of the point + /// \param theClickedY the vertical coordnate of the point + void fillRefAttribute(double theClickedX, double theClickedY); + void fillRefAttribute(const ObjectPtr& theObject); + protected: ModuleBase_IWorkshop* myWorkshop; ///< workshop diff --git a/src/SketchPlugin/SketchPlugin_Trim.cpp b/src/SketchPlugin/SketchPlugin_Trim.cpp index 5a6f4e1ee..f45bb609f 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.cpp +++ b/src/SketchPlugin/SketchPlugin_Trim.cpp @@ -110,19 +110,28 @@ void SketchPlugin_Trim::findShapePoints(const std::string& theObjectAttributeId, if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) { std::shared_ptr anEdge(new GeomAPI_Edge(aBaseShape)); - aStartPoint = anEdge->lastPoint(); - aLastPoint = anEdge->firstPoint(); + //GeomAPI_Shape::Orientation anOrientation = anEdge->orientation(); + //if (anOrientation == GeomAPI_Shape::REVERSED) { + aStartPoint = anEdge->lastPoint(); + aLastPoint = anEdge->firstPoint(); + //} + //else { + //aStartPoint = anEdge->firstPoint(); + //aLastPoint = anEdge->lastPoint(); + //} } } } } #ifdef DEBUG_TRIM std::cout << " => " - << "Start Point: [" - << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]" - << "Last Point: [" - << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]" - << std::endl; + << std::endl << "Attribute point: " + << anAttributePnt->x() << ", " << anAttributePnt->y() << ", " << anAttributePnt->z() << "]" + << std::endl << "Start Point: [" + << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]" + << std::endl << "Last Point: [" + << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]" + << std::endl; #endif } @@ -150,8 +159,7 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( aFound = true; } else { - std::shared_ptr aPlane = sketch()->plane(); - aPoint = thePoint->to2D(aPlane); + aPoint = sketch()->to2D(thePoint); aFound = true; } } @@ -159,8 +167,7 @@ std::shared_ptr SketchPlugin_Trim::convertPoint( if (!aFound) { // returns an end of the shape to define direction of split if feature's attribute // participates - std::shared_ptr aPlane = sketch()->plane(); - aPoint = thePoint->to2D(aPlane); + aPoint = sketch()->to2D(thePoint); } return aPoint; } @@ -189,7 +196,11 @@ void SketchPlugin_Trim::execute() /// points of trim std::shared_ptr aStartShapePoint, aLastShapePoint; +#ifdef DEBUG_TRIM + std::cout << " Base Feature: " << aBaseFeature->data()->name() << std::endl; +#endif findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint); + std::shared_ptr aStartShapePoint2d = convertPoint(aStartShapePoint); std::shared_ptr aLastShapePoint2d = convertPoint(aLastShapePoint); @@ -201,7 +212,6 @@ void SketchPlugin_Trim::execute() std::list aRefsToFeature; getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature); - // coincidence to result points // find coincidences to the base object, it should be used when attribute is found // in myObjectToPoints @@ -237,17 +247,29 @@ void SketchPlugin_Trim::execute() aFurtherCoincidences, aModifiedAttributes); } - // + // constraints to end points of trim feature if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end()) fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints); + // create coincidence to objects, intersected the base object const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject); - std::set::const_iterator anIt = aFurtherCoincidences.begin(), - aLast = aFurtherCoincidences.end(); - for (; anIt != aLast; anIt++) { + for (std::set::const_iterator anIt = aFurtherCoincidences.begin(), + aLast = aFurtherCoincidences.end(); + anIt != aLast; anIt++) { AttributePoint2DPtr aPointAttribute = (*anIt); std::shared_ptr aPoint2d = aPointAttribute->pnt(); +#ifdef DEBUG_TRIM + std::cout << " => " + << "aPoint2d: [" << aPoint2d->x() << ", " << aPoint2d->y() << "]" << std::endl; + if (aStartShapePoint2d.get()) + std::cout << "Start Point: [" << aStartShapePoint2d->x() << ", " << aStartShapePoint2d->y() + << "]" << std::endl; + if (aLastShapePoint2d.get()) + std::cout << "Last Point: [" << aLastShapePoint2d->x() << ", " << aLastShapePoint2d->y() + << "]" << std::endl; +#endif + std::shared_ptr aPoint; if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d)) aPoint = aStartShapePoint; @@ -266,7 +288,7 @@ void SketchPlugin_Trim::execute() break; } } - const std::list& anAttributes = anInfo.first; + /*const std::list& anAttributes = anInfo.first; for (std::list::const_iterator anAttrIt = anAttributes.begin(); anAttrIt != anAttributes.end(); anAttrIt++) { AttributePtr anAttribute = *anAttrIt; @@ -288,7 +310,7 @@ void SketchPlugin_Trim::execute() aRefAttr->setAttr(aPointAttribute); } } - + */ const std::list& anObjects = anInfo.second; for (std::list::const_iterator anObjectIt = anObjects.begin(); anObjectIt != anObjects.end(); anObjectIt++) { @@ -299,23 +321,28 @@ void SketchPlugin_Trim::execute() // move constraints from base feature to replacing feature: ignore coincidences to feature // if attributes of coincidence participated in split + ResultPtr aReplacingResult; if (aReplacingFeature.get()) { - ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature); - std::list::const_iterator anIt = aRefsToFeature.begin(), - aLast = aRefsToFeature.end(); - for (; anIt != aLast; anIt++) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anIt); - if (!aRefAttr.get()) - continue; - FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner()); - if (anAttrFeature.get() && - anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) - { - if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr || - anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr) - continue; + aReplacingFeature->execute(); // need it to obtain result + aReplacingResult = getFeatureResult(aReplacingFeature); + } + for(std::list::const_iterator anIt = aRefsToFeature.begin(), + aLast = aRefsToFeature.end(); + anIt != aLast; anIt++) { + AttributePtr anAttribute = *anIt; + if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences)) + continue; + + if (aReplacingResult.get()) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttribute); + if (aRefAttr.get()) + aRefAttr->setObject(aReplacingResult); + else { + AttributeReferencePtr aReferenceAttr = + std::dynamic_pointer_cast(anAttribute); + if (aReferenceAttr.get()) + aReferenceAttr->setObject(aReplacingResult); } - aRefAttr->setObject(aReplacingResult); } } @@ -350,6 +377,54 @@ void SketchPlugin_Trim::execute() #endif } +bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute, + const std::set& theFurtherCoincidences) +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID()) + return false; + + AttributePoint2DPtr aRefPointAttr = SketchPlugin_ConstraintCoincidence::getPoint(aFeature); + if (!aRefPointAttr.get()) + return false; + std::shared_ptr aRefPnt2d = aRefPointAttr->pnt(); + + std::set::const_iterator anIt = theFurtherCoincidences.begin(), + aLast = theFurtherCoincidences.end(); + bool aFoundPoint = false; + for (; anIt != aLast && !aFoundPoint; anIt++) { + AttributePoint2DPtr aPointAttribute = (*anIt); + std::shared_ptr aPoint2d = aPointAttribute->pnt(); + if (aPoint2d->isEqual(aRefPnt2d)) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + theAttribute); + /*if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_A()) + aRefAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B())); + else if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_B()) + aRefAttr = std::dynamic_pointer_cast( + aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));*/ + if (aRefAttr.get()) { + aRefAttr->setAttr(aPointAttribute); + aFoundPoint = true; + } + } + } + /*AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + if (!aRefAttr.get()) + return false; + + if (aRefAttr.get()) + aRefAttr->setObject(aReplacingResult);//continue; + else { + //AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anIt); + AttributeReferencePtr aReferenceAttr = + std::dynamic_pointer_cast(anAttribute); + }*/ + + return aFoundPoint; +} + bool SketchPlugin_Trim::isMacro() const { return true; @@ -542,20 +617,22 @@ void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject, anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()); } else { - aRefAttr = std::dynamic_pointer_cast + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B())); if (aRefAttr->isObject() && aRefAttr->object() == theObject) - { anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()); - } - if (anAttribute.get()) - { - aRefAttr = std::dynamic_pointer_cast - (anAttribute); - anAttribute = aRefAttr->attr(); - if (anAttribute.get()) - theCoincidencesToBaseFeature[anAttribute] = aRefFeature; - } + } + if (!anAttribute.get()) + continue; + + aRefAttr = std::dynamic_pointer_cast(anAttribute); + if (aRefAttr->isObject()) + continue; // one of attributes of coincidence contains link to an attribute + + anAttribute = aRefAttr->attr(); + if (anAttribute.get()) + { + theCoincidencesToBaseFeature[anAttribute] = aRefFeature; } } } @@ -754,6 +831,7 @@ void SketchPlugin_Trim::trimArc(const std::shared_ptr& theStartSh (aBaseFeature->attribute(aModifiedAttribute))); // equal Radius constraint for arcs + anArcFeature->execute(); // we need the created arc result to set equal constraint createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(), getFeatureResult(aBaseFeature), getFeatureResult(anArcFeature)); @@ -781,6 +859,8 @@ FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr& t /// trim feature FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint); + // arc created by trim of circle is always correct, that means that it is not inversed + anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false); theModifiedAttributes.insert( std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()), @@ -927,7 +1007,6 @@ FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature return aFeature; } - FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, const std::shared_ptr& theFirstPoint, const std::shared_ptr& theSecondPoint) @@ -965,7 +1044,7 @@ FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature, bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value(); aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed); } - aFeature->execute(); // to obtain result + //aFeature->execute(); // to obtain result aFeature->data()->blockSendAttributeUpdated(aWasBlocked); return aFeature; diff --git a/src/SketchPlugin/SketchPlugin_Trim.h b/src/SketchPlugin/SketchPlugin_Trim.h index db43d5fa6..6928c3b96 100644 --- a/src/SketchPlugin/SketchPlugin_Trim.h +++ b/src/SketchPlugin/SketchPlugin_Trim.h @@ -89,6 +89,9 @@ class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentab /// Moves the feature : Empty SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY) {}; + bool setCoincidenceToAttribute(const AttributePtr& theAttribute, + const std::set >& theFurtherCoincidences); + typedef std::map, std::pair >, std::list > > > PointToRefsMap; diff --git a/src/SketchPlugin/Test/TestTrimArc.py b/src/SketchPlugin/Test/TestTrimArc.py deleted file mode 100644 index 24c24ed3a..000000000 --- a/src/SketchPlugin/Test/TestTrimArc.py +++ /dev/null @@ -1,180 +0,0 @@ -from salome.shaper import model - -from ModelAPI import * -from GeomDataAPI import * -from salome.shaper import geom -import math - -TOLERANCE = 1.e-7 - -SketchPointId = 'SketchPoint' -SketchLineId = 'SketchLine' -SketchArcId = 'SketchArc' -SketchCircleId = 'SketchCircle' -SketchConstraintCoincidenceId = 'SketchConstraintCoincidence' -SketchConstraintMirrorId = 'SketchConstraintMirror' -SketchConstraintTangentId = 'SketchConstraintTangent' -SketchConstraintEqualId = 'SketchConstraintEqual' - -model.begin() -partSet = model.moduleDocument() -Part_1 = model.addPart(partSet) -Part_1_doc = Part_1.document() - -# Test1:begin split on circle with coincident point and intersection line : smaller part -Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchArc_1_1 = Sketch_1.addArc(50, 50, 55, 70, 30, 45, True) -SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30) -SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30) - -SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchArc_1_1.results()[1]) -SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint()) -GeomPoint_1_1 = geom.Pnt2d(60, 35) - -#check number of features before trim -Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature()) -idList_before_1 = [] -for index in range(Sketch_1_feature.numberOfSubs()): - idList_before_1.append(Sketch_1_feature.subFeature(index).getKind()) -assert(idList_before_1.count(SketchArcId) == 1) -assert(idList_before_1.count(SketchLineId) == 2) -assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2) -assert(idList_before_1.count(SketchConstraintEqualId) == 0) - -#perform trim -SketchTrim_1_1 = Sketch_1.addTrim(SketchArc_1_1, GeomPoint_1_1) -SketchTrim_1_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_1.feature()) -idList_after_1 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_1.append(SubFeature.getKind()) - -assert(idList_after_1.count(SketchArcId) == 2) -assert(idList_after_1.count(SketchLineId) == 2) -aCount = idList_after_1.count(SketchConstraintCoincidenceId) - -assert(idList_after_1.count(SketchConstraintCoincidenceId) == 4) -assert(idList_after_1.count(SketchConstraintEqualId) == 1) -# Test1:end - -# Test2: split on circle with coincident point and intersection line : largest part -Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -move_test_delta_y = 100 -move_test_delta_x = 0 -SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20) -SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y) -SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y) - -SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1]) -SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint()) -GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y) - -#check number of features before trim -Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature()) -idList_before_2 = [] -for index in range(Sketch_2_feature.numberOfSubs()): - idList_before_2.append(Sketch_2_feature.subFeature(index).getKind()) -assert(idList_before_2.count(SketchCircleId) == 1) -assert(idList_before_2.count(SketchArcId) == 0) -assert(idList_before_2.count(SketchLineId) == 2) -assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2) - -#perform trim -SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1) -SketchTrim_2_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_2.feature()) -idList_after_2 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_2.append(SubFeature.getKind()) - if SubFeature.getKind() == SketchArcId: - ArcFeature_2 = SubFeature - - -assert(idList_after_2.count(SketchCircleId) == 0) -assert(idList_after_2.count(SketchArcId) == 1) -assert(idList_after_2.count(SketchLineId) == 2) -assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3) - -#test created arc : it is not inversed, has coincidence to start line point -anInversed_2 = ArcFeature_2.boolean("InversedArc").value() -assert(anInversed_2 == False) -ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint")) -LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint()) -aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y()) -#print "Distance " + repr(aDistance_2) -assert (math.fabs(aDistance_2) <= TOLERANCE) -# Test2:end - - -# Test3: constraints to circle -Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25) -SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30) -SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30) -SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100) -SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20) -aSketchPoint_3 = Sketch_3.addPoint(145, 70) -SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70) - -SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1]) -SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint()) -GeomPoint_3_1 = geom.Pnt2d(165, 40) - -#Constraints -aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50) -aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]) -aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25) -aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0]) -aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0]) - -MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]] -aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3) - -#check number of features before trim -Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature()) -idList_before_3 = [] -for index in range(Sketch_3_feature.numberOfSubs()): - idList_before_3.append(Sketch_3_feature.subFeature(index).getKind()) - -assert(idList_before_3.count(SketchCircleId) == 4) -assert(idList_before_3.count(SketchArcId) == 0) -assert(idList_before_3.count(SketchLineId) == 4) -assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_before_3.count(SketchConstraintMirrorId) == 1) -assert(idList_before_3.count(SketchConstraintTangentId) == 1) -assert(idList_before_3.count(SketchConstraintEqualId) == 1) - -#perform trim -SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1) -SketchTrim_3_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_3.feature()) -idList_after_3 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_3.append(SubFeature.getKind()) - - -assert(idList_after_3.count(SketchCircleId) == 3) -assert(idList_after_3.count(SketchArcId) == 1) -assert(idList_after_3.count(SketchLineId) == 4) -assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_after_3.count(SketchConstraintMirrorId) == 0) -assert(idList_after_3.count(SketchConstraintTangentId) == 1) -assert(idList_after_3.count(SketchConstraintEqualId) == 1) -# Test3:end - - -model.end() - -#assert(model.checkPythonDump()) diff --git a/src/SketchPlugin/Test/TestTrimCircle.py b/src/SketchPlugin/Test/TestTrimCircle.py deleted file mode 100644 index b8acec087..000000000 --- a/src/SketchPlugin/Test/TestTrimCircle.py +++ /dev/null @@ -1,191 +0,0 @@ -from salome.shaper import model - -from ModelAPI import * -from GeomDataAPI import * -from salome.shaper import geom -import math - -TOLERANCE = 1.e-7 - -SketchPointId = 'SketchPoint' -SketchLineId = 'SketchLine' -SketchArcId = 'SketchArc' -SketchCircleId = 'SketchCircle' -SketchConstraintCoincidenceId = 'SketchConstraintCoincidence' -SketchConstraintMirrorId = 'SketchConstraintMirror' -SketchConstraintTangentId = 'SketchConstraintTangent' -SketchConstraintEqualId = 'SketchConstraintEqual' - -model.begin() -partSet = model.moduleDocument() -Part_1 = model.addPart(partSet) -Part_1_doc = Part_1.document() - -# Test1:begin split on circle with coincident point and intersection line : smaller part -Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchCircle_1_1 = Sketch_1.addCircle(50, 50, 20) -SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30) -SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30) - -SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchCircle_1_1.results()[1]) -SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint()) -GeomPoint_1_1 = geom.Pnt2d(60, 35) - -#check number of features before trim -Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature()) -idList_before_1 = [] -for index in range(Sketch_1_feature.numberOfSubs()): - idList_before_1.append(Sketch_1_feature.subFeature(index).getKind()) -assert(idList_before_1.count(SketchCircleId) == 1) -assert(idList_before_1.count(SketchArcId) == 0) -assert(idList_before_1.count(SketchLineId) == 2) -assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2) - -#perform trim -SketchTrim_1_1 = Sketch_1.addTrim(SketchCircle_1_1, GeomPoint_1_1) -SketchTrim_1_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_1.feature()) -idList_after_1 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_1.append(SubFeature.getKind()) - if SubFeature.getKind() == SketchArcId: - ArcFeature_1 = SubFeature - - -assert(idList_after_1.count(SketchCircleId) == 0) -assert(idList_after_1.count(SketchArcId) == 1) -assert(idList_after_1.count(SketchLineId) == 2) -assert(idList_after_1.count(SketchConstraintCoincidenceId) == 3) - -#test created arc: it is not inversed, has coincidence to end line point -anInversed_1 = ArcFeature_1.boolean("InversedArc").value() -assert(anInversed_1 == False) -ArcPoint_1 = geomDataAPI_Point2D(ArcFeature_1.attribute("ArcEndPoint")) -LinePoint_1 = geomDataAPI_Point2D(SketchLine_1_1.startPoint()) -aDistance_1 = math.hypot(LinePoint_1.x() - ArcPoint_1.x(), LinePoint_1.y() - ArcPoint_1.y()) -#print "Distance " + repr(aDistance) -assert (math.fabs(aDistance_1) <= TOLERANCE) -# Test1:end - - -# Test2: split on circle with coincident point and intersection line : largest part -Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -move_test_delta_y = 100 -move_test_delta_x = 0 -SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20) -SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y) -SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y) - -SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1]) -SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint()) -GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y) - -#check number of features before trim -Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature()) -idList_before_2 = [] -for index in range(Sketch_2_feature.numberOfSubs()): - idList_before_2.append(Sketch_2_feature.subFeature(index).getKind()) -assert(idList_before_2.count(SketchCircleId) == 1) -assert(idList_before_2.count(SketchArcId) == 0) -assert(idList_before_2.count(SketchLineId) == 2) -assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2) - -#perform trim -SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1) -SketchTrim_2_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_2.feature()) -idList_after_2 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_2.append(SubFeature.getKind()) - if SubFeature.getKind() == SketchArcId: - ArcFeature_2 = SubFeature - - -assert(idList_after_2.count(SketchCircleId) == 0) -assert(idList_after_2.count(SketchArcId) == 1) -assert(idList_after_2.count(SketchLineId) == 2) -assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3) - -#test created arc : it is not inversed, has coincidence to start line point -anInversed_2 = ArcFeature_2.boolean("InversedArc").value() -assert(anInversed_2 == False) -ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint")) -LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint()) -aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y()) -#print "Distance " + repr(aDistance_2) -assert (math.fabs(aDistance_2) <= TOLERANCE) -# Test2:end - - -# Test3: constraints to circle -Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25) -SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30) -SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30) -SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100) -SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20) -aSketchPoint_3 = Sketch_3.addPoint(145, 70) -SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70) - -SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1]) -SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint()) -GeomPoint_3_1 = geom.Pnt2d(165, 40) - -#Constraints -aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50) -aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]) -aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25) -aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0]) -aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0]) - -MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]] -aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3) - -#check number of features before trim -Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature()) -idList_before_3 = [] -for index in range(Sketch_3_feature.numberOfSubs()): - idList_before_3.append(Sketch_3_feature.subFeature(index).getKind()) - -assert(idList_before_3.count(SketchCircleId) == 4) -assert(idList_before_3.count(SketchArcId) == 0) -assert(idList_before_3.count(SketchLineId) == 4) -assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_before_3.count(SketchConstraintMirrorId) == 1) -assert(idList_before_3.count(SketchConstraintTangentId) == 1) -assert(idList_before_3.count(SketchConstraintEqualId) == 1) - -#perform trim -SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1) -SketchTrim_3_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_3.feature()) -idList_after_3 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_3.append(SubFeature.getKind()) - - -assert(idList_after_3.count(SketchCircleId) == 3) -assert(idList_after_3.count(SketchArcId) == 1) -assert(idList_after_3.count(SketchLineId) == 4) -assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_after_3.count(SketchConstraintMirrorId) == 0) -assert(idList_after_3.count(SketchConstraintTangentId) == 1) -assert(idList_after_3.count(SketchConstraintEqualId) == 1) -# Test3:end - - -model.end() - -#assert(model.checkPythonDump()) diff --git a/src/SketchPlugin/Test/TestTrimLine.py b/src/SketchPlugin/Test/TestTrimLine.py deleted file mode 100644 index b8acec087..000000000 --- a/src/SketchPlugin/Test/TestTrimLine.py +++ /dev/null @@ -1,191 +0,0 @@ -from salome.shaper import model - -from ModelAPI import * -from GeomDataAPI import * -from salome.shaper import geom -import math - -TOLERANCE = 1.e-7 - -SketchPointId = 'SketchPoint' -SketchLineId = 'SketchLine' -SketchArcId = 'SketchArc' -SketchCircleId = 'SketchCircle' -SketchConstraintCoincidenceId = 'SketchConstraintCoincidence' -SketchConstraintMirrorId = 'SketchConstraintMirror' -SketchConstraintTangentId = 'SketchConstraintTangent' -SketchConstraintEqualId = 'SketchConstraintEqual' - -model.begin() -partSet = model.moduleDocument() -Part_1 = model.addPart(partSet) -Part_1_doc = Part_1.document() - -# Test1:begin split on circle with coincident point and intersection line : smaller part -Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchCircle_1_1 = Sketch_1.addCircle(50, 50, 20) -SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30) -SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30) - -SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchCircle_1_1.results()[1]) -SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint()) -GeomPoint_1_1 = geom.Pnt2d(60, 35) - -#check number of features before trim -Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature()) -idList_before_1 = [] -for index in range(Sketch_1_feature.numberOfSubs()): - idList_before_1.append(Sketch_1_feature.subFeature(index).getKind()) -assert(idList_before_1.count(SketchCircleId) == 1) -assert(idList_before_1.count(SketchArcId) == 0) -assert(idList_before_1.count(SketchLineId) == 2) -assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2) - -#perform trim -SketchTrim_1_1 = Sketch_1.addTrim(SketchCircle_1_1, GeomPoint_1_1) -SketchTrim_1_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_1.feature()) -idList_after_1 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_1.append(SubFeature.getKind()) - if SubFeature.getKind() == SketchArcId: - ArcFeature_1 = SubFeature - - -assert(idList_after_1.count(SketchCircleId) == 0) -assert(idList_after_1.count(SketchArcId) == 1) -assert(idList_after_1.count(SketchLineId) == 2) -assert(idList_after_1.count(SketchConstraintCoincidenceId) == 3) - -#test created arc: it is not inversed, has coincidence to end line point -anInversed_1 = ArcFeature_1.boolean("InversedArc").value() -assert(anInversed_1 == False) -ArcPoint_1 = geomDataAPI_Point2D(ArcFeature_1.attribute("ArcEndPoint")) -LinePoint_1 = geomDataAPI_Point2D(SketchLine_1_1.startPoint()) -aDistance_1 = math.hypot(LinePoint_1.x() - ArcPoint_1.x(), LinePoint_1.y() - ArcPoint_1.y()) -#print "Distance " + repr(aDistance) -assert (math.fabs(aDistance_1) <= TOLERANCE) -# Test1:end - - -# Test2: split on circle with coincident point and intersection line : largest part -Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -move_test_delta_y = 100 -move_test_delta_x = 0 -SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20) -SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y) -SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y) - -SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1]) -SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint()) -GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y) - -#check number of features before trim -Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature()) -idList_before_2 = [] -for index in range(Sketch_2_feature.numberOfSubs()): - idList_before_2.append(Sketch_2_feature.subFeature(index).getKind()) -assert(idList_before_2.count(SketchCircleId) == 1) -assert(idList_before_2.count(SketchArcId) == 0) -assert(idList_before_2.count(SketchLineId) == 2) -assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2) - -#perform trim -SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1) -SketchTrim_2_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_2.feature()) -idList_after_2 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_2.append(SubFeature.getKind()) - if SubFeature.getKind() == SketchArcId: - ArcFeature_2 = SubFeature - - -assert(idList_after_2.count(SketchCircleId) == 0) -assert(idList_after_2.count(SketchArcId) == 1) -assert(idList_after_2.count(SketchLineId) == 2) -assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3) - -#test created arc : it is not inversed, has coincidence to start line point -anInversed_2 = ArcFeature_2.boolean("InversedArc").value() -assert(anInversed_2 == False) -ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint")) -LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint()) -aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y()) -#print "Distance " + repr(aDistance_2) -assert (math.fabs(aDistance_2) <= TOLERANCE) -# Test2:end - - -# Test3: constraints to circle -Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) -SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25) -SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30) -SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30) -SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100) -SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20) -aSketchPoint_3 = Sketch_3.addPoint(145, 70) -SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70) - -SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1]) -SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint()) -GeomPoint_3_1 = geom.Pnt2d(165, 40) - -#Constraints -aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50) -aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]) -aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25) -aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0]) -aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0]) - -MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]] -aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3) - -#check number of features before trim -Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature()) -idList_before_3 = [] -for index in range(Sketch_3_feature.numberOfSubs()): - idList_before_3.append(Sketch_3_feature.subFeature(index).getKind()) - -assert(idList_before_3.count(SketchCircleId) == 4) -assert(idList_before_3.count(SketchArcId) == 0) -assert(idList_before_3.count(SketchLineId) == 4) -assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_before_3.count(SketchConstraintMirrorId) == 1) -assert(idList_before_3.count(SketchConstraintTangentId) == 1) -assert(idList_before_3.count(SketchConstraintEqualId) == 1) - -#perform trim -SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1) -SketchTrim_3_1.execute() -model.do() - -#check number of features after trim -SketchFeatures = featureToCompositeFeature(Sketch_3.feature()) -idList_after_3 = [] -for SubIndex in range(SketchFeatures.numberOfSubs()): - SubFeature = SketchFeatures.subFeature(SubIndex) - idList_after_3.append(SubFeature.getKind()) - - -assert(idList_after_3.count(SketchCircleId) == 3) -assert(idList_after_3.count(SketchArcId) == 1) -assert(idList_after_3.count(SketchLineId) == 4) -assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3) -assert(idList_after_3.count(SketchConstraintMirrorId) == 0) -assert(idList_after_3.count(SketchConstraintTangentId) == 1) -assert(idList_after_3.count(SketchConstraintEqualId) == 1) -# Test3:end - - -model.end() - -#assert(model.checkPythonDump()) -- 2.30.2