X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchAPI%2FSketchAPI_Sketch.cpp;h=722cbbaa77e40782003c6940d9f14d61f867801a;hb=749e980caeebfe4d16441703b7028dbbb1f1d91a;hp=24be396bf39a2a109d11bd5f4d90d51b82b03e9a;hpb=424eaeb96c9c29ec2dea4ebaf80ac7822ab0bc4f;p=modules%2Fshaper.git diff --git a/src/SketchAPI/SketchAPI_Sketch.cpp b/src/SketchAPI/SketchAPI_Sketch.cpp index 24be396bf..722cbbaa7 100644 --- a/src/SketchAPI/SketchAPI_Sketch.cpp +++ b/src/SketchAPI/SketchAPI_Sketch.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 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,10 +12,9 @@ // // 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 "SketchAPI_Sketch.h" @@ -66,8 +65,12 @@ #include "SketchAPI_Rotation.h" #include "SketchAPI_Translation.h" //-------------------------------------------------------------------------------------- +#include #include +#include +#include #include +#include #include //-------------------------------------------------------------------------------------- SketchAPI_Sketch::SketchAPI_Sketch( @@ -128,6 +131,25 @@ void SketchAPI_Sketch::setPlane(const std::shared_ptr & thePlane) execute(); } +void SketchAPI_Sketch::setPlane(const ModelHighAPI_Selection & thePlane, + bool theRemoveExternalDependency) +{ + FeaturePtr aSketch = feature(); + + DocumentPtr aDoc = aSketch->document(); + bool useVisible = false; + FeaturePtr aCurFeatureBefore = aDoc->currentFeature(useVisible); + aDoc->setCurrentFeature(aSketch, useVisible); + + if (theRemoveExternalDependency) + aSketch->customAction(SketchPlugin_Sketch::ACTION_REMOVE_EXTERNAL()); + + setExternal(thePlane); + + aDoc->setCurrentFeature(aCurFeatureBefore, useVisible); +} + +//-------------------------------------------------------------------------------------- void SketchAPI_Sketch::setExternal(const ModelHighAPI_Selection & theExternal) { fillAttribute(theExternal, myexternal); @@ -204,6 +226,78 @@ SketchPtr addSketch(const std::shared_ptr & thePart, } +//-------------------------------------------------------------------------------------- +std::list< std::shared_ptr > SketchAPI_Sketch::getFreePoints() +{ + std::list< std::shared_ptr > aFreePoints; + std::list aPoints = SketcherPrs_Tools::getFreePoints(compositeFeature()); + for (std::list::iterator anIt = aPoints.begin(); anIt != aPoints.end(); ++anIt) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + PointPtr aPoint(new SketchAPI_Point(aFeature)); + aFreePoints.push_back(aPoint); + } + return aFreePoints; +} + +//-------------------------------------------------------------------------------------- +static GeomCurvePtr untrimmedCurve(GeomShapePtr theShape) +{ + GeomCurvePtr aCurve(new GeomAPI_Curve(theShape)); + if (aCurve->isTrimmed()) + aCurve = aCurve->basisCurve(); + return aCurve; +} + +void SketchAPI_Sketch::changeFacesOrder( + const std::list >& theFaces) +{ + // collect faces of the sketch + ResultConstructionPtr aSketchResult = + std::dynamic_pointer_cast(feature()->lastResult()); + if (!aSketchResult) { + // sketch is nested to a boolean operation, thus, it has no result yet. + feature()->execute(); + aSketchResult = + std::dynamic_pointer_cast(feature()->lastResult()); + } + std::list aFaces; + int aFacesNum = aSketchResult->facesNum(); + for (int i = 0; i < aFacesNum; ++i) + aFaces.push_back(aSketchResult->face(i)); + // find new faces order according to the given lists of edges + std::list aNewFacesOrder; + std::list >::const_iterator anIt = theFaces.begin(); + for (; anIt != theFaces.end(); ++anIt) { + // find the appropriate face + std::list::iterator aFIt = aFaces.begin(); + for (; aFIt != aFaces.end(); ++aFIt) { + std::list::const_iterator aEdgeIt = anIt->begin(); + GeomAPI_ShapeExplorer aFExp(*aFIt, GeomAPI_Shape::EDGE); + for (; aEdgeIt != anIt->end() && aFExp.more(); ++aEdgeIt, aFExp.next()) { + ResultPtr aCurRes = aEdgeIt->resultSubShapePair().first; + if (!aCurRes) + break; + GeomCurvePtr aCurve1 = untrimmedCurve(aCurRes->shape()); + GeomCurvePtr aCurve2 = untrimmedCurve(aFExp.current()); + if (!aCurve1->isEqual(aCurve2)) + break; + } + + if (aEdgeIt == anIt->end() && !aFExp.more()) { + // face is found + aNewFacesOrder.push_back(*aFIt); + aFaces.erase(aFIt); + break; + } + } + } + // place the rest faces at the end of new faces list + if (!aFaces.empty()) + aNewFacesOrder.insert(aNewFacesOrder.end(), aFaces.begin(), aFaces.end()); + // update the result of the sketch with the new order of faces + aSketchResult->setFacesOrder(aNewFacesOrder); +} + //-------------------------------------------------------------------------------------- std::shared_ptr SketchAPI_Sketch::addPoint( double theX, double theY) @@ -572,9 +666,9 @@ std::shared_ptr SketchAPI_Sketch::setAngle( fillAttribute(SketcherPrs_Tools::ANGLE_DIRECT, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID())); // fill the value before llines to avoid calculation of angle value by the Angle feature - fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); + fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -588,10 +682,9 @@ std::shared_ptr SketchAPI_Sketch::setAngleComplementary( compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID()); fillAttribute(SketcherPrs_Tools::ANGLE_COMPLEMENTARY, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID())); - fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); -// fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE())); + fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -605,10 +698,9 @@ std::shared_ptr SketchAPI_Sketch::setAngleBackward( compositeFeature()->addFeature(SketchPlugin_ConstraintAngle::ID()); fillAttribute(SketcherPrs_Tools::ANGLE_BACKWARD, aFeature->integer(SketchPlugin_ConstraintAngle::TYPE_ID())); - fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); fillAttribute(theLine1, aFeature->refattr(SketchPlugin_Constraint::ENTITY_A())); fillAttribute(theLine2, aFeature->refattr(SketchPlugin_Constraint::ENTITY_B())); -// fillAttribute(theValue, aFeature->real(SketchPlugin_Constraint::VALUE())); + fillAttribute(theValue, aFeature->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID())); aFeature->execute(); return InterfacePtr(new ModelHighAPI_Interface(aFeature)); } @@ -846,9 +938,7 @@ std::shared_ptr SketchAPI_Sketch::setVertical( static std::shared_ptr pointCoordinates(const AttributePtr& thePoint) { AttributePoint2DPtr aPnt = std::dynamic_pointer_cast(thePoint); - if (aPnt) - return aPnt->pnt(); - return std::shared_ptr(); + return aPnt ? aPnt->pnt() : std::shared_ptr(); } static std::shared_ptr middlePointOnLine(const FeaturePtr& theFeature) @@ -919,20 +1009,21 @@ static std::shared_ptr middlePointOnArc(const FeaturePtr& theFeat static std::shared_ptr middlePoint(const ObjectPtr& theObject) { + std::shared_ptr aMiddlePoint; FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); if (aFeature) { + // move only features of the following types const std::string& aFeatureKind = aFeature->getKind(); if (aFeatureKind == SketchPlugin_Point::ID()) - return pointCoordinates(aFeature->attribute(SketchPlugin_Point::COORD_ID())); + aMiddlePoint = pointCoordinates(aFeature->attribute(SketchPlugin_Point::COORD_ID())); else if (aFeatureKind == SketchPlugin_Line::ID()) - return middlePointOnLine(aFeature); + aMiddlePoint = middlePointOnLine(aFeature); else if (aFeatureKind == SketchPlugin_Circle::ID()) - return pointOnCircle(aFeature); + aMiddlePoint = pointOnCircle(aFeature); else if (aFeatureKind == SketchPlugin_Arc::ID()) - return middlePointOnArc(aFeature); + aMiddlePoint = middlePointOnArc(aFeature); } - // do not move other types of features - return std::shared_ptr(); + return aMiddlePoint; } void SketchAPI_Sketch::move(const ModelHighAPI_RefAttr& theMovedEntity, @@ -980,6 +1071,99 @@ std::shared_ptr SketchAPI_Sketch::to2D(const std::shared_ptr anEdges1; + for (GeomAPI_ShapeExplorer anExp(theFace1, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) + anEdges1.push_back(anExp.current()); + // compare edges of faces + for (GeomAPI_ShapeExplorer anExp(theFace2, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) { + GeomShapePtr aCurrent = anExp.current(); + bool isFound = false; + std::list::iterator anIt1 = anEdges1.begin(); + for (; anIt1 != anEdges1.end(); ++anIt1) + if (aCurrent->isSameGeometry(*anIt1)) { + isFound = true; + anEdges1.erase(anIt1); + break; + } + if (!isFound) + return true; + } + return !anEdges1.empty(); +} + +static bool isCustomFacesOrder(CompositeFeaturePtr theSketch) +{ + ResultConstructionPtr aSketchResult = + std::dynamic_pointer_cast(theSketch->lastResult()); + if (!aSketchResult) + return false; + + std::shared_ptr aWires = + std::dynamic_pointer_cast(aSketchResult->shape()); + if (!aWires) + return false; + + // collect faces constructed by SketchBuilder algorithm + GeomAlgoAPI_SketchBuilder aSketchBuilder(aWires->origin(), aWires->dirX(), + aWires->norm(), aWires); + const ListOfShape& aFaces = aSketchBuilder.faces(); + + // compare faces stored in sketch with faces generated by SketchBuilder + int aNbSketchFaces = aSketchResult->facesNum(); + int aFaceIndex = 0; + for (ListOfShape::const_iterator aFIt = aFaces.begin(); + aFIt != aFaces.end() && aFaceIndex < aNbSketchFaces; + ++aFIt, ++aFaceIndex) { + GeomFacePtr aSketchFace = aSketchResult->face(aFaceIndex); + GeomFacePtr aCurFace = (*aFIt)->face(); + if (isDifferent(aSketchFace, aCurFace)) + return true; + } + return false; +} + +static void edgesOfSketchFaces(CompositeFeaturePtr theSketch, + std::list >& theEdges) +{ + ResultConstructionPtr aSketchResult = + std::dynamic_pointer_cast(theSketch->lastResult()); + if (!aSketchResult) + return; + + // collect curves of the sketch + std::map aCurves; + int aSubNum = theSketch->numberOfSubs(); + for (int a = 0; a < aSubNum; ++a) { + FeaturePtr aSub = theSketch->subFeature(a); + const std::list& aResults = aSub->results(); + std::list::const_iterator aRes = aResults.cbegin(); + for (; aRes != aResults.cend(); aRes++) { + GeomShapePtr aCurShape = (*aRes)->shape(); + if (aCurShape && aCurShape->isEdge()) + aCurves[untrimmedCurve(aCurShape)] = *aRes; + } + } + + // convert each face to the list of results of its edges + int aFacesNum = aSketchResult->facesNum(); + for (int a = 0; a < aFacesNum; ++a) { + theEdges.push_back(std::list()); + std::list& aCurEdges = theEdges.back(); + + GeomFacePtr aFace = aSketchResult->face(a); + for (GeomAPI_ShapeExplorer anExp(aFace, GeomAPI_Shape::EDGE); + anExp.more(); anExp.next()) { + GeomCurvePtr aCurrent = untrimmedCurve(anExp.current()); + aCurEdges.push_back(aCurves[aCurrent]); + } + } +} + +//-------------------------------------------------------------------------------------- + void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const { FeaturePtr aBase = feature(); @@ -1039,4 +1223,24 @@ void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const // dump sketch's subfeatures CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(aBase); theDumper.processSubs(aCompFeat, true); + + // if face order differs to the order generated by SketchBuilder, + // dump the list of faces for correct execution of the script + if (isCustomFacesOrder(aCompFeat)) { + std::list > aFaces; + edgesOfSketchFaces(aCompFeat, aFaces); + + const std::string& aSketchName = theDumper.name(aBase); + std::string aMethodName(".changeFacesOrder"); + std::string aSpaceShift(aSketchName.size() + aMethodName.size(), ' '); + + theDumper << aSketchName << aMethodName << "(["; + for (std::list >::iterator aFIt = aFaces.begin(); + aFIt != aFaces.end(); ++aFIt) { + if (aFIt != aFaces.begin()) + theDumper << ",\n" << aSpaceShift << " "; + theDumper << *aFIt; + } + theDumper << "\n" << aSpaceShift << " ])" << std::endl; + } }