Salome HOME
Implement the Collinear constraint
authorazv <azv@opencascade.com>
Thu, 28 Jan 2016 10:39:36 +0000 (13:39 +0300)
committerdbv <dbv@opencascade.com>
Tue, 16 Feb 2016 14:04:31 +0000 (17:04 +0300)
17 files changed:
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_Validators.h
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/collinear.png [new file with mode: 0644]
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintCollinear.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/Test/TestConstraintCollinear.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_IConstraintWrapper.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp

index 47fa2a04f5d5d5f71da9630ad4c7816bfcef7306..124766058ad16f32fe557039438a8bd52a973703 100755 (executable)
@@ -202,6 +202,7 @@ void PartSet_Module::registerValidators()
   aFactory->registerValidator("PartSet_FilletSelection", new PartSet_FilletSelection);
   aFactory->registerValidator("PartSet_AngleSelection", new PartSet_AngleSelection);
   aFactory->registerValidator("PartSet_EqualSelection", new PartSet_EqualSelection);
+  aFactory->registerValidator("PartSet_CollinearSelection", new PartSet_CollinearSelection);
   aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator);
   aFactory->registerValidator("PartSet_CoincidentAttr", new PartSet_CoincidentAttr);
   aFactory->registerValidator("PartSet_SketchEntityValidator", new PartSet_SketchEntityValidator);
index b446bab1642528b4922b8ce7e84956f677309445..a81557ac4b05a6e3c8bddb48c321a4b849b17ab0 100755 (executable)
@@ -314,6 +314,16 @@ bool PartSet_EqualSelection::isValid(const ModuleBase_ISelection* theSelection,
   }
 }
 
+bool PartSet_CollinearSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const
+{
+  if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) {
+    return isEmptySelectionValid(theOperation);
+  } else {
+    int aCount = shapesNbLines(theSelection);
+    return (aCount > 0) && (aCount < 3);
+  }
+}
+
 
 std::string PartSet_DifferentObjectsValidator::errorMessage(
                          const PartSet_DifferentObjectsValidator::ErrorType& theType,
index 36f78e031d894dddfc382d1b3f78a99abb006724..05e90f05f6302232dc859842752cffdafaad9ada 100644 (file)
@@ -115,6 +115,14 @@ public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const;
 };
 
+//! \ingroup Validators
+//! A class to validate a selection for Collinear constraints operation
+class PartSet_CollinearSelection : public ModuleBase_SelectionValidator
+{
+public:
+  PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const;
+};
+
 ////////////// Attribute validators ////////////////
 
 
index 7fac03ac44250b64bd566247e6d1a7e88bf386ce..9b674aea94604e648a6530d59fd8a4a811b300af 100644 (file)
@@ -82,5 +82,6 @@
      <file>icons/bool_fuse.png</file>
      <file>icons/bool_common.png</file>
      <file>icons/plane_view.png</file>
+     <file>icons/collinear.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/collinear.png b/src/PartSet/icons/collinear.png
new file mode 100644 (file)
index 0000000..18c6dbe
Binary files /dev/null and b/src/PartSet/icons/collinear.png differ
index 2ef3a06b4e76bc02489d58bb1f68d325937a45af..a44cf0623a6d347a9cb28a5f85b9f5d9b020f565 100644 (file)
@@ -16,6 +16,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_Constraint.h
     SketchPlugin_ConstraintBase.h
     SketchPlugin_ConstraintCoincidence.h
+    SketchPlugin_ConstraintCollinear.h
     SketchPlugin_ConstraintDistance.h
     SketchPlugin_ConstraintLength.h
     SketchPlugin_ConstraintParallel.h
@@ -48,6 +49,7 @@ SET(PROJECT_SOURCES
     SketchPlugin_Constraint.cpp
     SketchPlugin_ConstraintBase.cpp
     SketchPlugin_ConstraintCoincidence.cpp
+    SketchPlugin_ConstraintCollinear.cpp
     SketchPlugin_ConstraintDistance.cpp
     SketchPlugin_ConstraintLength.cpp
     SketchPlugin_ConstraintParallel.cpp
@@ -101,6 +103,7 @@ INSTALL(FILES ${XML_RESOURCES} DESTINATION plugins)
 ADD_UNIT_TESTS(TestSketchPointLine.py
                TestSketchArcCircle.py
                TestConstraintConcidence.py
+               TestConstraintCollinear.py
                TestConstraintLength.py
                TestConstraintDistance.py
                TestConstraintParallel.py
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp
new file mode 100644 (file)
index 0000000..75da202
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintCollinear.cpp
+// Created: 26 May 2014
+// Author:  Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintCollinear.h"
+
+SketchPlugin_ConstraintCollinear::SketchPlugin_ConstraintCollinear()
+{
+}
+
+void SketchPlugin_ConstraintCollinear::initAttributes()
+{
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+}
+
+void SketchPlugin_ConstraintCollinear::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintCollinear::getAISObject(AISObjectPtr thePrevious)
+{
+  if (!sketch())
+    return thePrevious;
+
+  AISObjectPtr anAIS = thePrevious;
+  if (!anAIS) {
+    // TODO
+    //anAIS = SketcherPrs_Factory::collinearConstraint(this, sketch()->coordinatePlane());
+  }
+  return anAIS;
+}
+
+
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintCollinear.h b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.h
new file mode 100644 (file)
index 0000000..db8db73
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintCollinear.h
+// Created: 27 Jan 2016
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintCollinear_H_
+#define SketchPlugin_ConstraintCollinear_H_
+
+#include "SketchPlugin.h"
+#include <SketchPlugin_Sketch.h>
+#include "SketchPlugin_ConstraintBase.h"
+
+/** \class SketchPlugin_ConstraintCollinear
+ *  \ingroup Plugins
+ *  \brief Feature for creation of a new constraint collinearity of two lines
+ *
+ *  This constraint has two attributes:
+ *  SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B()
+ */
+class SketchPlugin_ConstraintCollinear : public SketchPlugin_ConstraintBase
+{
+ public:
+  /// Parallel constraint kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_CONSTRAINT_COLLINEAR_ID("SketchConstraintCollinear");
+    return MY_CONSTRAINT_COLLINEAR_ID;
+  }
+  /// \brief Returns the kind of a feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = SketchPlugin_ConstraintCollinear::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_ConstraintCollinear();
+};
+
+#endif
index 06a3d570257e14ff0a9163602e8e8331d2219db5..0119d3b633ead0527249ba168aaca5ecc1f1c3a3 100644 (file)
@@ -8,6 +8,7 @@
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintCollinear.h>
 #include <SketchPlugin_ConstraintDistance.h>
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintFillet.h>
@@ -113,6 +114,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new SketchPlugin_Arc);
   } else if (theFeatureID == SketchPlugin_ConstraintCoincidence::ID()) {
     return FeaturePtr(new SketchPlugin_ConstraintCoincidence);
+  } else if (theFeatureID == SketchPlugin_ConstraintCollinear::ID()) {
+    return FeaturePtr(new SketchPlugin_ConstraintCollinear);
   } else if (theFeatureID == SketchPlugin_ConstraintDistance::ID()) {
     return FeaturePtr(new SketchPlugin_ConstraintDistance);
   } else if (theFeatureID == SketchPlugin_ConstraintLength::ID()) {
diff --git a/src/SketchPlugin/Test/TestConstraintCollinear.py b/src/SketchPlugin/Test/TestConstraintCollinear.py
new file mode 100644 (file)
index 0000000..46bd273
--- /dev/null
@@ -0,0 +1,102 @@
+"""
+    TestConstraintCollinear.py
+    Unit test of SketchPlugin_ConstraintCollinear class
+        
+    SketchPlugin_ConstraintCollinear
+        static const std::string MY_CONSTRAINT_COLLINEAR_ID("SketchConstraintCollinear");
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2016-01-28"
+
+
+def checkCollinearVec(theX1, theY1, theX2, theY2):
+    TOL = 1.e-6
+    aLen1 = math.hypot(theX1, theY1)
+    aLen2 = math.hypot(theX2, theY2)
+    aDot = theX1 * theX2 + theY1 * theY2
+    assert math.fabs(math.fabs(aDot) - aLen1 * aLen2) < TOL**2, "aDot = {0}, aLen1 = {1}, aLen2 = {2}, aDiff = {3}".format(aDot, aLen1, aLen2, math.fabs(aDot) - aLen1 * aLen2)
+
+def checkCollinear(theLine1, theLine2):
+    aStartPoint1 = geomDataAPI_Point2D(theLine1.attribute("StartPoint"))
+    aEndPoint1   = geomDataAPI_Point2D(theLine1.attribute("EndPoint"))
+    aStartPoint2 = geomDataAPI_Point2D(theLine2.attribute("StartPoint"))
+    aEndPoint2   = geomDataAPI_Point2D(theLine2.attribute("EndPoint"))
+    
+    aDir1x, aDir1y = aEndPoint1.x() - aStartPoint1.x(), aEndPoint1.y() - aStartPoint1.y()
+    aDir2x, aDir2y = aEndPoint2.x() - aStartPoint1.x(), aEndPoint2.y() - aStartPoint1.y()
+    aDir3x, aDir3y = aStartPoint2.x() - aStartPoint1.x(), aStartPoint2.y() - aStartPoint1.y()
+    checkCollinearVec(aDir1x, aDir1y, aDir2x, aDir2y)
+    checkCollinearVec(aDir1x, aDir1y, aDir3x, aDir3y)
+
+
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Create two lines
+#=========================================================================
+aSession.startOperation()
+# line A
+aSketchLineA = aSketchFeature.addFeature("SketchLine")
+aLineAStartPoint = geomDataAPI_Point2D(aSketchLineA.attribute("StartPoint"))
+aLineAEndPoint = geomDataAPI_Point2D(aSketchLineA.attribute("EndPoint"))
+aSketchLineB = aSketchFeature.addFeature("SketchLine")
+aLineAStartPoint.setValue(0., 25)
+aLineAEndPoint.setValue(85., 25)
+# line B
+aLineBStartPoint = geomDataAPI_Point2D(aSketchLineB.attribute("StartPoint"))
+aLineBEndPoint = geomDataAPI_Point2D(aSketchLineB.attribute("EndPoint"))
+aLineBStartPoint.setValue(0., 50)
+aLineBEndPoint.setValue(80., 75)
+aSession.finishOperation()
+#=========================================================================
+# Link lines with collinear constraint
+#=========================================================================
+aSession.startOperation()
+aParallelConstraint = aSketchFeature.addFeature("SketchConstraintCollinear")
+refattrA = aParallelConstraint.refattr("ConstraintEntityA")
+refattrB = aParallelConstraint.refattr("ConstraintEntityB")
+refattrA.setObject(aSketchLineA.firstResult())
+refattrB.setObject(aSketchLineB.firstResult())
+aParallelConstraint.execute()
+aSession.finishOperation()
+checkCollinear(aSketchLineA, aSketchLineB)
+#=========================================================================
+# Check values and move one constrainted object
+#=========================================================================
+deltaX = deltaY = 10.
+# rotate line, check that reference's line points are moved also
+aLineBStartPointPrev = (aLineBStartPoint.x(), aLineBStartPoint.y())
+aLineBEndPointPrev = (aLineBEndPoint.x(), aLineBEndPoint.y())
+aSession.startOperation()
+aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX,
+                          aLineAStartPoint.y() + deltaY)
+aLineAEndPoint.setValue(aLineAEndPoint.x() - deltaX,
+                        aLineAEndPoint.y() - deltaY)
+aSession.finishOperation()
+checkCollinear(aSketchLineA, aSketchLineB)
+#=========================================================================
+# End of test
+#=========================================================================
index fd1d6f4e5caa3697d81f0198514070285a970219..6b7233f6ce54e62dd12df17a891a4fc9c0d58091 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 SketchConstraintTangent SketchConstraintFillet SketchConstraintCoincidence SketchConstraintMirror SketchConstraintAngle SketchMultiRotation SketchMultiTranslation"
+        nested="SketchPoint SketchLine SketchCircle SketchArc SketchConstraintLength SketchConstraintRadius SketchConstraintDistance SketchConstraintParallel SketchConstraintPerpendicular SketchConstraintRigid SketchConstraintHorizontal SketchConstraintVertical SketchConstraintEqual SketchConstraintTangent SketchConstraintFillet SketchConstraintCoincidence SketchConstraintMirror SketchConstraintAngle SketchMultiRotation SketchMultiTranslation SketchConstraintCollinear"
         when_nested="accept abort"
         title="Sketch"
         tooltip="Create sketch"
         </sketch_shape_selector>
         <validator id="PartSet_TangentSelection"/>
       </feature>
+      
+    <!--  SketchConstraintCollinear  -->
+      <feature id="SketchConstraintCollinear" title="Collinear" tooltip="Create constraint defining collinearity of two lines" icon=":icons/collinear.png">
+        <sketch_shape_selector id="ConstraintEntityA" 
+            label="First line" tooltip="Select a line" shape_types="edge">
+          <validator id="GeomValidators_ShapeType" parameters="line"/>
+          <validator id="PartSet_DifferentObjects"/>
+        </sketch_shape_selector>
+        
+        <sketch_shape_selector id="ConstraintEntityB"
+            label="Second line" tooltip="Select a line" shape_types="edge">
+          <validator id="GeomValidators_ShapeType" parameters="line"/>
+          <validator id="PartSet_DifferentObjects"/>
+        </sketch_shape_selector>
+        <validator id="PartSet_CollinearSelection"/>
+      </feature>
          
     </group>
     
index 95e01be607b8598a7a2b81e7642bb3f3e08283d8..9cc222f580223ed0cbb50e33ac7787ae8e8305eb 100644 (file)
@@ -128,6 +128,11 @@ static ConstraintWrapperPtr
                           const SketchSolver_ConstraintType& theType,
                           std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity1,
                           std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity2);
+static ConstraintWrapperPtr
+  createConstraintCollinear(ConstraintPtr theConstraint,
+                           const GroupID& theGroupID,
+                           std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity1,
+                           std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity2);
 
 
 
@@ -247,6 +252,10 @@ std::list<ConstraintWrapperPtr> PlaneGCSSolver_Builder::createConstraint(
     aResult = createConstraintTangent(theConstraint, theGroupID, theType,
                   GCS_ENTITY_WRAPPER(theEntity1), GCS_ENTITY_WRAPPER(theEntity2));
     break;
+  case CONSTRAINT_COLLINEAR:
+    aResult = createConstraintCollinear(theConstraint, theGroupID,
+                  GCS_ENTITY_WRAPPER(theEntity1), GCS_ENTITY_WRAPPER(theEntity2));
+    break;
   case CONSTRAINT_MULTI_TRANSLATION:
   case CONSTRAINT_MULTI_ROTATION:
     break;
@@ -909,6 +918,29 @@ ConstraintWrapperPtr createConstraintHorizVert(
   return aResult;
 }
 
+ConstraintWrapperPtr createConstraintCollinear(
+    ConstraintPtr theConstraint,
+    const GroupID& theGroupID,
+    std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity1,
+    std::shared_ptr<PlaneGCSSolver_EntityWrapper> theEntity2)
+{
+  std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
+  std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
+
+  // create two point-on-line constraints
+  std::list<GCSConstraintPtr> aConstrList;
+  aConstrList.push_back( GCSConstraintPtr(new GCS::ConstraintPointOnLine(aLine2->p1, *aLine1)) );
+  aConstrList.push_back( GCSConstraintPtr(new GCS::ConstraintPointOnLine(aLine2->p2, *aLine1)) );
+
+  ConstraintWrapperPtr aResult(new PlaneGCSSolver_ConstraintWrapper(
+      theConstraint, aConstrList, CONSTRAINT_COLLINEAR));
+  aResult->setGroup(theGroupID);
+  std::list<EntityWrapperPtr> aSubs(1, theEntity1);
+  aSubs.push_back(theEntity2);
+  aResult->setEntities(aSubs);
+  return aResult;
+}
+
 ConstraintWrapperPtr createConstraintParallel(
     ConstraintPtr theConstraint,
     const GroupID& theGroupID,
index 625d1ccf1b04ed795627ccf9ead18c8e962f7a2b..19d1b321b8b6f35603d6185783b1da7a52a55934 100644 (file)
@@ -306,8 +306,11 @@ void PlaneGCSSolver_Storage::changeGroup(EntityWrapperPtr theEntity, const Group
   theEntity->setGroup(theGroup);
   if (theGroup == myGroupID)
     makeVariable(theEntity);
-  else
+  else {
+    if (theEntity->type() == ENTITY_POINT)
+      update(theEntity);
     makeConstant(theEntity);
+  }
 }
 
 void PlaneGCSSolver_Storage::changeGroup(ParameterWrapperPtr theParam, const GroupID& theGroup)
@@ -382,6 +385,8 @@ void PlaneGCSSolver_Storage::processArc(const EntityWrapperPtr& theArc)
 void PlaneGCSSolver_Storage::makeConstant(const EntityWrapperPtr& theEntity)
 {
   toggleEntity(theEntity, myParameters, myConst);
+  if (theEntity->type() == ENTITY_POINT)
+    updateCoincident(theEntity);
 }
 
 void PlaneGCSSolver_Storage::makeVariable(const EntityWrapperPtr& theEntity)
@@ -423,6 +428,32 @@ void PlaneGCSSolver_Storage::toggleEntity(
   }
 }
 
+void PlaneGCSSolver_Storage::updateCoincident(const EntityWrapperPtr& thePoint)
+{
+  CoincidentPointsMap::iterator anIt = myCoincidentPoints.begin();
+  for (; anIt != myCoincidentPoints.end(); ++anIt) {
+    if (anIt->first == thePoint || anIt->second.find(thePoint) != anIt->second.end()) {
+      std::set<EntityWrapperPtr> aCoincident = anIt->second;
+      aCoincident.insert(anIt->first);
+
+      const std::list<ParameterWrapperPtr>& aBaseParams = thePoint->parameters();
+      std::list<ParameterWrapperPtr> aParams;
+      std::list<ParameterWrapperPtr>::const_iterator aBaseIt, anUpdIt;
+
+      std::set<EntityWrapperPtr>::const_iterator aCoincIt = aCoincident.begin();
+      for (; aCoincIt != aCoincident.end(); ++aCoincIt)
+        if (*aCoincIt != thePoint && (*aCoincIt)->group() != GID_OUTOFGROUP) {
+          aParams = (*aCoincIt)->parameters();
+          aBaseIt = aBaseParams.begin();
+          for (anUpdIt = aParams.begin(); anUpdIt != aParams.end(); ++anUpdIt, ++aBaseIt)
+            (*anUpdIt)->setValue((*aBaseIt)->value());
+        }
+
+      break;
+    }
+  }
+}
+
 
 void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
 {
index f13d158ebfbb35c7248d59c68fcb77089e3f5f8a..45d8d0c5b39e19b194ee81f666b75ce9e2cf2296 100644 (file)
@@ -100,6 +100,9 @@ private:
   /// \param theArc [in]  updated arc
   void processArc(const EntityWrapperPtr& theArc);
 
+  /// \brief Adjust parameters of points coincident with the given
+  void updateCoincident(const EntityWrapperPtr& thePoint);
+
 private:
   GCS::VEC_pD                      myParameters;         ///< list of parameters
   GCS::VEC_pD                      myConst;              ///< list of constants
index b7d928e805d3f81ddcbffc638021ed7ba9e95935..47ec0fdb3beb37bb8cfa6853c2f0007b09064771 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <SketchPlugin_ConstraintAngle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintCollinear.h>
 #include <SketchPlugin_ConstraintDistance.h>
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintHorizontal.h>
@@ -79,6 +80,8 @@ SketchSolver_ConstraintType SketchSolver_Constraint::TYPE(ConstraintPtr theConst
     return CONSTRAINT_RADIUS;
   else if (aType == SketchPlugin_ConstraintTangent::ID())
     return CONSTRAINT_TANGENT;
+  else if (aType == SketchPlugin_ConstraintCollinear::ID())
+    return CONSTRAINT_COLLINEAR;
   return CONSTRAINT_UNKNOWN;
 }
 
index 01020e9231681957cf7fa0c6fcae559876415cf9..fcd0c597a3bb8c41e7e09ab2940960695d6c804d 100644 (file)
@@ -40,6 +40,7 @@ enum SketchSolver_ConstraintType {
   CONSTRAINT_TANGENT_ARC_LINE,
   CONSTRAINT_TANGENT_CIRCLE_LINE,
   CONSTRAINT_TANGENT_ARC_ARC,
+  CONSTRAINT_COLLINEAR,
   CONSTRAINT_MULTI_TRANSLATION,
   CONSTRAINT_MULTI_ROTATION
 };
index 11b634a89b13d6da105b76f106bb03dbac91ec31..01b747804e4d089b0c46caa59125cbe5bc6f8607 100644 (file)
@@ -107,6 +107,25 @@ std::list<ConstraintWrapperPtr> SolveSpaceSolver_Builder::createConstraint(
     return createConstraint(theConstraint, theGroupID, theSketchID,
         CONSTRAINT_PT_LINE_DISTANCE, aRadius->value(), aCenter, EntityWrapperPtr(), theEntity2);
   }
+  else if (theType == CONSTRAINT_COLLINEAR) {
+    // replace by two constraints point-on-line
+    std::list<ConstraintWrapperPtr> aConstraints;
+    const std::list<EntityWrapperPtr>& aSubs1 = theEntity1->subEntities();
+    const std::list<EntityWrapperPtr>& aSubs2 = theEntity2->subEntities();
+    std::list<EntityWrapperPtr>::const_iterator anIt1, anIt2;
+    for (anIt2 = aSubs2.begin(); anIt2 != aSubs2.end(); ++anIt2) {
+      for (anIt1 = aSubs1.begin(); anIt1 != aSubs1.end(); ++anIt1)
+        if ((*anIt1)->id() == (*anIt2)->id())
+          break;
+      if (anIt1 != aSubs1.end())
+        continue; // the lines have coincident point
+
+      std::list<ConstraintWrapperPtr> aC = createConstraint(theConstraint, theGroupID,
+          theSketchID, CONSTRAINT_PT_ON_LINE, theValue, *anIt2, EntityWrapperPtr(), theEntity1);
+      aConstraints.insert(aConstraints.end(), aC.begin(), aC.end());
+    }
+    return aConstraints;
+  }
 
   int aType = ConstraintType::toSolveSpace(theType);
   if (aType == SLVS_C_UNKNOWN)