]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Constraint Tangent is added
authorazv <azv@opencascade.com>
Tue, 17 Mar 2015 09:18:34 +0000 (12:18 +0300)
committerazv <azv@opencascade.com>
Tue, 17 Mar 2015 09:20:12 +0000 (12:20 +0300)
src/GeomAPI/GeomAPI_Edge.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintTangent.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/Test/TestConstraintTangent.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp

index 759b0b323cb2c90205d2fef862abfe9c3fbc9c97..4b758eb90da225df14b56d7a9cf0e3c519de3ec1 100644 (file)
@@ -46,8 +46,12 @@ bool GeomAPI_Edge::isCircle() const
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
   double aFirst, aLast;
   Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
-  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)) && aCurve->IsClosed())
-    return true;
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)))
+  {
+    // Check the difference of first and last parameters to be equal to the curve period
+    if (Abs(aLast - aFirst - aCurve->Period()) < Precision::PConfusion())
+      return true;
+  }
   return false;
 }
 
@@ -56,8 +60,12 @@ bool GeomAPI_Edge::isArc() const
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
   double aFirst, aLast;
   Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
-  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)) && !aCurve->IsClosed())
-    return true;
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)))
+  {
+    // Check the difference of first and last parameters is not equal the curve period
+    if (Abs(aLast - aFirst - aCurve->Period()) >= Precision::PConfusion())
+      return true;
+  }
   return false;
 }
 
index c34904df28feac13373d0b122e8686f47a9d7ac8..d1499da27b51e7d82a9b6a664318a475d1e4591d 100644 (file)
@@ -25,6 +25,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_ConstraintHorizontal.h
     SketchPlugin_ConstraintVertical.h
     SketchPlugin_ConstraintEqual.h
+    SketchPlugin_ConstraintTangent.h
     SketchPlugin_ShapeValidator.h
     SketchPlugin_Validators.h
     SketchPlugin_ResultValidators.h 
@@ -50,6 +51,7 @@ SET(PROJECT_SOURCES
     SketchPlugin_ConstraintHorizontal.cpp
     SketchPlugin_ConstraintVertical.cpp
     SketchPlugin_ConstraintEqual.cpp
+    SketchPlugin_ConstraintTangent.cpp
     SketchPlugin_ShapeValidator.cpp
     SketchPlugin_Validators.cpp
     SketchPlugin_ResultValidators.cpp
@@ -91,12 +93,14 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestConstraintConcidence.py
                TestConstraintLength.py
                TestConstraintDistance.py
-               TestConstraintParallel.py
+#               TestConstraintParallel.py
                TestConstraintPerpendicular.py
                TestConstraintRadius.py
                TestConstraintRigid.py
                TestConstraintHorizontal.py
                TestConstraintVertical.py
                TestConstraintEqual.py
+               TestConstraintTangent.py
+               TestConstraintParallel.py
                TestHighload.py
                TestSnowflake.py)
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp b/src/SketchPlugin/SketchPlugin_ConstraintTangent.cpp
new file mode 100644 (file)
index 0000000..f2cf4a3
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintTangent.cpp
+// Created: 16 Mar 2015
+// Author:  Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintTangent.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintTangent::SketchPlugin_ConstraintTangent()
+{
+}
+
+void SketchPlugin_ConstraintTangent::initAttributes()
+{
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintTangent::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintTangent::getAISObject(AISObjectPtr thePrevious)
+{
+  if (!sketch())
+    return thePrevious;
+
+  AISObjectPtr anAIS = thePrevious;
+  /// TODO: Tangency constraint presentation should be put here
+  return anAIS;
+}
+
+
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintTangent.h b/src/SketchPlugin/SketchPlugin_ConstraintTangent.h
new file mode 100644 (file)
index 0000000..cb7edd5
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintTangent.h
+// Created: 16 Mar 2015
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintTangent_H_
+#define SketchPlugin_ConstraintTangent_H_
+
+#include "SketchPlugin.h"
+#include <SketchPlugin_Sketch.h>
+#include "SketchPlugin_ConstraintBase.h"
+
+/** \class SketchPlugin_ConstraintTangent
+ *  \ingroup Plugins
+ *  \brief Feature for creation of a new constraint tangency between line and arc 
+ *         or between two circular arcs. The used features must have shared vertex
+ *
+ *  This constraint has two attributes:
+ *  SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B()
+ */
+class SketchPlugin_ConstraintTangent : public SketchPlugin_ConstraintBase
+{
+ public:
+  /// Equal constraint kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_CONSTRAINT_TANGENT_ID("SketchConstraintTangent");
+    return MY_CONSTRAINT_TANGENT_ID;
+  }
+  /// \brief Returns the kind of a feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = SketchPlugin_ConstraintTangent::ID();
+    return MY_KIND;
+  }
+
+  /// \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);
+
+  /// \brief Use plugin manager for features creation
+  SketchPlugin_ConstraintTangent();
+};
+
+#endif
index 5e1ac512c7b8a9e9a975855e3e5f0948f1076003..fd9b04f8ac6331ea67e0bf9f130ae1f6c81d575a 100644 (file)
@@ -15,6 +15,7 @@
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
 #include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
 #include <SketchPlugin_Validators.h>
 #include <SketchPlugin_ResultValidators.h>
@@ -118,6 +119,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new SketchPlugin_ConstraintVertical);
   } else if (theFeatureID == SketchPlugin_ConstraintEqual::ID()) {
     return FeaturePtr(new SketchPlugin_ConstraintEqual);
+  } else if (theFeatureID == SketchPlugin_ConstraintTangent::ID()) {
+    return FeaturePtr(new SketchPlugin_ConstraintTangent);
   }
   // feature of such kind is not found
   return FeaturePtr();
@@ -165,6 +168,7 @@ std::shared_ptr<ModelAPI_FeatureStateMessage> SketchPlugin_Plugin
       aMsg->setState(SketchPlugin_ConstraintHorizontal::ID(), aHasSketchPlane);
       aMsg->setState(SketchPlugin_ConstraintVertical::ID(), aHasSketchPlane);
       aMsg->setState(SketchPlugin_ConstraintEqual::ID(), aHasSketchPlane);
+      aMsg->setState(SketchPlugin_ConstraintTangent::ID(), aHasSketchPlane);
     }
   }
   return aMsg;
diff --git a/src/SketchPlugin/Test/TestConstraintTangent.py b/src/SketchPlugin/Test/TestConstraintTangent.py
new file mode 100644 (file)
index 0000000..2eeb025
--- /dev/null
@@ -0,0 +1,97 @@
+"""
+    TestConstraintTangent.py
+    Unit test of SketchPlugin_ConstraintTangent class
+        
+    SketchPlugin_ConstraintTangent
+        static const std::string MY_CONSTRAINT_TANGENT_ID("SketchConstraintTangent");
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+
+"""
+from GeomDataAPI import *
+from GeomAPI import *
+from ModelAPI import *
+import math
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-17"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Creation of an arc and a line
+#=========================================================================
+# Arc
+aSession.startOperation()
+aSketchArc1 = aSketchFeature.addFeature("SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# Line
+aSession.startOperation()
+aSketchLine1 = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
+aLineStartPoint.setValue(0., 50.)
+aLineEndPoint.setValue(0., 100.)
+aSession.finishOperation()
+#=========================================================================
+# Link arc start point and line's point by the coincidence constraint
+#=========================================================================
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcStartPoint)
+reflistB.setAttr(aLineStartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+#=========================================================================
+# Add tangency constraint and check correctness
+#=========================================================================
+aSession.startOperation()
+aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
+aRefObjectA = aTangency.refattr("ConstraintEntityA")
+aRefObjectB = aTangency.refattr("ConstraintEntityB")
+anObjectA = modelAPI_ResultConstruction(aSketchArc1.firstResult())
+anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+anArcVecX = anArcStartPoint.x() - anArcCentr.x()
+anArcVecY = anArcStartPoint.y() - anArcCentr.y()
+aLineVecX = aLineEndPoint.x() - aLineStartPoint.x()
+aLineVecY = aLineEndPoint.y() - aLineStartPoint.y()
+aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY
+print anArcVecX, anArcVecY
+print aLineVecX, aLineVecY
+print aDot
+print aLineStartPoint.x(), aLineStartPoint.y(), aLineEndPoint.x(), aLineEndPoint.y()
+assert(aDot == 0.)
+#=========================================================================
+# End of test
+#=========================================================================
index b33c14891f2aabc453efe2ad1ed8e58016beafe4..8e88037581390215fa6a20e81f37c199c518bb84 100644 (file)
@@ -5,7 +5,7 @@
     <group id="Basic">
       <feature
         id="Sketch"
-        nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular SketchConstraintRigid SketchConstraintHorizontal SketchConstraintVertical SketchConstraintEqual"
+        nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular SketchConstraintRigid SketchConstraintHorizontal SketchConstraintVertical SketchConstraintEqual SketchConstraintTangent"
         when_nested="accept abort"
         title="Sketch"
         tooltip="Create a new sketch"
             label="Last object" tooltip="Select line, circle or arc" shape_types="edge">
         </sketch_constraint_shape_selector>
       </feature>
+    <!--  SketchConstraintTangent  -->
+      <feature id="SketchConstraintTangent" title="Tangent" tooltip="Create constraint defining tangency of two objects">
+        <sketch_constraint_shape_selector id="ConstraintEntityA" 
+            label="First object" tooltip="Select line or arc" shape_types="edge">
+        </sketch_constraint_shape_selector>
+        
+        <sketch_constraint_shape_selector id="ConstraintEntityB"
+            label="Last object" tooltip="Select line or arc" shape_types="edge">
+        </sketch_constraint_shape_selector>
+      </feature>
     </group>
   </workbench>
 </plugin>
index 980c51879e3574c5c2b008545912f2c6ce3339a6..e4af2a0643970b1518b35cd344566ccaffdce20a 100644 (file)
@@ -20,6 +20,7 @@
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
 #include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
 
 #include <ModelAPI_AttributeRefAttr.h>
@@ -229,8 +230,7 @@ const int& SketchSolver_Constraint::getType(
       std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       AttrType aType = typeOfAttribute(anAttr);
-      if (aType == LINE)
-      {
+      if (aType == LINE) {
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
         aNbLines++;
       }
@@ -242,6 +242,26 @@ const int& SketchSolver_Constraint::getType(
     return getType();
   }
 
+  if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0)
+  {
+    static const int anArcPosDefault = 2;
+    static const int aLinePosDefault = 3;
+    int anArcPos = anArcPosDefault; // arc in tangency constraint should be placed before line
+    int aLinePos = aLinePosDefault;
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      AttrType aType = typeOfAttribute(anAttr);
+      if (aType == LINE && aLinePos < CONSTRAINT_ATTR_SIZE)
+        myAttributesList[aLinePos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+      else if (aType == ARC)
+        myAttributesList[anArcPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+    }
+    if (anArcPos - anArcPosDefault + aLinePos - aLinePosDefault == 2)
+      myType = aLinePos > 3 ? SLVS_C_ARC_LINE_TANGENT : SLVS_C_CURVE_CURVE_TANGENT;
+    return getType();
+  }
+
   /// \todo Implement other kind of constraints
 
   return getType();
index 3cb51724764bb3d49f163e25583e4cb04aa9a209..61299f8a7c0bf55ec19a89dace873b947f581a5a 100644 (file)
@@ -52,6 +52,12 @@ class SketchSolver_Error
     static const std::string MY_ERROR_VALUE("Conflicting constraints");
     return MY_ERROR_VALUE;
   }
+  /// The entities need to have shared point, but they have not
+  inline static const std::string& NO_COINCIDENT_POINTS()
+  {
+    static const std::string MY_ERROR_VALUE("Objects should have coincident point");
+    return MY_ERROR_VALUE;
+  }
 };
 
 /// This value is used to give unique index to the groups
@@ -351,14 +357,50 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
           removeTemporaryConstraints(aTmpConstrToDelete);
       }
     }
+    // For the tangency constraints it is necessary to identify which points of entities are coincident
+    int aSlvsOtherFlag = 0;
+    int aSlvsOther2Flag = 0;
+    if (aConstrType == SLVS_C_ARC_LINE_TANGENT || aConstrType == SLVS_C_CURVE_CURVE_TANGENT) {
+      // Search entities used by constraint
+      int anEnt1Pos = Search(aConstrEnt[2], myEntities);
+      int anEnt2Pos = Search(aConstrEnt[3], myEntities);
+      // Obtain start and end points of entities
+      Slvs_hEntity aPointsToFind[4];
+      aPointsToFind[0] = myEntities[anEnt1Pos].point[1];
+      aPointsToFind[1]= myEntities[anEnt1Pos].point[2];
+      bool hasLine = (myEntities[anEnt2Pos].type == SLVS_E_LINE_SEGMENT);
+      aPointsToFind[2]= myEntities[anEnt2Pos].point[hasLine ? 0 : 1];
+      aPointsToFind[3]= myEntities[anEnt2Pos].point[hasLine ? 1 : 2];
+      // Search coincident points
+      bool isPointFound[4];
+      std::vector<std::set<Slvs_hEntity> >::const_iterator aCPIter = myCoincidentPoints.begin();
+      for ( ; aCPIter != myCoincidentPoints.end(); aCPIter++) {
+        for (int i = 0; i < 4; i++)
+          isPointFound[i] = (aCPIter->find(aPointsToFind[i]) != aCPIter->end());
+        if ((isPointFound[0] || isPointFound[1]) && (isPointFound[2] || isPointFound[3])) {
+          // the arc is tangent by end point
+          if (isPointFound[1]) aSlvsOtherFlag = 1;
+          // the second item is an arc and it is tangent by end point too
+          if (!hasLine && isPointFound[3]) aSlvsOther2Flag = 1;
+          break;
+        }
+      }
+      if (aCPIter == myCoincidentPoints.end()) {
+        // There is no coincident points between tangential objects. Generate error message
+        Events_Error::send(SketchSolver_Error::NO_COINCIDENT_POINTS(), this);
+        return false;
+      }
+    }
 
     // Create SolveSpace constraint structure
-    Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
+    Slvs_Constraint aSlvsConstr = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
                                                       myWorkplane.h, aDistance, aConstrEnt[0],
                                                       aConstrEnt[1], aConstrEnt[2], aConstrEnt[3]);
-    myConstraints.push_back(aConstraint);
-    myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>(1, aConstraint.h);
-    int aConstrPos = Search(aConstraint.h, myConstraints);
+    if (aSlvsOtherFlag != 0) aSlvsConstr.other = aSlvsOtherFlag;
+    if (aSlvsOther2Flag != 0) aSlvsConstr.other2 = aSlvsOther2Flag;
+    myConstraints.push_back(aSlvsConstr);
+    myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>(1, aSlvsConstr.h);
+    int aConstrPos = Search(aSlvsConstr.h, myConstraints);
     aConstrIter = myConstraints.begin() + aConstrPos;
     myNeedToSolve = true;
   } else { // Attributes of constraint may be changed => update constraint