aBaseIter->point[2],
SLVS_E_UNKNOWN};
Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point
- aBaseIter->point[2],
- aBaseIter->point[1],
+ aMirrorIter->point[2],
+ aMirrorIter->point[1],
SLVS_E_UNKNOWN};
Slvs_Entity aBothArcs[2] = {*aBaseIter, *aMirrorIter};
aMirrorPoint[2] = aMirrorPoint[1];
aMirrorPoint[1] = aTmp;
}
+ if (theBase.type == SLVS_E_POINT_IN_2D || theBase.type == SLVS_E_POINT_IN_3D) {
+ aBasePoint[0] = theBase.h;
+ aMirrorPoint[0] = theMirror.h;
+ }
// Mirror line parameters
std::shared_ptr<GeomAPI_XY> aLinePoints[2];
}
}
+void SketchSolver_ConstraintMirror::adjustConstraint()
+{
+ // Search mirror between middle points on the arcs and recompute their coordinates
+ std::list<Slvs_Constraint> aPonCirc = myStorage->getConstraintsByType(SLVS_C_PT_ON_CIRCLE);
+ if (aPonCirc.empty())
+ return;
+
+ AttributeRefAttrPtr aMirLineAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if (!aMirLineAttr || !aMirLineAttr->isInitialized() || !aMirLineAttr->isObject()) {
+ myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
+ return;
+ }
+ ResultConstructionPtr aRC =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aMirLineAttr->object());
+ FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
+ std::dynamic_pointer_cast<ModelAPI_Feature>(aMirLineAttr->object());
+ std::map<FeaturePtr, Slvs_hEntity>::iterator aMirLineIter = myFeatureMap.find(aFeature);
+ if (aMirLineIter == myFeatureMap.end())
+ return;
+ Slvs_Entity aMirrorLine = myStorage->getEntity(aMirLineIter->second);
+
+ double aStartEnd[4];
+ for (int i = 0; i < 2; i++) {
+ Slvs_Entity aPoint = myStorage->getEntity(aMirrorLine.point[i]);
+ for (int j = 0; j < 2; j++)
+ aStartEnd[2*i+j] = myStorage->getParameter(aPoint.param[j]).val;
+ }
+
+ Slvs_Constraint aMirror;
+ std::vector<Slvs_hConstraint>::iterator aConstrIter = mySlvsConstraints.begin();
+ for (; aConstrIter != mySlvsConstraints.end(); aConstrIter++) {
+ aMirror = myStorage->getConstraint(*aConstrIter);
+ if (aMirror.type != SLVS_C_SYMMETRIC_LINE)
+ continue;
+ Slvs_Constraint aPonCircA, aPonCircB;
+ aPonCircA.h = SLVS_E_UNKNOWN;
+ aPonCircB.h = SLVS_E_UNKNOWN;
+ std::list<Slvs_Constraint>::iterator aPtIter = aPonCirc.begin();
+ for (; aPtIter != aPonCirc.end(); aPtIter++) {
+ if (aMirror.ptA == aPtIter->ptA)
+ aPonCircA = *aPtIter;
+ if (aMirror.ptB == aPtIter->ptA)
+ aPonCircB = *aPtIter;
+ }
+ if (aPonCircA.h == SLVS_E_UNKNOWN || aPonCircB.h == SLVS_E_UNKNOWN)
+ continue;
+
+ // Calculate middle point for base arc and mirrored point on mirror arc
+ Slvs_Entity aBaseArc = myStorage->getEntity(aPonCircA.entityA);
+ Slvs_Entity aBasePoint = myStorage->getEntity(aPonCircA.ptA);
+ Slvs_Param aParamX = myStorage->getParameter(aBasePoint.param[0]);
+ Slvs_Param aParamY = myStorage->getParameter(aBasePoint.param[1]);
+ calculateMiddlePoint(aBaseArc, 0.5, aParamX.val, aParamY.val);
+ myStorage->updateParameter(aParamX);
+ myStorage->updateParameter(aParamY);
+ Slvs_Entity aMirrorPoint = myStorage->getEntity(aPonCircB.ptA);
+ makeMirrorEntity(aBasePoint, aMirrorPoint, aStartEnd);
+ }
+}
std::vector<Slvs_Entity>& theBaseEntities,
std::vector<Slvs_Entity>& theMirrorEntities);
+ /// \brief This method is used in derived objects to check consistence of constraint.
+ /// E.g. the distance between line and point may be signed.
+ virtual void adjustConstraint();
+
private:
/// \brief Change parameters of entities to be symmetric relative a line,
/// given by array of parameters (coordinates of first and last points)
anEntityID = myGroup->getFeatureId(myBaseFeature);
if (anEntityID == SLVS_E_UNKNOWN)
anEntityID = changeEntity(myBaseFeature, aType);
+ else
+ myFeatureMap[myBaseFeature] = anEntityID;
}
// Check the entity is complex
}
// Fix radius of the arc
- aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(),
- aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
- aConstraint.h = myStorage->addConstraint(aConstraint);
- mySlvsConstraints.push_back(aConstraint.h);
- if (!myBaseConstraint)
- myStorage->addTemporaryConstraint(aConstraint.h);
+ bool isExists = false;
+ std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
+ std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
+ for (; anIt != aDiamConstraints.end() && !isExists; anIt)
+ if (anIt->entityA == myFeatureMap.begin()->second)
+ isExists = true;
+ if (!isExists) {
+ aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER, myGroup->getWorkplaneId(),
+ aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
+ aConstraint.h = myStorage->addConstraint(aConstraint);
+ mySlvsConstraints.push_back(aConstraint.h);
+ if (!myBaseConstraint)
+ myStorage->addTemporaryConstraint(aConstraint.h);
+ }
}
}
Slvs_Constraint aConstraint = theConstraint;
+
+ // Find a constraint with same type uses same arguments
+ std::vector<Slvs_Constraint>::iterator aCIt = myConstraints.begin();
+ for (; aCIt != myConstraints.end(); aCIt++) {
+ if (aConstraint.type != aCIt->type)
+ continue;
+ if (aConstraint.ptA == aCIt->ptA && aConstraint.ptB == aCIt->ptB &&
+ aConstraint.entityA == aCIt->entityA && aConstraint.entityB == aCIt->entityB &&
+ aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD) {
+ aConstraint.h = aCIt->h;
+ return updateConstraint(aConstraint);
+ }
+ }
+
if (aConstraint.h > myConstrMaxID)
myConstrMaxID = aConstraint.h;
else
return aDummy;
}
+std::list<Slvs_Constraint> SketchSolver_Storage::getConstraintsByType(int theConstraintType) const
+{
+ std::list<Slvs_Constraint> aResult;
+ std::vector<Slvs_Constraint>::const_iterator aCIter = myConstraints.begin();
+ for (; aCIter != myConstraints.end(); aCIter++)
+ if (aCIter->type == theConstraintType)
+ aResult.push_back(*aCIter);
+ return aResult;
+}
+
+
void SketchSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
{
if (myFixed != SLVS_E_UNKNOWN)
#include "SketchSolver.h"
#include <SketchSolver_Solver.h>
+#include <list>
#include <memory>
#include <set>
#include <vector>
bool removeConstraint(const Slvs_hConstraint& theConstraintID);
/// \brief Returns the constraint by its ID
const Slvs_Constraint& getConstraint(const Slvs_hConstraint& theConstraintID) const;
+ /// \brief Returns list of constraints of specified type
+ std::list<Slvs_Constraint> getConstraintsByType(int theConstraintType) const;
/// \brief Attach temporary constraint to this storage. It need to make precise calculations
void addTemporaryConstraint(const Slvs_hConstraint& theConstraintID);