--- /dev/null
+SET(SLVS_ROOT_DIR $ENV{SOLVESPACE_ROOT_DIR})
+
+INCLUDE_DIRECTORIES(${SLVS_ROOT_DIR}/include)
+LINK_DIRECTORIES(${SLVS_ROOT_DIR}/lib)
+
+SET(SLVS_LIBRARIES ${SLVS_ROOT_DIR}/lib/slvs.lib)
INCLUDE(FindBoost)
INCLUDE(FindPython)
INCLUDE(FindSalome)
+INCLUDE(FindSolveSpace)
IF(UNIX)
IF(CMAKE_COMPILER_IS_GNUCC)
ADD_SUBDIRECTORY (src/PartSetPlugin)
ADD_SUBDIRECTORY (src/ConstructionPlugin)
ADD_SUBDIRECTORY (src/SketchPlugin)
+ADD_SUBDIRECTORY (src/SketchSolver)
ADD_SUBDIRECTORY (src/ModuleBase)
ADD_SUBDIRECTORY (src/PartSet)
ADD_SUBDIRECTORY (src/PyConsole)
export LIBXML2_LIB_DIR=${LIBXML2_ROOT_DIR}/lib
export LIBXML2_BIN_DIR=${LIBXML2_ROOT_DIR}/bin
##
+#------ SolveSpace ------
+export SOLVESPACE_ROOT_DIR=${PDIR}/solvespace-2.0
+export LD_LIBRARY_PATH=${SOLVESPACE_ROOT_DIR}/lib:${LD_LIBRARY_PATH}
+##
#------ OCCT ------
export CAS_ROOT_DIR=${PDIR}/OCCT-6.7.0
@SET PATH=%BOOST_ROOT_DIR%\lib;%PATH%
@REM -------------------------
+@REM -------------------------
+@SET SOLVESPACE_ROOT_DIR=%PDIR%\solvespace-2.0
+@SET PATH=%SOLVESPACE_ROOT_DIR%\lib;%PATH%
+@REM -------------------------
+
@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
@SET PATH=%ROOT_DIR%\install\plugins;%PATH%
myCoords->SetValue(1, theY);
myCoords->SetValue(2, theZ);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
myCoords->SetValue(1, theY);
myCoords->SetValue(2, theZ);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
myCoords->SetValue(0, theX);
myCoords->SetValue(1, theY);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
myComment->Set(TCollection_ExtendedString(theDoc->id().c_str()));
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
if (myReal->Get() != theValue) {
myReal->Set(theValue);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
using namespace std;
-void Model_AttributeRefAttr::setValue(boost::shared_ptr<ModelAPI_Attribute> theAttr)
+bool Model_AttributeRefAttr::isFeature()
{
- if (value() != theAttr) {
+ return myID->Get().Length() == 0;
+}
+
+void Model_AttributeRefAttr::setAttr(boost::shared_ptr<ModelAPI_Attribute> theAttr)
+{
+ boost::shared_ptr<Model_Data> aData =
+ boost::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
+ string anID = aData->id(theAttr);
+ if (feature() == theAttr->owner() && myID->Get().IsEqual(anID.c_str()))
+ return; // nothing is changed
+
+ myRef->Set(aData->label());
+ myID->Set(aData->id(theAttr).c_str());
+
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
+ Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Events_Loop::loop()->send(aMsg);
+}
+
+boost::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::attr()
+{
+ boost::shared_ptr<ModelAPI_Feature> aFeature = feature();
+ if (aFeature) {
boost::shared_ptr<Model_Data> aData =
- boost::dynamic_pointer_cast<Model_Data>(theAttr->feature()->data());
- if (myRef.IsNull()) {
- boost::shared_ptr<Model_Data> aMyData =
- boost::dynamic_pointer_cast<Model_Data>(feature()->data());
- TDF_Reference::Set(aMyData->label(), aData->label());
- } else {
- myRef->Set(aData->label());
- }
- myID->Set(aData->id(theAttr).c_str());
+ boost::dynamic_pointer_cast<Model_Data>(aFeature->data());
+ return aData->attribute(TCollection_AsciiString(myID->Get()).ToCString());
+ }
+ // not initialized
+ return boost::shared_ptr<ModelAPI_Attribute>();
+}
+
+void Model_AttributeRefAttr::setFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+ if (myID->Get().Length() != 0 || feature() != theFeature) {
+ boost::shared_ptr<Model_Data> aData =
+ boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
+ myRef->Set(aData->label());
+ myID->Set(""); // feature is identified by the empty ID
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
-boost::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::value()
+boost::shared_ptr<ModelAPI_Feature> Model_AttributeRefAttr::feature()
{
- if (!myRef.IsNull()) {
+ if (myRef->Get() != myRef->Label()) { // initialized
boost::shared_ptr<Model_Document> aDoc =
- boost::dynamic_pointer_cast<Model_Document>(feature()->document());
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
if (aDoc) {
TDF_Label aRefLab = myRef->Get();
TDF_Label aFeatureLab = aRefLab.Father();
- boost::shared_ptr<Model_Data> aData =
- boost::dynamic_pointer_cast<Model_Data>(aDoc->feature(aRefLab)->data());
- return aData->attribute(TCollection_AsciiString(myID->Get()).ToCString());
+ return aDoc->feature(aRefLab);
}
}
// not initialized
- return boost::shared_ptr<ModelAPI_Attribute>();
+ return boost::shared_ptr<ModelAPI_Feature>();
}
Model_AttributeRefAttr::Model_AttributeRefAttr(TDF_Label& theLabel)
// check the attribute could be already presented in this doc (after load document)
if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myID)) {
// create attribute: not initialized by value yet
- TDataStd_Comment::Set(theLabel, "");
- // reference attribute is not set to the label!
+ myID = TDataStd_Comment::Set(theLabel, "");
+ myRef = TDF_Reference::Set(theLabel, theLabel); // not initialized: reference to itself
}
}
class Model_AttributeRefAttr : public ModelAPI_AttributeRefAttr
{
Handle_TDF_Reference myRef; ///< reference to the feature label
- Handle_TDataStd_Comment myID; ///< ID of the referenced attirbute
+ ///< ID of the referenced attirbute (empty if this is a reference to a feature)
+ Handle_TDataStd_Comment myID;
public:
- /// Defines the attribute referenced from this attribute
- MODEL_EXPORT virtual void setValue(boost::shared_ptr<ModelAPI_Attribute> theAttr);
+ /// Returns true if this attribute references to a feature (not to the attribute)
+ MODEL_EXPORT virtual bool isFeature();
+
+ /// Defines the reference to the attribute
+ MODEL_EXPORT virtual void setAttr(boost::shared_ptr<ModelAPI_Attribute> theAttr);
/// Returns attribute referenced from this attribute
- MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Attribute> value();
+ MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Attribute> attr();
+
+ /// Defines the reference to the feature
+ MODEL_EXPORT virtual void setFeature(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
+ /// Returns feature referenced from this attribute
+ MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> feature();
protected:
/// Objects are created for features automatically
myRef->Append(aData->label());
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
{
std::list< boost::shared_ptr<ModelAPI_Feature> > aResult;
boost::shared_ptr<Model_Document> aDoc =
- boost::dynamic_pointer_cast<Model_Document>(feature()->document());
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
if (aDoc) {
const TDF_LabelList& aList = myRef->List();
for(TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
if (myRef.IsNull()) {
boost::shared_ptr<Model_Data> aMyData =
- boost::dynamic_pointer_cast<Model_Data>(feature()->data());
+ boost::dynamic_pointer_cast<Model_Data>(owner()->data());
TDF_Reference::Set(aMyData->label(), aData->label());
} else {
myRef->Set(aData->label());
}
static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(feature(), anEvent);
+ Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
Events_Loop::loop()->send(aMsg);
}
}
{
if (!myRef.IsNull()) {
boost::shared_ptr<Model_Document> aDoc =
- boost::dynamic_pointer_cast<Model_Document>(feature()->document());
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
if (aDoc) {
TDF_Label aRefLab = myRef->Get();
return aDoc->feature(aRefLab);
{myFeature = theFeature;}
/// Returns the owner of this attribute
- MODELAPI_EXPORT const boost::shared_ptr<ModelAPI_Feature>& feature()
+ MODELAPI_EXPORT const boost::shared_ptr<ModelAPI_Feature>& owner()
{return myFeature;}
protected:
/// Objects are created for features automatically
/**\class ModelAPI_AttributeRefAttr
* \ingroup DataModel
- * \brief Attribute that contains reference to an attribute of a feature
- * (located in the same document).
+ * \brief Attribute that contains reference to an attribute of a feature or reference to
+ * a feature (switchable)
*/
class ModelAPI_AttributeRefAttr : public ModelAPI_Attribute
{
public:
- /// Defines the attribute referenced from this attribute
- MODELAPI_EXPORT virtual void setValue(boost::shared_ptr<ModelAPI_Attribute> theAttr) = 0;
+ /// Returns true if this attribute references to a feature (not to the attribute)
+ MODELAPI_EXPORT virtual bool isFeature() = 0;
+
+ /// Defines the reference to the attribute
+ MODELAPI_EXPORT virtual void setAttr(boost::shared_ptr<ModelAPI_Attribute> theAttr) = 0;
/// Returns attribute referenced from this attribute
- MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Attribute> value() = 0;
+ MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Attribute> attr() = 0;
+
+ /// Defines the reference to the feature
+ MODELAPI_EXPORT virtual void setFeature(boost::shared_ptr<ModelAPI_Feature> theFeature) = 0;
+
+ /// Returns feature referenced from this attribute
+ MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> feature() = 0;
/// Returns the type of this class of attributes
MODELAPI_EXPORT static std::string type() {return "RefAttr";}
#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
+#include <ModelAPI_AttributeRefAttr.h>
+
+#include <SketchPlugin_Constraint.h>
+
+#include <Geom_Line.hxx>
+#include <gp_Lin.hxx>
+
+#include <XGUI_ViewerPrs.h>
#include <SketchPlugin_Line.h>
#include <V3d_View.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
#ifdef _DEBUG
#include <QDebug>
void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView,
const std::list<XGUI_ViewerPrs>& theSelected)
{
+ double aX, anY;
+
gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
+ if (theSelected.empty()) {
+ PartSet_Tools::ConvertTo2D(aPoint, mySketch, theView, aX, anY);
+ }
+ else {
+ XGUI_ViewerPrs aPrs = theSelected.front();
+ const TopoDS_Shape& aShape = aPrs.shape();
+ if (!aShape.IsNull()) // the point is selected
+ {
+ if (aShape.ShapeType() == TopAbs_VERTEX) {
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
+ if (!aVertex.IsNull()) {
+ aPoint = BRep_Tool::Pnt(aVertex);
+ PartSet_Tools::ConvertTo2D(aPoint, mySketch, theView, aX, anY);
+ }
+ }
+ else if (aShape.ShapeType() == TopAbs_EDGE) // the line is selected
+ {
+ boost::shared_ptr<ModelAPI_Feature> aFeature = aPrs.feature();
+ if (aFeature) {
+ double X0, X1, X2, X3;
+ double Y0, Y1, Y2, Y3;
+ getLinePoint(aFeature, LINE_ATTR_START, X2, Y2);
+ getLinePoint(aFeature, LINE_ATTR_END, X3, Y3);
+ PartSet_Tools::ConvertTo2D(aPoint, mySketch, theView, X1, Y1);
+
+ switch (myPointSelectionMode) {
+ case SM_FirstPoint:
+ PartSet_Tools::ProjectPointOnLine(X2, Y2, X3, Y3, X1, Y1, aX, anY);
+ break;
+ case SM_SecondPoint: {
+ getLinePoint(feature(), LINE_ATTR_START, X0, Y0);
+ PartSet_Tools::IntersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, aX, anY);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
switch (myPointSelectionMode)
{
case SM_FirstPoint: {
- setLinePoint(aPoint, theView, LINE_ATTR_START);
+ setLinePoint(aX, anY, LINE_ATTR_START);
myPointSelectionMode = SM_SecondPoint;
}
break;
case SM_SecondPoint: {
- setLinePoint(aPoint, theView, LINE_ATTR_END);
+ setLinePoint(aX, anY, LINE_ATTR_END);
commit();
emit featureConstructed(feature(), FM_Deactivation);
emit launchOperation(PartSet_OperationSketchLine::Type(), feature());
{
PartSet_OperationSketchBase::startOperation();
myPointSelectionMode = !myInitPoint ? SM_FirstPoint : SM_SecondPoint;
+ emit multiSelectionEnabled(false);
}
void PartSet_OperationSketchLine::abortOperation()
PartSet_OperationSketchBase::abortOperation();
}
+void PartSet_OperationSketchLine::stopOperation()
+{
+ PartSet_OperationSketchBase::stopOperation();
+ emit multiSelectionEnabled(true);
+}
+
boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchLine::createFeature()
{
boost::shared_ptr<ModelAPI_Feature> aNewFeature = ModuleBase_Operation::createFeature();
boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aData->attribute(LINE_ATTR_START));
aPoint->setValue(myInitPoint->x(), myInitPoint->y());
+
+ //createConstraint(myInitPoint, aPoint);
}
emit featureConstructed(aNewFeature, FM_Activation);
return aNewFeature;
}
-void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint,
- Handle(V3d_View) theView,
+void PartSet_OperationSketchLine::createConstraint(boost::shared_ptr<GeomDataAPI_Point2D> thePoint1,
+ boost::shared_ptr<GeomDataAPI_Point2D> thePoint2)
+{
+ boost::shared_ptr<ModelAPI_Document> aDoc = document();
+ boost::shared_ptr<ModelAPI_Feature> aFeature = aDoc->addFeature("SketchConstraintCoincidence");
+
+ boost::shared_ptr<ModelAPI_Data> aData = aFeature->data();
+
+ boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
+ aRef1->setAttr(thePoint1);
+
+ boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_B));
+ aRef2->setAttr(thePoint2);
+
+ if (aFeature) // TODO: generate an error if feature was not created
+ aFeature->execute();
+}
+
+void PartSet_OperationSketchLine::getLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature,
+ const std::string& theAttribute,
+ double& theX, double& theY)
+{
+ if (!theFeature)
+ return;
+ boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
+ theX = aPoint->x();
+ theY = aPoint->y();
+}
+
+void PartSet_OperationSketchLine::setLinePoint(double theX, double theY,
const std::string& theAttribute)
{
boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
+ aPoint->setValue(theX, theY);
+}
+void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint,
+ Handle(V3d_View) theView,
+ const std::string& theAttribute)
+{
double aX, anY;
PartSet_Tools::ConvertTo2D(thePoint, mySketch, theView, aX, anY);
+ boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
aPoint->setValue(aX, anY);
}
/// Before the feature is aborted, it should be hidden from the viewer
virtual void abortOperation();
+ /// Virtual method called when operation stopped - committed or aborted.
+ /// Restore the multi selection state
+ virtual void stopOperation();
+
/// Creates an operation new feature
/// In addition to the default realization it appends the created line feature to
/// the sketch feature
/// \returns the created feature
virtual boost::shared_ptr<ModelAPI_Feature> createFeature();
+ /// Creates a constraint on two points
+ /// \param thePoint1 the first point
+ /// \param thePoint1 the second point
+ void createConstraint(boost::shared_ptr<GeomDataAPI_Point2D> thePoint1,
+ boost::shared_ptr<GeomDataAPI_Point2D> thePoint2);
+
protected:
+ /// \brief Get the line point 2d coordinates.
+ /// \param theFeature the line feature
+ /// \param theAttribute the start or end attribute of the line
+ /// \param theX the horizontal coordinate
+ /// \param theY the vertical coordinate
+ void getLinePoint(boost::shared_ptr<ModelAPI_Feature> theFeature, const std::string& theAttribute,
+ double& theX, double& theY);
+ /// \brief Save the point to the line.
+ /// \param theX the horizontal coordinate
+ /// \param theY the vertical coordinate
+ /// \param theAttribute the start or end attribute of the line
+ void setLinePoint(double theX, double theY, const std::string& theAttribute);
/// \brief Save the point to the line.
/// \param thePoint the 3D point in the viewer
/// \param theAttribute the start or end attribute of the line
#include <PartSet_Tools.h>
-#include <V3d_View.hxx>
-#include <gp_Pln.hxx>
-#include <ProjLib.hxx>
-#include <ElSLib.hxx>
-
#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
+
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Dir.h>
+
+#include <GeomAPI_Dir.h>
+#include <GeomAPI_XYZ.h>
+
#include <SketchPlugin_Sketch.h>
+#include <V3d_View.hxx>
+#include <gp_Pln.hxx>
+#include <ProjLib.hxx>
+#include <ElSLib.hxx>
+#include <Geom_Line.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+
#ifdef _DEBUG
#include <QDebug>
#endif
+const double PRECISION_TOLERANCE = 0.000001;
+
gp_Pnt PartSet_Tools::ConvertClickToPoint(QPoint thePoint, Handle(V3d_View) theView)
{
if (theView.IsNull())
boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
gp_Vec aNormalVec(aNormal->x(), aNormal->y(), aNormal->z());
- double aDen = anEyeVec*aNormalVec;
- double aLVec = aDen != 0 ? aVec*aNormalVec/aDen : aVec*aNormalVec;
+ double aDen = anEyeVec * aNormalVec;
+ double aLVec = aDen != 0 ? aVec * aNormalVec / aDen : DBL_MAX;
gp_Vec aDeltaVec = anEyeVec*aLVec;
aVec = aVec - aDeltaVec;
theX = aVec.X() * aX->x() + aVec.Y() * aX->y() + aVec.Z() * aX->z();
theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z();
}
+
+void PartSet_Tools::IntersectLines(double theX0, double theY0, double theX1, double theY1,
+ double theX2, double theY2, double theX3, double theY3,
+ double& theX, double& theY)
+{
+ double aV1 = theX1 - theX0, aV2 = theY1 - theY0;
+ double aW1 = theX3 - theX2, aW2 = theY3 - theY2;
+
+ double aT2 = 0;
+ if (aV1 != 0 && aV2 != 0)
+ aT2 = (( theY2 - theY0 )/aV2 - ( theX2 - theX0 )/aV1) / ( aW1/aV1 - aW2/aV2 );
+ else
+ aT2 = DBL_MAX;
+
+ theX = theX2 + aT2*aW1;
+ theY = theY2 + aT2*aW2;
+
+ // the coordinates of two lines are on the common line
+ //It is not possible to use Precision::Confusion(), because it is e-0.8, but V is sometimes e-6
+ Standard_Real aPrec = PRECISION_TOLERANCE;
+ if (fabs(theX - theX0) < aPrec && fabs(theY - theY0) < aPrec) {
+ ProjectPointOnLine(theX2, theY2, theX3, theY3, theX1, theY1, theX, theY);
+ }
+}
+
+void PartSet_Tools::ProjectPointOnLine(double theX1, double theY1, double theX2, double theY2,
+ double thePointX, double thePointY, double& theX, double& theY)
+{
+ theX = theY = 0;
+
+ Handle(Geom_Line) aLine = new Geom_Line(gp_Pnt(theX1, theY1, 0),
+ gp_Dir(gp_Vec(gp_Pnt(theX1, theY1, 0), gp_Pnt(theX2, theY2, 0))));
+ GeomAPI_ProjectPointOnCurve aProj(gp_Pnt(thePointX, thePointY, 0), aLine);
+
+ Standard_Integer aNbPoint = aProj.NbPoints();
+ if (aNbPoint > 0) {
+ gp_Pnt aPoint = aProj.Point(1);
+ theX = aPoint.X();
+ theY = aPoint.Y();
+ }
+}
/// \param theY the Y coordinate
static void ConvertTo2D(const gp_Pnt& thePoint, boost::shared_ptr<ModelAPI_Feature> theSketch,
Handle(V3d_View) theView, double& theX, double& theY);
+
+ /// Returns the point of intersection of the two lines, the first is (v0, v1), the second is (v2, v3),
+ /// where vi - {xi,yi}. If the v0 is on the second line, the result is a projection of the v1 to this line
+ /// \param theX0 the horizontal coordinate of 0 point
+ /// \param theY0 the vertical coordinate of 0 point
+ /// \param theX1 the horizontal coordinate of 1 point
+ /// \param theY1 the vertical coordinate of 1 point
+ /// \param theX2 the horizontal coordinate of 2 point
+ /// \param theY2 the vertical coordinate of 2 point
+ /// \param theX3 the horizontal coordinate of 3 point
+ /// \param theY3 the vertical coordinate of 3 point
+ /// \param theX the output horizontal coordinate of the intersection point
+ /// \param theY the outpup vertical coordinate of the intersection point
+ static void IntersectLines(double theX0, double theY0, double theX1, double theY1,
+ double theX2, double theY2, double theX3, double theY3,
+ double& theX, double& theY);
+
+ /// Returns the coordinates of projection of the point to the line
+ /// \param thePointX the projected point horizontal coordinate
+ /// \param thePointY the projected point vertictal coordinate
+ /// \param theX1 the horizontal coordinate of the first line point
+ /// \param theY1 the vertical coordinate of the first line point
+ /// \param theX2 the horizontal coordinate of the second line point
+ /// \param theY2 the vertical coordinate of the second line point
+ static void ProjectPointOnLine(double theX1, double theY1, double theX2, double theY2,
+ double thePointX, double thePointY, double& theX, double& theY);
};
#endif
SketchPlugin_Plugin.h
SketchPlugin_Sketch.h
SketchPlugin_Line.h
+ SketchPlugin_Point.h
+ SketchPlugin_Constraint.h
+ SketchPlugin_ConstraintCoincidence.h
)
SET(PROJECT_SOURCES
SketchPlugin_Plugin.cpp
SketchPlugin_Sketch.cpp
SketchPlugin_Line.cpp
+ SketchPlugin_Point.cpp
+ SketchPlugin_ConstraintCoincidence.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// File: SketchPlugin_Constraint.h
+// Created: 08 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_Constraint_HeaderFile
+#define SketchPlugin_Constraint_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Feature.h"
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <list>
+
+/* Description:
+ * Each constraint uses a set of parameters. In the SolveSpace library
+ * these parameters are named "valA", "ptA", "ptB", "entityA", "entityB".
+ * The "ptA" and "ptB" parameters represents a point in the constraint.
+ * The "entityA" and "entityB" represents any other object (and a point too).
+ * And the "valA" represents a real value.
+ *
+ * The attributes below are named independent of the SolveSpace.
+ * Some of them may be unused.
+ *
+ * Also the list of possible attributes is provided to simplify assignment.
+ */
+/// The value parameter for the constraint
+const std::string CONSTRAINT_ATTR_VALUE("ConstraintValue");
+/// First entity for the constraint
+const std::string CONSTRAINT_ATTR_ENTITY_A("ConstraintEntityA");
+/// Second entity for the constraint
+const std::string CONSTRAINT_ATTR_ENTITY_B("ConstraintEntityB");
+/// Third entity for the constraint
+const std::string CONSTRAINT_ATTR_ENTITY_C("ConstraintEntityC");
+/// Fourth entity for the constraint
+const std::string CONSTRAINT_ATTR_ENTITY_D("ConstraintEntityD");
+/// List of constraint attributes
+const std::string CONSTRAINT_ATTRIBUTES[4] =
+ {CONSTRAINT_ATTR_ENTITY_A, CONSTRAINT_ATTR_ENTITY_B,
+ CONSTRAINT_ATTR_ENTITY_C, CONSTRAINT_ATTR_ENTITY_D};
+
+
+/** \class SketchPlugin_Constraint
+ * \ingroup DataModel
+ * \brief Feature for creation of a new constraint between other features.
+ * Base class for all constraints.
+ */
+class SketchPlugin_Constraint: public SketchPlugin_Feature
+{
+public:
+ /// \brief Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {static std::string MY_KIND = "SketchConstraint"; return MY_KIND;}
+
+ /// \brief Returns to which group in the document must be added feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
+ {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+ /** \brief Adds sub-feature of the higher level feature (sub-element of the sketch)
+ * \param theFeature sub-feature
+ */
+ SKETCHPLUGIN_EXPORT virtual const void addSub(
+ const boost::shared_ptr<ModelAPI_Feature>& theFeature) {}
+
+ /// \brief Use plugin manager for features creation
+ SketchPlugin_Constraint() {}
+};
+
+#endif
--- /dev/null
+// File: SketchPlugin_ConstraintCoincidence.cpp
+// Created: 08 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintCoincidence.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Point.h>
+
+SketchPlugin_ConstraintCoincidence::SketchPlugin_ConstraintCoincidence()
+{
+}
+
+void SketchPlugin_ConstraintCoincidence::initAttributes()
+{
+ data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
+ data()->addAttribute(CONSTRAINT_ATTR_ENTITY_B, ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintCoincidence::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_ConstraintCoincidence::preview()
+{
+ /// \todo Preview for point coincidence
+ return getPreview();
+}
+
--- /dev/null
+// File: SketchPlugin_ConstraintCoincidence.h
+// Created: 08 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintCoincidence_HeaderFile
+#define SketchPlugin_ConstraintCoincidence_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Constraint.h"
+#include <list>
+
+
+/** \class SketchPlugin_ConstraintCoincidence
+ * \ingroup DataModel
+ * \brief Feature for creation of a new constraint which defines equvalence of two points
+ *
+ * These constraint has two attributes: CONSTRAINT_ATTR_POINT_A and CONSTRAINT_ATTR_POINT_B
+ */
+class SketchPlugin_ConstraintCoincidence: public SketchPlugin_Constraint
+{
+public:
+ /// \brief Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {static std::string MY_KIND = "SketchConstraintCoincidence"; return MY_KIND;}
+
+ /// \brief Returns to which group in the document must be added feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
+ {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+ /// \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();
+
+ /// \brief Returns the sketch preview
+ SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+ /// \brief Use plugin manager for features creation
+ SketchPlugin_ConstraintCoincidence();
+};
+
+#endif
#include "SketchPlugin_Plugin.h"
#include "SketchPlugin_Sketch.h"
#include "SketchPlugin_Line.h"
+#include "SketchPlugin_ConstraintCoincidence.h"
#include <ModelAPI_PluginManager.h>
#include <ModelAPI_Document.h>
else if (theFeatureID == "SketchLine") {
return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_Line);
}
+ else if (theFeatureID == "SketchConstraintCoincidence") {
+ return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintCoincidence);
+ }
// feature of such kind is not found
return boost::shared_ptr<ModelAPI_Feature>();
}
--- /dev/null
+// File: SketchPlugin_Point.cpp
+// Created: 07 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_Point.h"
+#include "SketchPlugin_Sketch.h"
+#include <ModelAPI_Data.h>
+#include <GeomDataAPI_Point2D.h>
+
+using namespace std;
+
+SketchPlugin_Point::SketchPlugin_Point()
+{
+}
+
+void SketchPlugin_Point::initAttributes()
+{
+ data()->addAttribute(POINT_ATTR_COORD, GeomDataAPI_Point2D::type());
+}
+
+void SketchPlugin_Point::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Point::preview()
+{
+ SketchPlugin_Sketch* aSketch = sketch();
+ // compute a point in 3D view
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(POINT_ATTR_COORD));
+ boost::shared_ptr<GeomAPI_Pnt> aPoint3D(aSketch->to3D(aPoint->x(), aPoint->y()));
+ // make a visible point
+ //boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
+ //setPreview(anEdge);
+
+ return getPreview();
+}
--- /dev/null
+// File: SketchPlugin_Point.h
+// Created: 07 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_Point_HeaderFile
+#define SketchPlugin_Point_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Feature.h"
+#include <list>
+
+/// Coordinates of the point
+const std::string POINT_ATTR_COORD("PointCoordindates");
+
+/**\class SketchPlugin_Point
+ * \ingroup DataModel
+ * \brief Feature for creation of a new point.
+ */
+class SketchPlugin_Point: public SketchPlugin_Feature
+{
+public:
+ /// Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {static std::string MY_KIND = "SketchPoint"; return MY_KIND;}
+
+ /// Returns to which group in the document must be added feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
+ {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+ /// Creates a new part document if needed
+ SKETCHPLUGIN_EXPORT virtual void execute();
+
+ /// Request for initialization of data model of the feature: adding all attributes
+ SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Returns the sketch preview
+ SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+ /// Adds sub-feature of the higher level feature (sub-element of the sketch)
+ /// \param theFeature sub-feature
+ SKETCHPLUGIN_EXPORT virtual const void addSub(
+ const boost::shared_ptr<ModelAPI_Feature>& theFeature) {};
+
+ /// Use plugin manager for features creation
+ SketchPlugin_Point();
+};
+
+#endif
<label text="Select a plane on which to create a sketch" tooltip="Select a plane on which to create a sketch"/>
<!--icon=":pictures/x_point.png"-->
</feature>
+ <feature id="SketchPoint" text="Point" tooltip="Create a new point" icon=":icons/point.png" />
<feature id="SketchLine" text="Line" tooltip="Create a new line" icon=":icons/line.png">
<point_selector id="StartPoint" title="Start point" tooltip="Start point of the line"/>
<point_selector id="EndPoint" title="End point" tooltip="End point of the line"/>
</feature>
+ <feature id="SketchConstraintCoincidence" text="Points coincidence" tooltip="Create constraint for the coincidence of two points" icon="" />
</group>
</workbench>
</plugin>
--- /dev/null
+INCLUDE(Common)
+INCLUDE(FindSolveSpace)
+
+SET(PROJECT_HEADERS
+ SketchSolver.h
+ SketchSolver_Solver.h
+ SketchSolver_ConstraintManager.h
+)
+
+SET(PROJECT_SOURCES
+ SketchSolver_Solver.cpp
+ SketchSolver_ConstraintManager.cpp
+)
+
+SET(PROJECT_LIBRARIES
+ ${SLVS_LIBRARIES}
+ SketchPlugin
+)
+
+INCLUDE_DIRECTORIES(
+ ../SketchPlugin
+ ../ModelAPI
+ ../GeomAPI
+)
+
+ADD_DEFINITIONS(-DSKETCHSOLVER_EXPORTS ${BOOST_DEFINITIONS})
+
+ADD_LIBRARY(SketchSolver SHARED
+ ${PROJECT_SOURCES}
+ ${PROJECT_HEADERS}
+)
+
+TARGET_LINK_LIBRARIES(SketchSolver
+ ${PROJECT_LIBRARIES}
+)
+
+INSTALL(TARGETS SketchSolver DESTINATION plugins)
--- /dev/null
+#ifndef SKETCHSOLVER_H
+#define SKETCHSOLVER_H
+
+#if defined SKETCHSOLVER_EXPORTS
+#if defined WIN32
+#define SKETCHSOLVER_EXPORT __declspec( dllexport )
+#else
+#define SKETCHSOLVER_EXPORT
+#endif
+#else
+#if defined WIN32
+#define SKETCHSOLVER_EXPORT __declspec( dllimport )
+#else
+#define SKETCHSOLVER_EXPORT
+#endif
+#endif
+
+#endif
--- /dev/null
+// File: SketchSolver_ConstraintManager.cpp
+// Created: 08 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchSolver_ConstraintManager.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Constraint.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_Line.h>
+
+
+/// This value is used to give unique index to the groups
+static Slvs_hGroup myGroupIndexer = 0;
+
+// ========================================================
+// ========= SketchSolver_ConstraintManager ===============
+// ========================================================
+SketchSolver_ConstraintManager::SketchSolver_ConstraintManager()
+{
+ myGroups.clear();
+}
+
+SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
+{
+ myGroups.clear();
+}
+
+void SketchSolver_ConstraintManager::findGroups(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
+ std::vector<Slvs_hGroup>& theGroupIDs) const
+{
+ std::vector<SketchSolver_ConstraintGroup>::const_iterator aGroupIter;
+ for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
+ if (aGroupIter->isInteract(theConstraint))
+ theGroupIDs.push_back(aGroupIter->getId());
+}
+
+
+// ========================================================
+// ========= SketchSolver_ConstraintGroup ===============
+// ========================================================
+
+SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup()
+ : myID(++myGroupIndexer),
+ myParamMaxID(0),
+ myEntityMaxID(0),
+ myConstrMaxID(0),
+ myConstraintMap()
+{
+ myParams.clear();
+ myEntities.clear();
+ myConstraints.clear();
+
+ // The workplane will be initialized on first constraint, so its handle is NULL meanwhile
+ myWorkplane.h = 0;
+
+ // Nullify all elements of the set of equations
+ myConstrSet.param = 0;
+ myConstrSet.entity = 0;
+ myConstrSet.constraint = 0;
+ myConstrSet.failed = 0;
+}
+
+SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup()
+{
+ myParams.clear();
+ myEntities.clear();
+ myConstraints.clear();
+ myConstraintMap.clear();
+
+ if (myConstrSet.param)
+ delete [] myConstrSet.param;
+ if (myConstrSet.entity)
+ delete [] myConstrSet.entity;
+ if (myConstrSet.constraint)
+ delete [] myConstrSet.constraint;
+ if (myConstrSet.failed)
+ delete [] myConstrSet.failed;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isInteract(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const
+{
+ /// \todo Should be implemented
+ return false;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addConstraint(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+ if (myWorkplane.h == 0)
+ {
+// // Create workplane when first constraint is added
+// std::list< boost::shared_ptr<ModelAPI_Attribute> > aWPAttr;
+// theConstraint->getSketchParameters(aWPAttr);
+// if (!addWorkplane(aWPAttr))
+// return false;
+ }
+
+ // Create constraint parameters
+ double aDistance = 0.0; // scalar value of the constraint
+ boost::shared_ptr<ModelAPI_AttributeDouble> aDistAttr =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE));
+ if (aDistAttr.get())
+ aDistance = aDistAttr->value();
+
+ /// \todo Specify the entities
+ Slvs_hEntity aPtA, aPtB, aEntityA, aEntityB; // parameters of the constraint
+ boost::shared_ptr<ModelAPI_Attribute> aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_A);
+ aPtA = addEntity(aEntAttr);
+ if (aPtA == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_B);
+ aPtB = addEntity(aEntAttr);
+ if (aPtB == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_C);
+ aEntityA = addEntity(aEntAttr);
+ if (aEntityA == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_D);
+ aEntityB = addEntity(aEntAttr);
+ if (aEntityB == 0) return false;
+
+ // Constraint type
+ int aConstrType = getConstraintType(theConstraint);
+ if (aConstrType == 0) return false;
+
+ // Create SolveSpace constraint structure
+ Slvs_Constraint aConstraint =
+ Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, myWorkplane.h,
+ aDistance, aPtA, aPtB, aEntityA, aEntityB);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint] = *(myConstraints.rbegin());
+
+ return true;
+}
+
+Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addEntity(
+ boost::shared_ptr<ModelAPI_Attribute> theEntity)
+{
+ /// \todo Should be implemented
+ return 0;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane(
+ std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams)
+{
+ /// \todo Should be implemented
+ return false;
+}
+
+int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintType(
+ const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint) const
+{
+// if (theConstraint->getKind() == SketchPlugin_ConstraintDistance().getKind())
+// {
+// boost::shared_ptr<ModelAPI_Attribute> aPtA = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_A);
+// boost::shared_ptr<ModelAPI_Attribute> aPtB = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_B);
+// boost::shared_ptr<ModelAPI_Attribute> aEntA = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_A);
+// boost::shared_ptr<ModelAPI_Attribute> aEntB = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_B);
+// boost::shared_ptr<ModelAPI_AttributeDouble> aDistance =
+// boost::shared_dynamic_cast<ModelAPI_AttributeDouble>(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE));
+// if (aPtA.get()) // ptA is an attribute of the constraint
+// {
+//// if (aEntA.get()) // entityA is an attribute of the constraint
+//// {
+//// if (aEntA->feature()->getKind() == SketchPlugin_Line().getKind()) // entityA is a line
+//// {
+//// if (aEntB.get() && aEntB->feature()->getKind() == SketchPlugin_Line().getKind()) // entityB is a line too
+//// return SLVS_C_ANGLE;
+//// else if (aPtB.get()) // ptB is also an attribute of the constraint
+//// return SLVS_C_PROJ_PT_DISTANCE;
+//// else
+//// return SLVS_C_PT_LINE_DISTANCE;
+//// }
+//// /// \todo Implement other point-entity distances
+//// }
+//// else
+// if (aPtB.get()) // ptB is an attribute of the constrtaint => point-point distance
+// {
+// if (aDistance->value() == 0.0)
+// return SLVS_C_POINTS_COINCIDENT;
+// else
+// return SLVS_C_PT_PT_DISTANCE;
+// }
+// }
+// else if (aEntA.get() && !aEntB.get() && !aPtB.get())
+// return SLVS_C_DIAMETER;
+// return SLVS_C_UNKNOWN;
+// }
+ /// \todo Implement other kind of constrtaints
+
+ return SLVS_C_UNKNOWN;
+}
--- /dev/null
+// File: SketchSolver_ConstraintManager.h
+// Created: 08 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchSolver_ConstraintManager_Headerfile
+#define SketchSolver_ConstraintManager_Headerfile
+
+#include "SketchSolver.h"
+
+#include <SketchPlugin_Constraint.h>
+
+// Need to be defined before including SolveSpace to avoid additional dependances on Windows platform
+#if defined(WIN32) && !defined(HAVE_C99_INTEGER_TYPES)
+typedef unsigned int UINT32;
+#endif
+#include <string.h>
+#include <slvs.h>
+
+#include <map>
+#include <vector>
+
+
+// Unknown constraint (for error reporting)
+#define SLVS_C_UNKNOWN 0
+
+/** \class SketchSolver_ConstraintManager
+ * \ingroup DataModel
+ * \brief Transforms the Constraint feature into the format understandable by SolveSpace library.
+ *
+ * Constraints created for SolveSpace library will be divided into the groups.
+ * The division order based on connectedness of the features by the constraints.
+ * The groups may be fused or separated according to the new constraints.
+ */
+class SketchSolver_ConstraintManager
+{
+public:
+ SketchSolver_ConstraintManager();
+ ~SketchSolver_ConstraintManager();
+
+ /** \brief Adds a constraint into the manager
+ * \param[in] theConstraint constraint to be added
+ * \return \c true if the constraint added successfully
+ */
+ SKETCHSOLVER_EXPORT bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+ /** \brief Removes a constraint from the manager
+ * \param[in] theConstraint constraint to be removed
+ * \return \c true if the constraint removed successfully
+ */
+ SKETCHSOLVER_EXPORT bool removeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+private:
+ class SketchSolver_ConstraintGroup;
+
+ /** \brief Searches list of groups which interact with specified constraint
+ * \param[in] theConstraint constraint to be found
+ * \param[out] theGroups list of group indexes interacted with constraint
+ */
+ void findGroups(boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
+ std::vector<Slvs_hGroup>& theGroupIDs) const;
+
+private:
+ std::vector<SketchSolver_ConstraintGroup> myGroups; ///< groups of constraints
+};
+
+
+/** \class SketchSolver_ConstraintGroup
+ * \ingroup DataModel
+ * \brief Keeps the group of constraints which based on the same entities
+ */
+class SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup
+{
+public:
+ SketchSolver_ConstraintGroup();
+ ~SketchSolver_ConstraintGroup();
+
+ /// \brief Returns group's unique identifier
+ const Slvs_hGroup& getId() const
+ {return myID;}
+
+ /** \brief Adds a constraint into the group
+ * \param[in] theConstraint constraint to be added
+ * \return \c true if the constraint added successfully
+ */
+ bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+ /** \brief Removes a constraint into the group
+ * \param[in] theConstraint constraint to be removed
+ * \return \c true if the constraint removed successfully
+ */
+ bool removeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+ /** \brief Verifies the constraint uses the objects from this group
+ * \param[in] theConstraint constraint for verification of interaction
+ * \return \c true if the constrained objects are used in current group
+ */
+ bool isInteract(boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const;
+
+protected:
+ /** \brief Creates a workplane from the sketch parameters
+ * \param[in] theParams list of the basic parameters of the workplane
+ * \return \c true if success
+ */
+ bool addWorkplane(std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams);
+
+ /** \brief Adds an entity into the group
+ * \param[in] theEntity the object of constraint
+ * \return identifier of created entity or 0 if entity was not added
+ */
+ Slvs_hEntity addEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
+
+ /** \brief Adds a parameter into the group
+ * \param[in] theParam parameter to be added
+ * \return identifier of created parameter or 0 if it was not added
+ */
+ Slvs_hParam addParameter(double theParam);
+
+ /** \brief Compute constraint type according to SolveSpace identifiers
+ * \param[in] theConstraint constraint which type should be determined
+ * \return identifier of constraint type
+ */
+ int getConstraintType(const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint) const;
+
+private:
+ Slvs_hGroup myID; ///< the index of the group
+ Slvs_Entity myWorkplane; ///< Workplane for the current group
+ std::vector<Slvs_Param> myParams; ///< List of parameters of the constraints
+ Slvs_hParam myParamMaxID; ///< Actual maximal ID of parameters
+ std::vector<Slvs_Entity> myEntities; ///< List of entities of the constaints
+ Slvs_hEntity myEntityMaxID; ///< Actual maximal ID of entities
+ std::vector<Slvs_Constraint> myConstraints; ///< List of constraints in SolveSpace format
+ Slvs_hConstraint myConstrMaxID; ///< Actual maximal ID of constraints
+ Slvs_System myConstrSet; ///< SolveSpace's set of equations obtained by constraints
+ std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_Constraint>
+ myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
+};
+
+#endif
--- /dev/null
+// File: SketchSolver_Solver.cpp
+// Created: 07 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchSolver_Solver.h"
--- /dev/null
+// File: SketchSolver_Solver.h
+// Created: 07 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchSolver_Solver_Headerfile
+#define SketchSolver_Solver_Headerfile
+
+#include "SketchSolver.h"
+
+#endif