From 71661288cbd8d2c0f5ae6d1cc45e07e6783c38e9 Mon Sep 17 00:00:00 2001 From: azv Date: Thu, 28 Jan 2016 13:39:36 +0300 Subject: [PATCH] Implement the Collinear constraint --- src/PartSet/PartSet_Module.cpp | 1 + src/PartSet/PartSet_Validators.cpp | 10 ++ src/PartSet/PartSet_Validators.h | 8 ++ src/PartSet/PartSet_icons.qrc | 1 + src/PartSet/icons/collinear.png | Bin 0 -> 414 bytes src/SketchPlugin/CMakeLists.txt | 3 + .../SketchPlugin_ConstraintCollinear.cpp | 36 +++++++ .../SketchPlugin_ConstraintCollinear.h | 50 +++++++++ src/SketchPlugin/SketchPlugin_Plugin.cpp | 3 + .../Test/TestConstraintCollinear.py | 102 ++++++++++++++++++ src/SketchPlugin/plugin-Sketch.xml | 18 +++- .../PlaneGCSSolver/PlaneGCSSolver_Builder.cpp | 32 ++++++ .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 33 +++++- .../PlaneGCSSolver/PlaneGCSSolver_Storage.h | 3 + src/SketchSolver/SketchSolver_Constraint.cpp | 3 + .../SketchSolver_IConstraintWrapper.h | 1 + .../SolveSpaceSolver_Builder.cpp | 19 ++++ 17 files changed, 321 insertions(+), 2 deletions(-) create mode 100644 src/PartSet/icons/collinear.png create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintCollinear.h create mode 100644 src/SketchPlugin/Test/TestConstraintCollinear.py diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 47fa2a04f..124766058 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -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); diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index b446bab16..a81557ac4 100755 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -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, diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index 36f78e031..05e90f05f 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -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 //////////////// diff --git a/src/PartSet/PartSet_icons.qrc b/src/PartSet/PartSet_icons.qrc index 7fac03ac4..9b674aea9 100644 --- a/src/PartSet/PartSet_icons.qrc +++ b/src/PartSet/PartSet_icons.qrc @@ -82,5 +82,6 @@ icons/bool_fuse.png icons/bool_common.png icons/plane_view.png + icons/collinear.png diff --git a/src/PartSet/icons/collinear.png b/src/PartSet/icons/collinear.png new file mode 100644 index 0000000000000000000000000000000000000000..18c6dbe26e2444d691b7802e22735c00b5274c76 GIT binary patch literal 414 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHh#u42Ox-))egq1_nlLPZ!4!i_=pt*?S*$kU0MF{aw{w zm%;*%w3n}}Up$Zx66l_=PvUu3_ktf$B}JKRUt=vSEIegd7G8}yW2?7wLfbVncK02p zYv=vGtJ=ZQYt6&rvcR$~o7J4pTrc4Gdg+HBZ~eIZS#R|Z%R8@JJ$LODo2OM9dh~tW zYH8J#@~SH@t;w*z6~mr%{>~58J8#~;ozKI_yhdYzNaKxetvvr@-;WxwZ}~3I#+1O- zBERo`rvI_XR9C(mt(=eY>H`wEC0zEEr)^%d?F^HKU}VdAMz@=D`%mOgT=uk#wPel` z%Z9i%#z!h|uPAXV#2mqz`=})-x2*i9J||>pAn5<-mUhP^Dcw_zp%hbVXNgB z`5Uy9nH#riw5&7}c|RvGj@SO|-0gp)Pp>vQn!0QGA4Ziz<&eMO>MwvH$>8bg=d#Wz Gp$Pyt%cyn$ literal 0 HcmV?d00001 diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index 2ef3a06b4..a44cf0623 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -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 index 000000000..75da202f1 --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.cpp @@ -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 index 000000000..db8db738b --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintCollinear.h @@ -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 +#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 diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 06a3d5702..0119d3b63 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -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 index 000000000..46bd27340 --- /dev/null +++ b/src/SketchPlugin/Test/TestConstraintCollinear.py @@ -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 +#========================================================================= diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index fd1d6f4e5..6b7233f6c 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -5,7 +5,7 @@ + + + + + + + + + + + + + + diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp index 95e01be60..9cc222f58 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp @@ -128,6 +128,11 @@ static ConstraintWrapperPtr const SketchSolver_ConstraintType& theType, std::shared_ptr theEntity1, std::shared_ptr theEntity2); +static ConstraintWrapperPtr + createConstraintCollinear(ConstraintPtr theConstraint, + const GroupID& theGroupID, + std::shared_ptr theEntity1, + std::shared_ptr theEntity2); @@ -247,6 +252,10 @@ std::list 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 theEntity1, + std::shared_ptr theEntity2) +{ + std::shared_ptr aLine1 = std::dynamic_pointer_cast(theEntity1->entity()); + std::shared_ptr aLine2 = std::dynamic_pointer_cast(theEntity2->entity()); + + // create two point-on-line constraints + std::list 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 aSubs(1, theEntity1); + aSubs.push_back(theEntity2); + aResult->setEntities(aSubs); + return aResult; +} + ConstraintWrapperPtr createConstraintParallel( ConstraintPtr theConstraint, const GroupID& theGroupID, diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 625d1ccf1..19d1b321b 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -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 aCoincident = anIt->second; + aCoincident.insert(anIt->first); + + const std::list& aBaseParams = thePoint->parameters(); + std::list aParams; + std::list::const_iterator aBaseIt, anUpdIt; + + std::set::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) { diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h index f13d158eb..45d8d0c5b 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h @@ -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 diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index b7d928e80..47ec0fdb3 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -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; } diff --git a/src/SketchSolver/SketchSolver_IConstraintWrapper.h b/src/SketchSolver/SketchSolver_IConstraintWrapper.h index 01020e923..fcd0c597a 100644 --- a/src/SketchSolver/SketchSolver_IConstraintWrapper.h +++ b/src/SketchSolver/SketchSolver_IConstraintWrapper.h @@ -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 }; diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp index 11b634a89..01b747804 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp @@ -107,6 +107,25 @@ std::list 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 aConstraints; + const std::list& aSubs1 = theEntity1->subEntities(); + const std::list& aSubs2 = theEntity2->subEntities(); + std::list::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 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) -- 2.30.2