/// Returns edge length.
GEOMAPI_EXPORT
double length() const;
+
+ /// Returns true if the edge is closed (like full circle)
+ GEOMAPI_EXPORT
+ bool isClosed() const;
+
+ /// Returns true if the edge is degenerated (has no 3D curve)
+ GEOMAPI_EXPORT
+ bool isDegenerated() const;
};
+//! Pointer on attribute object
+typedef std::shared_ptr<GeomAPI_Edge> GeomEdgePtr;
+
#endif
{
if(theSubShapeName.empty() || theType.empty()) return;
- // check this is Part-name: 2 delimiters in the name
- std::size_t aPartEnd = theSubShapeName.find('/');
- if (aPartEnd != std::string::npos && aPartEnd != theSubShapeName.rfind('/')) {
- std::string aPartName = theSubShapeName.substr(0, aPartEnd);
- ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName);
- if (aFound.get()) { // found such part, so asking it for the name
- ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFound);
- std::string aNameInPart = theSubShapeName.substr(aPartEnd + 1);
- int anIndex;
- std::shared_ptr<GeomAPI_Shape> aSelected = aPart->shapeInPart(aNameInPart, theType, anIndex);
- if (aSelected.get()) {
- setValue(aPart, aSelected);
- TDataStd_Integer::Set(selectionLabel(), anIndex);
- return;
+ std::string aSubShapeName = theSubShapeName;
+ CenterType aCenterType = theType[0] == 'v' || theType[0] == 'V' ? // only for vertex-type
+ centerTypeByName(aSubShapeName) : NOT_CENTER;
+ std::string aType = aCenterType == NOT_CENTER ? theType : "EDGE"; // search for edge now
+
+ // first iteration is selection by name without center prefix, second - in case of problem,
+ // try with initial name
+ for(int aUseCenter = 1; aUseCenter >= 0; aUseCenter--) {
+ if (aUseCenter == 0 && aCenterType != NOT_CENTER) {
+ aSubShapeName = theSubShapeName;
+ aCenterType = NOT_CENTER;
+ aType = theType;
+ } else if (aUseCenter != 1) continue;
+
+ // check this is Part-name: 2 delimiters in the name
+ std::size_t aPartEnd = aSubShapeName.find('/');
+ if (aPartEnd != std::string::npos && aPartEnd != aSubShapeName.rfind('/')) {
+ std::string aPartName = aSubShapeName.substr(0, aPartEnd);
+ ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName);
+ if (aFound.get()) { // found such part, so asking it for the name
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFound);
+ std::string aNameInPart = aSubShapeName.substr(aPartEnd + 1);
+ int anIndex;
+ std::shared_ptr<GeomAPI_Shape> aSelected = aPart->shapeInPart(aNameInPart, aType, anIndex);
+ if (aSelected.get()) {
+ if (aCenterType != NOT_CENTER) {
+ if (!aSelected->isEdge())
+ continue;
+ std::shared_ptr<GeomAPI_Edge> aSelectedEdge(new GeomAPI_Edge(aSelected));
+ setValueCenter(aPart, aSelectedEdge, aCenterType);
+ } else
+ setValue(aPart, aSelected);
+ TDataStd_Integer::Set(selectionLabel(), anIndex);
+ return;
+ }
}
}
- }
- Model_SelectionNaming aSelNaming(selectionLabel());
- std::shared_ptr<Model_Document> aDoc =
- std::dynamic_pointer_cast<Model_Document>(owner()->document());
- std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected;
- ResultPtr aCont;
- if (aSelNaming.selectSubShape(theType, theSubShapeName, aDoc, aShapeToBeSelected, aCont)) {
- // try to find the last context to find the up to date shape
- if (aCont->shape().get() && !aCont->shape()->isNull() &&
- aCont->groupName() == ModelAPI_ResultBody::group() && aDoc == owner()->document()) {
- const TopoDS_Shape aConShape = aCont->shape()->impl<TopoDS_Shape>();
- if (!aConShape.IsNull()) {
- Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel());
- if (!aNS.IsNull()) {
- aNS = TNaming_Tool::CurrentNamedShape(aNS);
+ Model_SelectionNaming aSelNaming(selectionLabel());
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(owner()->document());
+ std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected;
+ ResultPtr aCont;
+ if (aSelNaming.selectSubShape(aType, aSubShapeName, aDoc, aShapeToBeSelected, aCont)) {
+ // try to find the last context to find the up to date shape
+ if (aCont->shape().get() && !aCont->shape()->isNull() &&
+ aCont->groupName() == ModelAPI_ResultBody::group() && aDoc == owner()->document()) {
+ const TopoDS_Shape aConShape = aCont->shape()->impl<TopoDS_Shape>();
+ if (!aConShape.IsNull()) {
+ Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel());
- if (!aNS.IsNull()) {
+ if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228
- TDF_Label aLab = aNS->Label();
- while(aLab.Depth() != 7 && aLab.Depth() > 5)
- aLab = aLab.Father();
- ObjectPtr anObj = aDoc->objects()->object(aLab);
- if (anObj.get()) {
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
- if (aRes)
- aCont = aRes;
+ aNS = TNaming_Tool::CurrentNamedShape(aNS);
+ if (!aNS.IsNull()) {
+ TDF_Label aLab = aNS->Label();
+ while(aLab.Depth() != 7 && aLab.Depth() > 5)
+ aLab = aLab.Father();
+ ObjectPtr anObj = aDoc->objects()->object(aLab);
+ if (anObj.get()) {
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
+ if (aRes)
+ aCont = aRes;
+ }
}
}
}
return int(filter(str.isdigit, aSketch.string("SolverDOF").value()))
def distancePointPoint(thePoint1, thePoint2):
- aPnt1 = toList(thePoint1)
- aPnt2 = toList(thePoint2)
- return math.hypot(aPnt1[0] - aPnt2[0], aPnt1[1] - aPnt2[1])
+ aGeomPnt1 = thePoint1
+ aGeomPnt2 = thePoint2
+ if issubclass(type(thePoint1), GeomDataAPI.GeomDataAPI_Point2D):
+ aGeomPnt1 = thePoint1.pnt()
+ if issubclass(type(thePoint2), GeomDataAPI.GeomDataAPI_Point2D):
+ aGeomPnt2 = thePoint2.pnt()
+ return aGeomPnt1.distance(aGeomPnt2)
+def signedDistancePointLine(thePoint, theLine):
+ aPoint = toList(thePoint)
+ aLine = toSketchFeature(theLine)
+
+ aLineStart = geomDataAPI_Point2D(aLine.attribute("StartPoint")).pnt().xy()
+ aLineEnd = geomDataAPI_Point2D(aLine.attribute("EndPoint")).pnt().xy()
+ aLineDir = aLineEnd.decreased(aLineStart)
+ aLineLen = aLineEnd.distance(aLineStart)
+ aCross = (aPoint[0] - aLineStart.x()) * aLineDir.y() - (aPoint[1] - aLineStart.y()) * aLineDir.x()
+ return aCross / aLineLen
+
+def distancePointLine(thePoint, theLine):
+ return math.fabs(signedDistancePointLine(thePoint, theLine))
+
def lastSubFeature(theSketch, theKind):
"""
obtains last feature of given kind from the sketch
SketchPlugin_ConstraintCoincidence.h
SketchPlugin_ConstraintCollinear.h
SketchPlugin_ConstraintDistance.h
+ SketchPlugin_ConstraintDistanceHorizontal.h
+ SketchPlugin_ConstraintDistanceVertical.h
SketchPlugin_ConstraintEqual.h
+ SketchPlugin_Fillet.h
SketchPlugin_ConstraintHorizontal.h
SketchPlugin_ConstraintLength.h
SketchPlugin_ConstraintMiddle.h
SketchPlugin_ConstraintRigid.h
SketchPlugin_ConstraintTangent.h
SketchPlugin_ConstraintVertical.h
+ SketchPlugin_Ellipse.h
SketchPlugin_ExternalValidator.h
SketchPlugin_Feature.h
- SketchPlugin_Fillet.h
SketchPlugin_IntersectionPoint.h
SketchPlugin_Line.h
SketchPlugin_MacroArc.h
SketchPlugin_ConstraintCoincidence.cpp
SketchPlugin_ConstraintCollinear.cpp
SketchPlugin_ConstraintDistance.cpp
+ SketchPlugin_ConstraintDistanceHorizontal.cpp
+ SketchPlugin_ConstraintDistanceVertical.cpp
SketchPlugin_ConstraintEqual.cpp
+ SketchPlugin_Fillet.cpp
SketchPlugin_ConstraintHorizontal.cpp
SketchPlugin_ConstraintLength.cpp
SketchPlugin_ConstraintMiddle.cpp
SketchPlugin_ConstraintRigid.cpp
SketchPlugin_ConstraintTangent.cpp
SketchPlugin_ConstraintVertical.cpp
+ SketchPlugin_Ellipse.cpp
SketchPlugin_ExternalValidator.cpp
SketchPlugin_Feature.cpp
- SketchPlugin_Fillet.cpp
SketchPlugin_IntersectionPoint.cpp
SketchPlugin_Line.cpp
SketchPlugin_MacroArc.cpp
TestTrimCircleAndArc01.py
TestTrimLine01.py
TestTrimLine02.py
+ Test2229.py
+ Test2239.py
+ TestDistanceSignedVsUnsigned01.py
+ TestDistanceSignedVsUnsigned02.py
+ TestDistanceSignedVsUnsigned03.py
+ TestDistanceSignedVsUnsigned04.py
+ TestDistanceSignedVsUnsigned05.py
+ TestSignedDistancePointPoint.py
+ TestSignedDistancePointLine.py
)
+
+if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
+ ADD_UNIT_TESTS(
+ TestMovePoint.py
+ TestMoveLine.py
+ TestMoveCircle.py
+ TestMoveArc.py
+ TestMovementComplex.py
+ )
+endif()
}
// ============================================================================
-// Function: changeConstraintOrEntity
+// Function: updateFeature
- // Purpose: create/update constraint or feature in appropriate group
+ // Purpose: create/update the constraint or the feature and place it into appropriate group
// ============================================================================
- bool SketchSolver_Manager::updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature)
+ bool SketchSolver_Manager::updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature,
+ bool theMoved)
{
// Check feature validity and find a group to place it.
// If the feature is not valid, the returned group will be empty.
/** \brief Adds or updates a constraint or an entity in the suitable group
* \param[in] theFeature sketch feature to be changed
+ * \param[in] theMoved \c true if the feature has been moved in the viewer
* \return \c true if the feature changed successfully
*/
- bool updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature);
+ bool updateFeature(std::shared_ptr<SketchPlugin_Feature> theFeature, bool theMoved = false);
+ /** \brief Move feature
+ * \param[in] theMovedFeature dragged sketch feature
+ * \param[in] theFromPoint original position of the feature
+ * \param[in] theToPoint prefereble position of the feature (current position of the mouse)
+ * \return \c true if the feature has been changed successfully
+ */
+ bool moveFeature(const std::shared_ptr<SketchPlugin_Feature>& theMovedFeature,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFromPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theToPoint);
+
+ /** \brief Move feature using its moved attribute
+ * \param[in] theMovedAttribute dragged point attribute of sketch feature
+ * \param[in] theFromPoint original position of the moved point
+ * \param[in] theToPoint prefereble position (current position of the mouse)
+ * \return \c true if the attribute owner has been changed successfully
+ */
+ bool moveAttribute(const std::shared_ptr<GeomDataAPI_Point2D>& theMovedAttribute,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFromPoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theToPoint);
+
/** \brief Removes a constraint from the manager
* \param[in] theConstraint constraint to be removed
* \return \c true if the constraint removed successfully