]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge remote-tracking branch 'origin/Dev_PluginPathExtension'
authormpv <mpv@opencascade.com>
Mon, 30 Oct 2017 12:24:24 +0000 (15:24 +0300)
committermpv <mpv@opencascade.com>
Mon, 30 Oct 2017 12:24:24 +0000 (15:24 +0300)
23 files changed:
CMakeLists.txt
src/ConstructionPlugin/ConstructionPlugin_Point.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.h
src/FeaturesPlugin/FeaturesPlugin_Scale.cpp
src/FeaturesPlugin/FeaturesPlugin_Symmetry.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/PartSet/PartSet_CenterPrs.cpp
src/PartSet/PartSet_CenterPrs.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintDistanceHorizontal.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistanceHorizontal.h
src/SketchPlugin/SketchPlugin_ConstraintDistanceVertical.cpp
src/SketchPlugin/SketchPlugin_ConstraintDistanceVertical.h
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/Test/Test2280.py [new file with mode: 0644]
src/SketchPlugin/Test/TestConstraintDistanceBehavior.py
src/SketchPlugin/Test/TestConstraintDistanceHorizontal.py
src/SketchPlugin/Test/TestConstraintDistanceVertical.py
src/SketchPlugin/plugin-Sketch.xml
src/SketcherPrs/SketcherPrs_LengthDimension.cpp

index 67da105d280076e77e23aec24c16a9e41f165a30..ea6768c3e439bcd25dba7d396722dd2f99441113 100644 (file)
@@ -27,7 +27,7 @@ IF(WIN32)
   CMAKE_POLICY(SET CMP0020 OLD) # disable automatic linking to qtmain.lib
 ENDIF(WIN32)
 
-SET (SHAPER_Version 2.9.0)
+SET (SHAPER_Version 2.9.1)
 
 SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH})
 
index f08cd5fa42661a5d97b3d325f02e52af0fa71928..08ff70a3a7a2ed8a7f5cdba439c975df2f0fe4ef 100644 (file)
@@ -79,7 +79,7 @@ void ConstructionPlugin_Point::execute()
 {
   GeomShapePtr aShape;
 
-   // to support compatibility with old documents where aCreationMethod did not exist
+  // to support compatibility with old documents where aCreationMethod did not exist
   std::string aCreationMethod =
     string(CREATION_METHOD()).get() && !string(CREATION_METHOD())->value().empty() ?
     string(CREATION_METHOD())->value() : CREATION_METHOD_BY_XYZ();
@@ -92,7 +92,20 @@ void ConstructionPlugin_Point::execute()
   } else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) {
     aShape = createByLinesIntersection();
   }*/ else if(aCreationMethod == CREATION_METHOD_BY_LINE_AND_PLANE_INTERSECTION()) {
-    aShape = createByLineAndPlaneIntersection();
+    // this may produce several points
+    std::list<std::shared_ptr<GeomAPI_Vertex> > aPoints = createByLineAndPlaneIntersection();
+    if (!aPoints.empty()) { // if no points found produce the standard error later
+      int anIndex = 0;
+      std::list<std::shared_ptr<GeomAPI_Vertex> >::iterator aPIter = aPoints.begin();
+      for(; aPIter != aPoints.end(); aPIter++, anIndex++) {
+        std::shared_ptr<ModelAPI_ResultConstruction> aConstr =
+          document()->createConstruction(data(), anIndex);
+        aConstr->setShape(*aPIter);
+        setResult(aConstr, anIndex);
+      }
+      removeResults(anIndex);
+      return;
+    }
   }
 
   if(!aShape.get()) {
@@ -100,6 +113,7 @@ void ConstructionPlugin_Point::execute()
     return;
   }
 
+  removeResults(1); // for case the point type was switched from multi-results type
   std::shared_ptr<ModelAPI_ResultConstruction> aConstr = document()->createConstruction(data());
   aConstr->setShape(aShape);
   setResult(aConstr);
@@ -191,7 +205,8 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByLinesIntersect
 */
 
 //==================================================================================================
-std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByLineAndPlaneIntersection()
+std::list<std::shared_ptr<GeomAPI_Vertex> >
+  ConstructionPlugin_Point::createByLineAndPlaneIntersection()
 {
   // Get line.
   AttributeSelectionPtr aLineSelection = selection(INTERSECTION_LINE());
@@ -218,5 +233,6 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByLineAndPlaneIn
     }
   }
 
-  return GeomAlgoAPI_ShapeTools::intersect(anEdge, aFace);
+  return GeomAlgoAPI_ShapeTools::intersect(anEdge, aFace,
+    aPlaneSelection->context()->groupName() == ModelAPI_ResultConstruction::group());
 }
index a9f59d31de4f1c92c91e9afe33f1ec29e4bfe7e4..f983ec3270015565d858b96836e67beecd008c14 100644 (file)
@@ -223,7 +223,7 @@ private:
   /*std::shared_ptr<GeomAPI_Vertex> createByDistanceOnEdge();
   std::shared_ptr<GeomAPI_Vertex> createByProjection();
   std::shared_ptr<GeomAPI_Vertex> createByLinesIntersection();*/
-  std::shared_ptr<GeomAPI_Vertex> createByLineAndPlaneIntersection();
+  std::list<std::shared_ptr<GeomAPI_Vertex> > createByLineAndPlaneIntersection();
 
 };
 
index 6791520eb1524156b409faddccf7d0d658e40052..4e854c22a5f491e742f68ad57121d9b4c916382b 100644 (file)
@@ -28,7 +28,7 @@
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultPart.h>
 
-#include <iostream>
+#include <FeaturesPlugin_Tools.h>
 
 //=================================================================================================
 FeaturesPlugin_Scale::FeaturesPlugin_Scale()
@@ -251,9 +251,8 @@ void FeaturesPlugin_Scale::loadNamingDS(GeomAlgoAPI_Scale& theScaleAlgo,
 
   // Name the faces
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theScaleAlgo.mapOfSubShapes();
-  int aReflectedTag = 1;
-  std::string aReflectedName = "Scaled";
-  theResultBody->loadAndOrientModifiedShapes(&theScaleAlgo,
-                                              theBaseShape, GeomAPI_Shape::FACE,
-                                              aReflectedTag, aReflectedName, *aSubShapes.get());
+  std::string aScaledName = "Scaled";
+  FeaturesPlugin_Tools::storeModifiedShapes(theScaleAlgo, theResultBody,
+                                            theBaseShape, 1, 2, 3, aScaledName,
+                                            *aSubShapes.get());
 }
index 962679d49966782d299b43b0066f88228acfab59..7121e968d710362ec4be831088e383c6ba14f249 100644 (file)
@@ -21,6 +21,7 @@
 #include <FeaturesPlugin_Symmetry.h>
 
 #include <GeomAlgoAPI_PointBuilder.h>
+#include <GeomAlgoAPI_FaceBuilder.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Face.h>
@@ -33,8 +34,7 @@
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultPart.h>
 
-#include <iostream>
-#include <GeomAlgoAPI_FaceBuilder.h>
+#include <FeaturesPlugin_Tools.h>
 
 //=================================================================================================
 FeaturesPlugin_Symmetry::FeaturesPlugin_Symmetry()
@@ -369,9 +369,8 @@ void FeaturesPlugin_Symmetry::loadNamingDS(GeomAlgoAPI_Symmetry& theSymmetryAlgo
 
   // Name the faces
   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = theSymmetryAlgo.mapOfSubShapes();
-  int aReflectedTag = 1;
   std::string aReflectedName = "Symmetried";
-  theResultBody->loadAndOrientModifiedShapes(&theSymmetryAlgo,
-                                              theBaseShape, GeomAPI_Shape::FACE,
-                                              aReflectedTag, aReflectedName, *aSubShapes.get());
+  FeaturesPlugin_Tools::storeModifiedShapes(theSymmetryAlgo, theResultBody,
+                                            theBaseShape, 1, 2, 3, aReflectedName,
+                                            *aSubShapes.get());
 }
index 04ae892e351dcb00e8e2ede067e17185042ca8fe..d798b50ad00687b5f6cbe53edd6701623740dca3 100644 (file)
@@ -54,7 +54,7 @@
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
-#include <GeomAPI_ExtremaCurveSurface.hxx>
+#include <GeomAPI_IntCS.hxx>
 #include <gp_Pln.hxx>
 #include <GProp_GProps.hxx>
 #include <IntAna_IntConicQuad.hxx>
@@ -750,11 +750,13 @@ bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr<GeomAPI_Edge> theE
 }
 
 //==================================================================================================
-std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_ShapeTools::intersect(
-  const std::shared_ptr<GeomAPI_Edge> theEdge, const std::shared_ptr<GeomAPI_Face> theFace)
+std::list<std::shared_ptr<GeomAPI_Vertex> > GeomAlgoAPI_ShapeTools::intersect(
+  const std::shared_ptr<GeomAPI_Edge> theEdge, const std::shared_ptr<GeomAPI_Face> theFace,
+  const bool thePointsOutsideFace)
 {
+  std::list<std::shared_ptr<GeomAPI_Vertex> > aResult;
   if(!theEdge.get() || !theFace.get()) {
-    return std::shared_ptr<GeomAPI_Vertex>();
+    return aResult;
   }
 
   TopoDS_Edge anEdge = TopoDS::Edge(theEdge->impl<TopoDS_Shape>());
@@ -764,33 +766,22 @@ std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_ShapeTools::intersect(
   TopoDS_Face aFace  = TopoDS::Face(theFace->impl<TopoDS_Shape>());
   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
 
-  GeomAPI_ExtremaCurveSurface anExt(aCurve, aSurf);
-  // searching for the best point-intersection
-  int aMaxLevel = 0;
-  gp_Pnt aResult;
-  for(int anIntNum = 1; anIntNum <= anExt.NbExtrema(); anIntNum++) {
-    if (anExt.Distance(anIntNum) > Precision::Confusion())
-      continue;
-    Standard_Real aW, aU, aV;
-    anExt.Parameters(anIntNum, aW, aU, aV);
-    gp_Pnt2d aPointOfSurf(aU, aV);
-    // level of the intersection: if it is inside of edge and/or face the level is higher
-    int aIntLevel = aW > aFirstOnCurve && aW < aLastOnCurve ? 2 : 1;
-    BRepClass_FaceClassifier aFClass(aFace, aPointOfSurf, Precision::Confusion());
-    if (aFClass.State() == TopAbs_IN) // "in" is better than "on"
-      aIntLevel += 2;
-    else if (aFClass.State() == TopAbs_ON)
-      aIntLevel += 1;
-    if (aMaxLevel < aIntLevel) {
-      aMaxLevel = anIntNum;
-      anExt.Points(anIntNum, aResult, aResult);
+  GeomAPI_IntCS anIntAlgo(aCurve, aSurf);
+  if (!anIntAlgo.IsDone())
+    return aResult;
+  // searching for points-intersection
+  for(int anIntNum = 1; anIntNum <= anIntAlgo.NbPoints() + anIntAlgo.NbSegments(); anIntNum++) {
+    gp_Pnt anInt;
+    if (anIntNum <= anIntAlgo.NbPoints()) {
+      anInt = anIntAlgo.Point(anIntNum);
+    } else { // take the middle point on the segment of the intersection
+      Handle(Geom_Curve) anIntCurve = anIntAlgo.Segment(anIntNum - anIntAlgo.NbPoints());
+      anIntCurve->D0((anIntCurve->FirstParameter() + anIntCurve->LastParameter()) / 2., anInt);
     }
+    aResult.push_back(std::shared_ptr<GeomAPI_Vertex>(
+      new GeomAPI_Vertex(anInt.X(), anInt.Y(), anInt.Z())));
   }
-  if (aMaxLevel > 0) { // intersection found
-    return std::shared_ptr<GeomAPI_Vertex>(
-      new GeomAPI_Vertex(aResult.X(), aResult.Y(), aResult.Z()));
-  }
-  return std::shared_ptr<GeomAPI_Vertex>(); // no intersection found
+  return aResult;
 }
 
 //==================================================================================================
index 168e076098a486fe4bc4384bd97425ea13cbd745..a7f051a8dfc1f22b7c0166dc770f88dbf38df036 100644 (file)
@@ -137,8 +137,9 @@ public:
   // Computes intersection point between the edge curve and a face surface (only one point, with
   // preferences to point that belongs to edge and face boundaries.
   /// \returns null if there is no intersection
-  GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Vertex> intersect(
-    const std::shared_ptr<GeomAPI_Edge> theEdge, const std::shared_ptr<GeomAPI_Face> theFace);
+  GEOMALGOAPI_EXPORT static std::list<std::shared_ptr<GeomAPI_Vertex> > intersect(
+    const std::shared_ptr<GeomAPI_Edge> theEdge, const std::shared_ptr<GeomAPI_Face> theFace,
+    const bool thePointsOutsideFace);
 
   typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
                    std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
index 065c7971cae650daa565e2e0bfa78f772cec1d26..cc2ad4b0f090eead63aa3bc8e3837ef7f4bb804c 100644 (file)
 
 #include "PartSet_CenterPrs.h"
 
+#include <ModuleBase_Tools.h>
 #include <Geom_CartesianPoint.hxx>
+#include <Prs3d_PointAspect.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
+#include <Prs3d_Root.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <AIS_InteractiveContext.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(PartSet_CenterPrs, AIS_Point)
 
+
 PartSet_CenterPrs::PartSet_CenterPrs(const ObjectPtr& theObject,
                                      const GeomEdgePtr& theEdge,
                                      const gp_Pnt& theCenter,
@@ -38,4 +45,61 @@ PartSet_CenterPrs::PartSet_CenterPrs(const ObjectPtr& theObject,
   myEdge(theEdge),
   myCenterType(theType)
 {
-}
\ No newline at end of file
+  SetAutoHilight(Standard_False);
+}
+
+void PartSet_CenterPrs::drawPoint(const Handle(Prs3d_Presentation)& thePrs,
+                                  Quantity_Color theColor)
+{
+  Handle(Prs3d_Drawer) aDrawer = HilightAttributes();
+
+  Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
+
+  Handle(Graphic3d_AspectMarker3d) PtA = aPntAspect->Aspect();
+  PtA->SetType(Aspect_TOM_RING1);
+  PtA->SetColor(theColor);
+
+  Handle(Geom_Point) aPnt = Component();
+  Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(thePrs);
+  TheGroup->SetPrimitivesAspect(PtA);
+
+  Handle(Graphic3d_ArrayOfPoints) aPoint = new Graphic3d_ArrayOfPoints (1);
+  aPoint->AddVertex(aPnt->X(),aPnt->Y(),aPnt->Z());
+  TheGroup->AddPrimitiveArray(aPoint);
+
+  PtA = new Graphic3d_AspectMarker3d();
+  PtA->SetType(Aspect_TOM_POINT);
+  PtA->SetScale(5.);
+  PtA->SetColor(theColor);
+  TheGroup->SetPrimitivesAspect(PtA);
+  TheGroup->AddPrimitiveArray (aPoint);
+}
+
+void PartSet_CenterPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& PM,
+                                        const SelectMgr_SequenceOfOwner& Seq)
+{
+  Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( PM );
+  aSelectionPrs->Clear();
+
+  drawPoint(aSelectionPrs, GetContext()->SelectionStyle()->Color());
+
+  aSelectionPrs->SetDisplayPriority(9);
+  aSelectionPrs->Display();
+  PM->Color(this, GetContext()->SelectionStyle());
+}
+
+void PartSet_CenterPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM,
+                                              const Handle(Graphic3d_HighlightStyle)& theStyle,
+                                              const Handle(SelectMgr_EntityOwner)& theOwner)
+{
+  Handle( Prs3d_Presentation ) aHilightPrs = GetHilightPresentation( thePM );
+  aHilightPrs->Clear();
+
+  thePM->Color(this, theStyle);
+  drawPoint(aHilightPrs, theStyle->Color());
+
+  aHilightPrs->SetZLayer(Graphic3d_ZLayerId_Topmost);
+
+  if (thePM->IsImmediateModeOn())
+    thePM->AddToImmediateList(aHilightPrs);
+}
index 86e54b24f345f62e11fd06baa0f12a7c41760d06..91a5387cd5a57d3a66f50e613b7809a7664fbf20 100644 (file)
@@ -32,6 +32,7 @@
 #include <AIS_Point.hxx>
 #include <Standard_DefineHandle.hxx>
 #include <gp_Pnt.hxx>
+#include <Geom_Point.hxx>
 
 DEFINE_STANDARD_HANDLE(PartSet_CenterPrs, AIS_Point)
 
@@ -61,9 +62,16 @@ public:
   /// Returns type of the center
   ModelAPI_AttributeSelection::CenterType centerType() const { return myCenterType; }
 
+  virtual void HilightSelected(const Handle(PrsMgr_PresentationManager3d)& PM, const SelectMgr_SequenceOfOwner& Seq);
+  virtual void HilightOwnerWithColor (const Handle(PrsMgr_PresentationManager3d)&,
+                                      const Handle(Graphic3d_HighlightStyle)&,
+                                      const Handle(SelectMgr_EntityOwner)&);
+
   DEFINE_STANDARD_RTTIEXT(PartSet_CenterPrs, AIS_Point)
 
 private:
+  void drawPoint(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor);
+
   ObjectPtr myObject;
   GeomEdgePtr myEdge;
   ModelAPI_AttributeSelection::CenterType myCenterType;
index 1fb666420b538d8451e902480832d87571e5b610..e7ec8b7c75dd03891b82e56f0ad4bde4e7c85cba 100644 (file)
@@ -31,6 +31,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_ConstraintCoincidence.h
     SketchPlugin_ConstraintCollinear.h
     SketchPlugin_ConstraintDistance.h
+    SketchPlugin_ConstraintDistanceAlongDir.h
     SketchPlugin_ConstraintDistanceHorizontal.h
     SketchPlugin_ConstraintDistanceVertical.h
     SketchPlugin_ConstraintEqual.h
@@ -76,6 +77,7 @@ SET(PROJECT_SOURCES
     SketchPlugin_ConstraintCoincidence.cpp
     SketchPlugin_ConstraintCollinear.cpp
     SketchPlugin_ConstraintDistance.cpp
+    SketchPlugin_ConstraintDistanceAlongDir.cpp
     SketchPlugin_ConstraintDistanceHorizontal.cpp
     SketchPlugin_ConstraintDistanceVertical.cpp
     SketchPlugin_ConstraintEqual.cpp
@@ -222,6 +224,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestSignedDistancePointPoint.py
                TestSignedDistancePointLine.py
                Test2273.py
+               Test2280.py
 )
 
 if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.cpp
new file mode 100644 (file)
index 0000000..b0763b5
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright (C) 2017  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+// File:    SketchPlugin_ConstraintDistanceAlongDir.cpp
+// Created: 24 October 2017
+// Author:  Artem ZHIDKOV
+
+#include <SketchPlugin_ConstraintDistanceAlongDir.h>
+
+#include <SketcherPrs_Tools.h>
+#include <SketcherPrs_Factory.h>
+
+#include <GeomAPI_Dir2d.h>
+#include <GeomAPI_XY.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+#include <cmath>
+
+const double tolerance = 1e-7;
+
+
+SketchPlugin_ConstraintDistanceAlongDir::SketchPlugin_ConstraintDistanceAlongDir()
+  : SketchPlugin_ConstraintDistance(),
+    myValue(-1.e100),
+    myValueUpdate(false)
+{
+}
+
+//*************************************************************************************
+void SketchPlugin_ConstraintDistanceAlongDir::initAttributes()
+{
+  data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+
+  data()->addAttribute(LOCATION_TYPE_ID(), ModelAPI_AttributeInteger::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID());
+
+  data()->addAttribute(DISTANCE_VALUE_ID(), ModelAPI_AttributeDouble::typeId());
+
+  data()->addAttribute(NEGATIVE_TYPE_ID(), ModelAPI_AttributeBoolean::typeId());
+  boolean(NEGATIVE_TYPE_ID())->setValue(false);
+}
+
+//*************************************************************************************
+void SketchPlugin_ConstraintDistanceAlongDir::execute()
+{
+  AttributeDoublePtr anAttrValue = real(SketchPlugin_Constraint::VALUE());
+  if (anAttrValue->isInitialized() || !areAttributesInitialized())
+    return;
+
+  double aDistance = calculateCurrentDistance();
+  anAttrValue->setValue(aDistance);
+}
+
+//*************************************************************************************
+AISObjectPtr SketchPlugin_ConstraintDistanceAlongDir::getAISObject(AISObjectPtr thePrevious)
+{
+  if (!sketch())
+    return thePrevious;
+
+  AISObjectPtr anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this,
+                                                                      sketch()->coordinatePlane(),
+                                                                      thePrevious);
+  return anAIS;
+}
+
+void SketchPlugin_ConstraintDistanceAlongDir::attributeChanged(const std::string& theID)
+{
+  if (theID == SketchPlugin_Constraint::ENTITY_A() ||
+      theID == SketchPlugin_Constraint::ENTITY_B())
+  {
+    AttributeDoublePtr aValueAttr = real(SketchPlugin_Constraint::VALUE());
+    if (!aValueAttr->isInitialized() && areAttributesInitialized()) {
+      // only if it is not initialized, try to compute the current value
+      double aDistance = calculateCurrentDistance();
+      aValueAttr->setValue(aDistance);
+    }
+  } else if (theID == SketchPlugin_Constraint::VALUE() && !myValueUpdate) {
+    myValueUpdate = true;
+    // value of the distance shown to the user should be always positive
+    AttributeDoublePtr aDistanceValueAttr = real(DISTANCE_VALUE_ID());
+    double aConstraintValue = real(SketchPlugin_Constraint::VALUE())->value();
+    aDistanceValueAttr->setValue(fabs(aConstraintValue));
+    myValueUpdate = false;
+  } else if (theID == DISTANCE_VALUE_ID() && !myValueUpdate){
+    myValueUpdate = true;
+    // update value of the distance according to the value set by user
+    double aDistanceValue = real(DISTANCE_VALUE_ID())->value();
+    AttributeDoublePtr aConstraintValueAttr = real(SketchPlugin_Constraint::VALUE());
+    if (aConstraintValueAttr->value() < 0.0)
+      aDistanceValue = -aDistanceValue;
+    aConstraintValueAttr->setValue(aDistanceValue);
+    myValueUpdate = false;
+  } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
+    // Recalculate flyout point in local coordinates of the distance constraint:
+    // the X coordinate is a length of projection of the flyout point on the
+    //                  line binding two distanced points
+    //                  or a line of projection of the distanced point onto the distanced segment
+    // the Y coordinate is a distance from the flyout point to the line
+    std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+        attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+    std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
+
+    std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
+    std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
+        data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
+    std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
+        data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
+
+    std::shared_ptr<GeomAPI_XY> aStartPnt = aPointA->pnt()->xy();
+    std::shared_ptr<GeomAPI_XY> aEndPnt = aPointB->pnt()->xy();
+
+    if (aEndPnt->distance(aStartPnt) < tolerance)
+      return;
+
+    std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aEndPnt);
+    myFlyoutUpdate = true;
+    updateFlyoutPoint();
+    myFlyoutUpdate = false;
+  }
+}
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h b/src/SketchPlugin/SketchPlugin_ConstraintDistanceAlongDir.h
new file mode 100644 (file)
index 0000000..bd38dad
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (C) 2017  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
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+// File:    SketchPlugin_ConstraintDistanceAlongDir.h
+// Created: 24 October 2017
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintDistanceAlongDir_H_
+#define SketchPlugin_ConstraintDistanceAlongDir_H_
+
+#include <SketchPlugin.h>
+#include <SketchPlugin_ConstraintDistance.h>
+
+/** \class SketchPlugin_ConstraintDistanceAlongDir
+ *  \ingroup Plugins
+ *  \brief Feature for creation of a new constraint which defines a distance along direction.
+ *         The base class for horizontal and vertical constraints.
+ *
+ *  This constraint has three attributes:
+ *  SketchPlugin_Constraint::VALUE(), SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B()
+ */
+class SketchPlugin_ConstraintDistanceAlongDir : public SketchPlugin_ConstraintDistance
+{
+public:
+  /// attribute name of dimension location type
+  inline static const std::string& LOCATION_TYPE_ID()
+  {
+    static const std::string MY_LOCATION_TYPE_ID("LocationType");
+    return MY_LOCATION_TYPE_ID;
+  }
+
+  /// attribute name of the distance value shown to the user
+  inline static const std::string& DISTANCE_VALUE_ID()
+  {
+    static const std::string& MY_DISTANCE_VALUE("DistanceValue");
+    return MY_DISTANCE_VALUE;
+  }
+
+  /// attribute name of the sign of distance
+  inline static const std::string& NEGATIVE_TYPE_ID()
+  {
+    static const std::string MY_NEGATIVE_VALUE("NegativeValue");
+    return MY_NEGATIVE_VALUE;
+  }
+
+  /// \brief Creates a new part document if needed
+  SKETCHPLUGIN_EXPORT virtual void execute();
+
+  /// \brief Request for initialization of data model of the feature: adding all attributes
+  SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Returns the AIS preview
+  SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
+
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+  /// \brief Use plugin manager for features creation
+  SketchPlugin_ConstraintDistanceAlongDir();
+
+protected:
+  /// Returns the current distance between the feature attributes
+  virtual double calculateCurrentDistance() = 0;
+
+  /// Update flyout point
+  virtual void updateFlyoutPoint() = 0;
+
+protected:
+  double myValue;
+  bool myValueUpdate;
+};
+
+#endif
index 355292413533f48d127d4443380c85af2188e92f..ae3a5e0a56d14da1fa3d762c42653fe8f5b4ae71 100644 (file)
 #include <SketchPlugin_ConstraintDistanceHorizontal.h>
 
 #include <SketcherPrs_Tools.h>
-#include <SketcherPrs_Factory.h>
 
-#include <GeomAPI_Dir2d.h>
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
 
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeInteger.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-const double tolerance = 1e-7;
-
 
 SketchPlugin_ConstraintDistanceHorizontal::SketchPlugin_ConstraintDistanceHorizontal()
-  : SketchPlugin_ConstraintDistance()
-{
-}
-
-//*************************************************************************************
-void SketchPlugin_ConstraintDistanceHorizontal::initAttributes()
-{
-  data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
-
-  data()->addAttribute(SketchPlugin_ConstraintDistanceHorizontal::LOCATION_TYPE_ID(),
-                       ModelAPI_AttributeInteger::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID());
-}
-
-//*************************************************************************************
-void SketchPlugin_ConstraintDistanceHorizontal::execute()
-{
-  AttributeDoublePtr anAttrValue = real(SketchPlugin_Constraint::VALUE());
-  if (anAttrValue->isInitialized() || !areAttributesInitialized())
-    return;
-
-  double aDistance = calculateCurrentDistance();
-  anAttrValue->setValue(aDistance);
-}
-
-//*************************************************************************************
-AISObjectPtr SketchPlugin_ConstraintDistanceHorizontal::getAISObject(AISObjectPtr thePrevious)
+  : SketchPlugin_ConstraintDistanceAlongDir()
 {
-  if (!sketch())
-    return thePrevious;
-
-  AISObjectPtr anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this,
-                                                                      sketch()->coordinatePlane(),
-                                                                      thePrevious);
-  return anAIS;
 }
 
 double SketchPlugin_ConstraintDistanceHorizontal::calculateCurrentDistance()
@@ -92,44 +47,19 @@ double SketchPlugin_ConstraintDistanceHorizontal::calculateCurrentDistance()
   return aPointB->x() - aPointA->x();
 }
 
-void SketchPlugin_ConstraintDistanceHorizontal::attributeChanged(const std::string& theID)
+void SketchPlugin_ConstraintDistanceHorizontal::updateFlyoutPoint()
 {
-  if (theID == SketchPlugin_Constraint::ENTITY_A() ||
-      theID == SketchPlugin_Constraint::ENTITY_B())
-  {
-    AttributeDoublePtr aValueAttr = real(SketchPlugin_Constraint::VALUE());
-    if (!aValueAttr->isInitialized() && areAttributesInitialized()) {
-      // only if it is not initialized, try to compute the current value
-      double aDistance = calculateCurrentDistance();
-      aValueAttr->setValue(aDistance);
-    }
-  } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
-    // Recalculate flyout point in local coordinates of the distance constraint:
-    // the X coordinate is a length of projection of the flyout point on the
-    //                  line binding two distanced points
-    //                  or a line of projection of the distanced point onto the distanced segment
-    // the Y coordinate is a distance from the flyout point to the line
-    std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-        attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
-    std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
+  std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+  std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
 
-    std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
-    std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
-        data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
-    std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
-        data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
-
-    std::shared_ptr<GeomAPI_XY> aStartPnt = aPointA->pnt()->xy();
-    std::shared_ptr<GeomAPI_XY> aEndPnt = aPointB->pnt()->xy();
-    if (aEndPnt->distance(aStartPnt) < tolerance)
-      return;
+  std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
+  std::shared_ptr<GeomDataAPI_Point2D> aEndPoint = SketcherPrs_Tools::getFeaturePoint(
+      data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
 
-    myFlyoutUpdate = true;
-    std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aEndPnt);
-    double X = aFlyoutDir->x(); // Dot on OX axis
-    double Y = aFlyoutDir->y(); // Cross to OX axis
-    aFlyoutAttr->setValue(X, Y);
-    myFlyoutUpdate = false;
-  }
+  std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aEndPoint->pnt()->xy());
+  double X = aFlyoutDir->x(); // Dot on OX axis
+  double Y = aFlyoutDir->y(); // Cross to OX axis
+  aFlyoutAttr->setValue(X, Y);
 }
index c5ddc47fe42e7044cf825520d24e77d6ffd16315..689cf57d329946989954c550543ea6eb7f7168be 100644 (file)
@@ -26,7 +26,7 @@
 #define SketchPlugin_ConstraintDistanceHorizontal_H_
 
 #include <SketchPlugin.h>
-#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintDistanceAlongDir.h>
 
 /** \class SketchPlugin_ConstraintDistanceHorizontal
  *  \ingroup Plugins
@@ -35,7 +35,7 @@
  *  This constraint has three attributes:
  *  SketchPlugin_Constraint::VALUE(), SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B()
  */
-class SketchPlugin_ConstraintDistanceHorizontal : public SketchPlugin_ConstraintDistance
+class SketchPlugin_ConstraintDistanceHorizontal : public SketchPlugin_ConstraintDistanceAlongDir
 {
 public:
   /// Distance constraint kind
@@ -52,33 +52,15 @@ public:
     return MY_KIND;
   }
 
-  /// attribute name of dimension location type
-  inline static const std::string& LOCATION_TYPE_ID()
-  {
-    static const std::string MY_LOCATION_TYPE_ID("LocationType");
-    return MY_LOCATION_TYPE_ID;
-  }
-
-
-  /// \brief Creates a new part document if needed
-  SKETCHPLUGIN_EXPORT virtual void execute();
-
-  /// \brief Request for initialization of data model of the feature: adding all attributes
-  SKETCHPLUGIN_EXPORT virtual void initAttributes();
-
-  /// Returns the AIS preview
-  SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
-
-  /// Called on change of any argument-attribute of this object
-  /// \param theID identifier of changed attribute
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
-
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintDistanceHorizontal();
 
 protected:
   /// Returns the current distance between the feature attributes
   virtual double calculateCurrentDistance();
+
+  /// Update flyout point
+  virtual void updateFlyoutPoint();
 };
 
 #endif
index 8823c3aa06bd25ae252a611e9de489f5d9b7658e..d0dae6161abeed62beb81cd4b83e5434a65e422e 100644 (file)
 #include <SketchPlugin_ConstraintDistanceVertical.h>
 
 #include <SketcherPrs_Tools.h>
-#include <SketcherPrs_Factory.h>
 
-#include <GeomAPI_Dir2d.h>
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
 
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeInteger.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
-const double tolerance = 1e-7;
-
 
 SketchPlugin_ConstraintDistanceVertical::SketchPlugin_ConstraintDistanceVertical()
-  : SketchPlugin_ConstraintDistance()
+  : SketchPlugin_ConstraintDistanceAlongDir()
 {
 }
 
-//*************************************************************************************
-void SketchPlugin_ConstraintDistanceVertical::initAttributes()
-{
-  data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
-  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
-
-  data()->addAttribute(SketchPlugin_ConstraintDistanceVertical::LOCATION_TYPE_ID(),
-                       ModelAPI_AttributeInteger::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATION_TYPE_ID());
-}
-
-//*************************************************************************************
-void SketchPlugin_ConstraintDistanceVertical::execute()
-{
-  AttributeDoublePtr anAttrValue = real(SketchPlugin_Constraint::VALUE());
-  if (anAttrValue->isInitialized() || !areAttributesInitialized())
-    return;
-
-  double aDistance = calculateCurrentDistance();
-  anAttrValue->setValue(aDistance);
-}
-
-//*************************************************************************************
-AISObjectPtr SketchPlugin_ConstraintDistanceVertical::getAISObject(AISObjectPtr thePrevious)
-{
-  if (!sketch())
-    return thePrevious;
-
-  AISObjectPtr anAIS = SketcherPrs_Factory::lengthDimensionConstraint(this,
-                                                                      sketch()->coordinatePlane(),
-                                                                      thePrevious);
-  return anAIS;
-}
-
 double SketchPlugin_ConstraintDistanceVertical::calculateCurrentDistance()
 {
   std::shared_ptr<ModelAPI_Data> aData = data();
@@ -92,45 +47,19 @@ double SketchPlugin_ConstraintDistanceVertical::calculateCurrentDistance()
   return aPointB->y() - aPointA->y();
 }
 
-void SketchPlugin_ConstraintDistanceVertical::attributeChanged(const std::string& theID)
+void SketchPlugin_ConstraintDistanceVertical::updateFlyoutPoint()
 {
-  if (theID == SketchPlugin_Constraint::ENTITY_A() ||
-      theID == SketchPlugin_Constraint::ENTITY_B())
-  {
-    AttributeDoublePtr aValueAttr = real(SketchPlugin_Constraint::VALUE());
-    if (!aValueAttr->isInitialized() && areAttributesInitialized()) {
-      // only if it is not initialized, try to compute the current value
-      double aDistance = calculateCurrentDistance();
-      aValueAttr->setValue(aDistance);
-    }
-  } else if (theID == SketchPlugin_Constraint::FLYOUT_VALUE_PNT() && !myFlyoutUpdate) {
-    // Recalculate flyout point in local coordinates of the distance constraint:
-    // the X coordinate is a length of projection of the flyout point on the
-    //                  line binding two distanced points
-    //                  or a line of projection of the distanced point onto the distanced segment
-    // the Y coordinate is a distance from the flyout point to the line
-    std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-        attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
-    std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
-
-    std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
-    std::shared_ptr<GeomDataAPI_Point2D> aPointA = SketcherPrs_Tools::getFeaturePoint(
-        data(), SketchPlugin_Constraint::ENTITY_A(), aPlane);
-    std::shared_ptr<GeomDataAPI_Point2D> aPointB = SketcherPrs_Tools::getFeaturePoint(
-        data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
+  std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+  std::shared_ptr<GeomAPI_Pnt2d> aFlyoutPnt = aFlyoutAttr->pnt();
 
-    std::shared_ptr<GeomAPI_XY> aStartPnt = aPointA->pnt()->xy();
-    std::shared_ptr<GeomAPI_XY> aEndPnt = aPointB->pnt()->xy();
-
-    if (aEndPnt->distance(aStartPnt) < tolerance)
-      return;
+  std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(sketch());
+  std::shared_ptr<GeomDataAPI_Point2D> aEndPoint = SketcherPrs_Tools::getFeaturePoint(
+      data(), SketchPlugin_Constraint::ENTITY_B(), aPlane);
 
-    std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aEndPnt);
-    myFlyoutUpdate = true;
-    double X =  aFlyoutDir->y(); // Dot on OY axis
-    double Y = -aFlyoutDir->x(); // Cross to OY axis
-    aFlyoutAttr->setValue(X, Y);
-    myFlyoutUpdate = false;
-  }
+  std::shared_ptr<GeomAPI_XY> aFlyoutDir = aFlyoutPnt->xy()->decreased(aEndPoint->pnt()->xy());
+  double X =  aFlyoutDir->y(); // Dot on OY axis
+  double Y = -aFlyoutDir->x(); // Cross to OY axis
+  aFlyoutAttr->setValue(X, Y);
 }
index 1bfb6f144dfae47fb61b3be19ba6de6981597d7d..a9d7284b95c409e29c3883a5f217c5bd67ae9368 100644 (file)
@@ -26,7 +26,7 @@
 #define SketchPlugin_ConstraintDistanceVertical_H_
 
 #include <SketchPlugin.h>
-#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintDistanceAlongDir.h>
 
 /** \class SketchPlugin_ConstraintDistanceVertical
  *  \ingroup Plugins
@@ -35,7 +35,7 @@
  *  This constraint has three attributes:
  *  SketchPlugin_Constraint::VALUE(), SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B()
  */
-class SketchPlugin_ConstraintDistanceVertical : public SketchPlugin_ConstraintDistance
+class SketchPlugin_ConstraintDistanceVertical : public SketchPlugin_ConstraintDistanceAlongDir
 {
 public:
   /// Distance constraint kind
@@ -52,32 +52,15 @@ public:
     return MY_KIND;
   }
 
-  /// attribute name of dimension location type
-  inline static const std::string& LOCATION_TYPE_ID()
-  {
-    static const std::string MY_LOCATION_TYPE_ID("LocationType");
-    return MY_LOCATION_TYPE_ID;
-  }
-
-  /// \brief Creates a new part document if needed
-  SKETCHPLUGIN_EXPORT virtual void execute();
-
-  /// \brief Request for initialization of data model of the feature: adding all attributes
-  SKETCHPLUGIN_EXPORT virtual void initAttributes();
-
-  /// Returns the AIS preview
-  SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
-
-  /// Called on change of any argument-attribute of this object
-  /// \param theID identifier of changed attribute
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
-
   /// \brief Use plugin manager for features creation
   SketchPlugin_ConstraintDistanceVertical();
 
 protected:
   /// Returns the current distance between the feature attributes
   virtual double calculateCurrentDistance();
+
+  /// Update flyout point
+  virtual void updateFlyoutPoint();
 };
 
 #endif
index d67e97c8ce5aeac1bc27bae68b278936df555a24..aedc763322e4c4969e9a362fe366714debcf09d9 100644 (file)
@@ -54,6 +54,7 @@
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
 #include <SketchPlugin_Point.h>
+#include <SketchPlugin_Projection.h>
 
 #include <ModelAPI_EventReentrantMessage.h>
 
@@ -1416,7 +1417,7 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject,
                          std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
     for (int i = 0; i < aSketchComposite->numberOfSubs(); i++) {
       FeaturePtr aFeature = aSketchComposite->subFeature(i);
-      if (aFeature.get())
+      if (aFeature.get() && aFeature->getKind() != SketchPlugin_Projection::ID())
         aFeatures.push_back(aFeature);
     }
     ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
diff --git a/src/SketchPlugin/Test/Test2280.py b/src/SketchPlugin/Test/Test2280.py
new file mode 100644 (file)
index 0000000..d96bf8a
--- /dev/null
@@ -0,0 +1,54 @@
+## Copyright (C) 2014-2017  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
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## 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
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+    Test2280.py
+    Test case for issue #2280 "Trim in the sketch generates a SIGSEGV"
+"""
+
+from salome.shaper import model
+from GeomAPI import GeomAPI_Pnt2d
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Cylinder_1_1/Face_2"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "Cylinder_1_1/Face_1&Cylinder_1_1/Face_2"), True)
+SketchCircle_1 = SketchProjection_1.createdFeature()
+SketchCircle_2 = Sketch_1.addCircle(0.0, 10.0, 8.0)
+model.do()
+
+assert(Sketch_1.feature().error() == "")
+assert(Sketch_1.solverError().value() == "")
+model.testNbSubFeatures(Sketch_1, "SketchArc", 0)
+model.testNbSubFeatures(Sketch_1, "SketchCircle", 2)
+
+# Trim sircle
+SketchTrim_1 = Sketch_1.addTrim(SketchCircle_2, GeomAPI_Pnt2d(0.0, 18.0))
+model.do()
+
+assert(Sketch_1.feature().error() == "")
+assert(Sketch_1.solverError().value() == "")
+model.testNbSubFeatures(Sketch_1, "SketchArc", 1)
+model.testNbSubFeatures(Sketch_1, "SketchCircle", 1)
+
+model.end()
index 35ab1496c62a7d35459e590568951f54a7431421..a38089083b344ab3de2abc200841e464764bc1ba 100644 (file)
@@ -45,6 +45,8 @@ model.do()
 
 # changing the parameter
 for param in range(-30, 31, 2):
+    if param == 0:
+        continue
     DistanceParam.setValue(param)
     model.do()
     dist = secondPoint.x() - firstPoint.x()
@@ -66,6 +68,8 @@ model.do()
 
 # changing the parameter
 for param in range(-30, 31, 2):
+    if param == 0:
+        continue
     DistanceParam.setValue(param)
     model.do()
     dist = secondPoint.y() - firstPoint.y()
index 24278747112d3c0b53efa128acf1c87452511983..29cfb568025fcc4482f30f47de0d864e47ccf611 100644 (file)
@@ -125,7 +125,10 @@ while d >= -30.:
     DISTANCE1 = d
     aDistance.setValue(DISTANCE1)
     aSession.finishOperation()
-    assert math.fabs(horizontalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
+    if DISTANCE1 == 0:
+        assert(aHDist1.error() != "")
+    else:
+        assert math.fabs(horizontalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
     d += dStep
 assert (model.dof(aSketchFeature) == 3)
 
@@ -158,9 +161,12 @@ while d >= -50.:
     DISTANCE2 = d
     aDistance.setValue(DISTANCE2)
     aSession.finishOperation()
-    assert math.fabs(horizontalDistance(anExtCoords, aPoint1Coords) - DISTANCE2) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(anExtCoords, aPoint1Coords), DISTANCE2)
-    assert math.fabs(aPoint1Coords.x() - DISTANCE2) < 1.e-5, "Wrong point coordinates ({}, {}), expected x = {}".format(aPoint1Coords.x(), aPoint1Coords.y(), DISTANCE2)
-    assert math.fabs(horizontalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
+    if DISTANCE2 == 0:
+        assert(aHDist2.error() != "")
+    else:
+        assert math.fabs(horizontalDistance(anExtCoords, aPoint1Coords) - DISTANCE2) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(anExtCoords, aPoint1Coords), DISTANCE2)
+        assert math.fabs(aPoint1Coords.x() - DISTANCE2) < 1.e-5, "Wrong point coordinates ({}, {}), expected x = {}".format(aPoint1Coords.x(), aPoint1Coords.y(), DISTANCE2)
+        assert math.fabs(horizontalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
     d += dStep
 assert (model.dof(aSketchFeature) == 2)
 
@@ -217,7 +223,10 @@ while d >= -50.:
     DISTANCE3 = d
     aDistance.setValue(DISTANCE3)
     aSession.finishOperation()
-    assert math.fabs(horizontalDistance(aStartPoint, aEndPoint) - DISTANCE3) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aStartPoint, aEndPoint), DISTANCE3)
+    if DISTANCE3 == 0:
+        assert(aHDist3.error() != "")
+    else:
+        assert math.fabs(horizontalDistance(aStartPoint, aEndPoint) - DISTANCE3) < 1.e-5, "Distance values are different: {0} != {1}".format(horizontalDistance(aStartPoint, aEndPoint), DISTANCE3)
     d += dStep
 assert (model.dof(aSketchFeature) == 6)
 
index 8910edcbfd5613e5da8b4e631d3d12ab6d63b393..5045080d35512ed3ce1f7206e8a4c5776857979b 100644 (file)
@@ -125,7 +125,10 @@ while d >= -30.:
     DISTANCE1 = d
     aDistance.setValue(DISTANCE1)
     aSession.finishOperation()
-    assert math.fabs(verticalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
+    if DISTANCE1 == 0:
+        assert(aVDist1.error() != "")
+    else:
+        assert math.fabs(verticalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
     d += dStep
 assert (model.dof(aSketchFeature) == 3)
 
@@ -158,9 +161,12 @@ while d >= -50.:
     DISTANCE2 = d
     aDistance.setValue(DISTANCE2)
     aSession.finishOperation()
-    assert math.fabs(verticalDistance(anExtCoords, aPoint1Coords) - DISTANCE2) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(anExtCoords, aPoint1Coords), DISTANCE2)
-    assert math.fabs(aPoint1Coords.y() - DISTANCE2) < 1.e-5, "Wrong point coordinates ({}, {}), expected y = {}".format(aPoint1Coords.x(), aPoint1Coords.y(), DISTANCE2)
-    assert math.fabs(verticalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
+    if DISTANCE2 == 0:
+        assert(aVDist2.error() != "")
+    else:
+        assert math.fabs(verticalDistance(anExtCoords, aPoint1Coords) - DISTANCE2) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(anExtCoords, aPoint1Coords), DISTANCE2)
+        assert math.fabs(aPoint1Coords.y() - DISTANCE2) < 1.e-5, "Wrong point coordinates ({}, {}), expected y = {}".format(aPoint1Coords.x(), aPoint1Coords.y(), DISTANCE2)
+        assert math.fabs(verticalDistance(aPoint1Coords, aPoint2Coords) - DISTANCE1) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aPoint1Coords, aPoint2Coords), DISTANCE1)
     d += dStep
 assert (model.dof(aSketchFeature) == 2)
 
@@ -217,7 +223,10 @@ while d >= -50.:
     DISTANCE3 = d
     aDistance.setValue(DISTANCE3)
     aSession.finishOperation()
-    assert math.fabs(verticalDistance(aStartPoint, aEndPoint) - DISTANCE3) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aStartPoint, aEndPoint), DISTANCE3)
+    if DISTANCE3 == 0:
+        assert(aVDist3.error() != "")
+    else:
+        assert math.fabs(verticalDistance(aStartPoint, aEndPoint) - DISTANCE3) < 1.e-5, "Distance values are different: {0} != {1}".format(verticalDistance(aStartPoint, aEndPoint), DISTANCE3)
     d += dStep
 assert (model.dof(aSketchFeature) == 6)
 
index 2c004c890d6a739d59cd72bd238a6decb7bb5c0d..4372af6457090572f69c3a43ff15a0bcebfb897c 100644 (file)
@@ -703,7 +703,9 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
         </sketch_shape_selector>
         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
 
-        <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed"/>
+        <doublevalue_editor label="Value" tooltip="Distance" id="DistanceValue" default="computed" min="0">
+          <validator id="GeomValidators_Positive"/>
+        </doublevalue_editor>
 
         <module_choice id="LocationType"
           widget_type="radiobuttons"
@@ -745,7 +747,9 @@ email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com
         </sketch_shape_selector>
         <sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
 
-        <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed"/>
+        <doublevalue_editor label="Value" tooltip="Distance" id="DistanceValue" default="computed" min="0">
+          <validator id="GeomValidators_Positive"/>
+        </doublevalue_editor>
 
         <module_choice id="LocationType"
           widget_type="radiobuttons"
index cee80b8b9b29ca6ad1c5abf0738c51feaf654e7d..5f9b54cff59faad8698f26c9d2715c414c016ef8 100644 (file)
@@ -158,7 +158,12 @@ void SketcherPrs_LengthDimension::Compute(
     myPlane = gp_Pln(mySketcherPlane->impl<gp_Ax3>());
 
     DataPtr aData = myConstraint->data();
-    AttributeDoublePtr anAttributeValue = aData->real(SketchPlugin_Constraint::VALUE());
+    AttributeDoublePtr anAttributeValue;
+    if (myConstraint->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
+        myConstraint->getKind() == SketchPlugin_ConstraintDistanceVertical::ID())
+      anAttributeValue = aData->real(SketchPlugin_ConstraintDistanceAlongDir::DISTANCE_VALUE_ID());
+    else
+      anAttributeValue = aData->real(SketchPlugin_Constraint::VALUE());
     myValue.init(anAttributeValue);
   }