if (data()->boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value())
aSize = -aSize;
+ eraseResults(); // to erase the previously stored naming structures
boost::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
if(!aFeature.isDone()) {
// Author: Artem ZHIDKOV
#include<GeomAPI_Edge.h>
+#include<GeomAPI_Pnt.h>
+#include<GeomAPI_Circ.h>
+#include<GeomAPI_Dir.h>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Circle.hxx>
+#include <gp_Ax1.hxx>
GeomAPI_Edge::GeomAPI_Edge()
- : GeomAPI_Shape()
+ : GeomAPI_Shape()
{
}
+GeomAPI_Edge::GeomAPI_Edge(const boost::shared_ptr<GeomAPI_Shape>& theShape)
+{
+ if (!theShape->isNull() && theShape->isEdge()) {
+ setImpl(new TopoDS_Shape(theShape->impl<TopoDS_Shape>()));
+ }
+}
+
bool GeomAPI_Edge::isLine() const
{
const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
return true;
return false;
}
+
+boost::shared_ptr<GeomAPI_Pnt> GeomAPI_Edge::firstPoint()
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ gp_Pnt aPoint;
+ aCurve->D0(aFirst, aPoint);
+ return boost::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z()));
+}
+
+boost::shared_ptr<GeomAPI_Pnt> GeomAPI_Edge::lastPoint()
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ gp_Pnt aPoint;
+ aCurve->D0(aLast, aPoint);
+ return boost::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z()));
+}
+
+boost::shared_ptr<GeomAPI_Circ> GeomAPI_Edge::circle()
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ if (aCurve) {
+ Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(aCurve);
+ if (aCirc) {
+ gp_Pnt aLoc = aCirc->Location();
+ boost::shared_ptr<GeomAPI_Pnt> aCenter(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z()));
+ gp_Dir anAxis = aCirc->Axis().Direction();
+ boost::shared_ptr<GeomAPI_Dir> aDir(new GeomAPI_Dir(anAxis.X(), anAxis.Y(), anAxis.Z()));
+ return boost::shared_ptr<GeomAPI_Circ>(new GeomAPI_Circ(aCenter, aDir, aCirc->Radius()));
+ }
+ }
+ return boost::shared_ptr<GeomAPI_Circ>(); // not circle
+}
#include <GeomAPI_Shape.h>
+class GeomAPI_Pnt;
+class GeomAPI_Circ;
+
/**\class GeomAPI_Edge
- * \ingroup DataModel
+* \ingroup DataModel
* \brief Interface to the edge object
*/
class GEOMAPI_EXPORT GeomAPI_Edge : public GeomAPI_Shape
{
- public:
- /// Creation of empty (null) shape
- GeomAPI_Edge();
-
- /// Returns whether the shape is a vertex
- virtual bool isVertex() const
- {
- return false;
- }
-
- /// Returns whether the shape is an edge
- virtual bool isEdge() const
- {
- return true;
- }
+public:
+ /// Creation of empty (null) shape
+ GeomAPI_Edge();
+
+ /// Creation of edge by the edge-shape
+ GeomAPI_Edge(const boost::shared_ptr<GeomAPI_Shape>& theShape);
/// Verifies that the edge is a line
bool isLine() const;
/// Verifies that the edge is an arc of circle
bool isArc() const;
+
+ /// Returns the first vertex coordinates of the edge
+ boost::shared_ptr<GeomAPI_Pnt> firstPoint();
+
+ /// Returns the Last vertex coordinates of the edge
+ boost::shared_ptr<GeomAPI_Pnt> lastPoint();
+
+ /// Returns a circle if edge is based on the cirsle curve
+ boost::shared_ptr<GeomAPI_Circ> circle();
};
#endif
#include<GeomAPI_Pnt.h>
#include<GeomAPI_XYZ.h>
+#include<GeomAPI_Pnt2d.h>
+#include<GeomAPI_Dir.h>
#include<gp_Pnt.hxx>
{
return MY_PNT->Distance(theOther->impl<gp_Pnt>());
}
+
+boost::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Pnt::to2D(const boost::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const boost::shared_ptr<GeomAPI_Dir>& theDirX, const boost::shared_ptr<GeomAPI_Dir>& theDirY)
+{
+ gp_Pnt anOriginPnt(theOrigin->x(), theOrigin->y(), theOrigin->z());
+ gp_Vec aVec(anOriginPnt, impl<gp_Pnt>());
+
+ double aX = aVec.X() * theDirX->x() + aVec.Y() * theDirX->y() + aVec.Z() * theDirX->z();
+ double aY = aVec.X() * theDirY->x() + aVec.Y() * theDirY->y() + aVec.Z() * theDirY->z();
+ return boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, aY));
+}
#include <boost/shared_ptr.hpp>
class GeomAPI_XYZ;
+class GeomAPI_Pnt2d;
+class GeomAPI_Dir;
/**\class GeomAPI_Pnt
* \ingroup DataModel
/// Distance between two points
double distance(const boost::shared_ptr<GeomAPI_Pnt>& theOther) const;
+
+ /// Projects a point to the plane defined by the origin and 2 axes vectors in this plane
+ boost::shared_ptr<GeomAPI_Pnt2d> to2D(const boost::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const boost::shared_ptr<GeomAPI_Dir>& theDirX,
+ const boost::shared_ptr<GeomAPI_Dir>& theDirY);
};
#endif
-
if (theAttr->isArgument()) {
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
+ if (myObject) {
+ myObject->attributeChanged();
+ }
}
}
return myResults.empty() ? boost::shared_ptr<ModelAPI_Result>() : *(myResults.begin());
}
+boost::shared_ptr<ModelAPI_Result> ModelAPI_Feature::lastResult()
+{
+ return myResults.empty() ? boost::shared_ptr<ModelAPI_Result>() : *(myResults.rbegin());
+}
+
void ModelAPI_Feature::setResult(const boost::shared_ptr<ModelAPI_Result>& theResult)
{
if (firstResult() == theResult) { // just updated
MODELAPI_EXPORT const std::list<boost::shared_ptr<ModelAPI_Result> >& results();
/// returns the first result in the list or NULL reference
MODELAPI_EXPORT boost::shared_ptr<ModelAPI_Result> firstResult();
+ /// returns the last result in the list or NULL reference
+ MODELAPI_EXPORT boost::shared_ptr<ModelAPI_Result> lastResult();
/// sets the alone result
MODELAPI_EXPORT void setResult(const boost::shared_ptr<ModelAPI_Result>& theResult);
/// sets the result by index (zero based), results before this must be set before
/// Returns the group identifier of this object
virtual std::string groupName() = 0;
+ /// Called on change of any argument-attribute of this object
+ MODELAPI_EXPORT virtual void attributeChanged()
+ {}
+
/// To use virtuality for destructors
virtual ~ModelAPI_Object() {}
Standard_Real aStart, aEnd;
Handle(V3d_View) aNullView;
- FeaturePtr myFeature;
+ FeaturePtr aMyFeature;
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aStart, aEnd);
GeomAdaptor_Curve aAdaptor(aCurve);
if (aAdaptor.GetType() == GeomAbs_Line) {
// Create line
- myFeature = theSketch->addFeature(SketchPlugin_Line::ID());
+ aMyFeature = theSketch->addFeature(SketchPlugin_Line::ID());
//DataPtr aData = myFeature->data();
//boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr =
} else if (aAdaptor.GetType() == GeomAbs_Circle) {
if (aAdaptor.IsClosed()) {
// Create circle
- myFeature = theSketch->addFeature(SketchPlugin_Circle::ID());
+ aMyFeature = theSketch->addFeature(SketchPlugin_Circle::ID());
//gp_Circ aCirc = aAdaptor.Circle();
//gp_Pnt aCenter = aCirc.Location();
//setFeatureValue(myFeature, aCirc.Radius(), SketchPlugin_Circle::RADIUS_ID());
} else {
// Create arc
- myFeature = theSketch->addFeature(SketchPlugin_Arc::ID());
+ aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID());
}
}
- if (myFeature) {
- DataPtr aData = myFeature->data();
+ if (aMyFeature) {
+ DataPtr aData = aMyFeature->data();
AttributeSelectionPtr anAttr =
boost::dynamic_pointer_cast<ModelAPI_AttributeSelection>
(aData->attribute(SketchPlugin_Feature::EXTERNAL_ID()));
anEdge->setImpl(new TopoDS_Shape(aShape));
anAttr->setValue(aRes, anEdge);
- myFeature->execute();
- return myFeature->firstResult();
+ aMyFeature->execute();
+ return aMyFeature->lastResult();
}
}
return ResultPtr();
#include <ModelAPI_Session.h>
#include <GeomAPI_Pnt2d.h>
+#include <GeomAPI_Circ.h>
#include <GeomDataAPI_Point2D.h>
#include <GeomDataAPI_Dir.h>
#include <GeomAlgoAPI_PointBuilder.h>
void SketchPlugin_Circle::initAttributes()
{
- data()->addAttribute(SketchPlugin_Circle::CENTER_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(SketchPlugin_Circle::RADIUS_ID(), ModelAPI_AttributeDouble::type());
+ data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
+ data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::type());
data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
// compute a circle point in 3D view
boost::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = boost::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Circle::CENTER_ID()));
- AttributeDoublePtr aRadiusAttr = boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
- data()->attribute(SketchPlugin_Circle::RADIUS_ID()));
+ GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+ AttributeDoublePtr aRadiusAttr =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(RADIUS_ID()));
if (aCenterAttr->isInitialized() && aRadiusAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
// make a visible point
boost::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
- //aShapes.push_back(aCenterPointShape);
boost::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
data(), 0);
aConstr1->setShape(aCenterPointShape);
setResult(aConstr2, 1);
}
}
- /*
- boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
- // store the result
- boost::shared_ptr<ModelAPI_ResultConstruction> aConstr =
- document()->createConstruction(data());
- aConstr->setShape(aCompound);
- aConstr->setIsInHistory(false);
- setResult(aConstr);
- */
}
}
return;
boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Circle::CENTER_ID()));
+ aData->attribute(CENTER_ID()));
aPoint1->move(theDeltaX, theDeltaY);
}
double SketchPlugin_Circle::distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint)
{
boost::shared_ptr<ModelAPI_Data> aData = data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Circle::CENTER_ID()));
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(CENTER_ID()));
return aPoint->pnt()->distance(thePoint);
}
bool SketchPlugin_Circle::isFixed() {
return data()->selection(EXTERNAL_ID())->context();
}
+
+void SketchPlugin_Circle::attributeChanged() {
+ static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
+ boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+ if (aSelection && !myIsUpdated) { // update arguments due to the selection value
+ myIsUpdated = true;
+ boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
+ boost::shared_ptr<GeomAPI_Circ> aCirc = anEdge->circle();
+ boost::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
+ aCenterAttr->setValue(sketch()->to2D(aCirc->center()));
+ real(RADIUS_ID())->setValue(aCirc->radius());
+ myIsUpdated = false;
+ }
+}
/// \param thePoint the point
virtual double distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+ /// Called on change of any argument-attribute of this object
+ SKETCHPLUGIN_EXPORT virtual void attributeChanged();
+
/// Use plugin manager for features creation
SketchPlugin_Circle();
};
void SketchPlugin_Line::initAttributes()
{
- data()->addAttribute(SketchPlugin_Line::START_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(SketchPlugin_Line::END_ID(), GeomDataAPI_Point2D::type());
+ data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
+ data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
if (aSketch) {
// compute a start point in 3D view
boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr = boost::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Line::START_ID()));
+ GeomDataAPI_Point2D>(data()->attribute(START_ID()));
// compute an end point in 3D view
boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr = boost::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Line::END_ID()));
+ GeomDataAPI_Point2D>(data()->attribute(END_ID()));
if (aStartAttr->isInitialized() && anEndAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
// make linear edge
- boost::shared_ptr<GeomAPI_Shape> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
+ boost::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
// store the result
boost::shared_ptr<ModelAPI_ResultConstruction> aConstr = document()->createConstruction(
data());
if (!aData->isValid())
return;
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Line::START_ID()));
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aData->attribute(START_ID()));
aPoint1->move(theDeltaX, theDeltaY);
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Line::END_ID()));
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aData->attribute(END_ID()));
aPoint2->move(theDeltaX, theDeltaY);
}
double aDelta = 0;
boost::shared_ptr<ModelAPI_Data> aData = data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Line::START_ID()));
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_Line::END_ID()));
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(START_ID()));
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(END_ID()));
GeomAPI_Lin2d aLin2d(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y());
bool SketchPlugin_Line::isFixed() {
return data()->selection(EXTERNAL_ID())->context();
}
+
+void SketchPlugin_Line::attributeChanged() {
+ static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
+ boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+ if (aSelection && !myIsUpdated) { // update arguments due to the selection value
+ myIsUpdated = true;
+ boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
+ boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_ID()));
+ aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
+ boost::shared_ptr<GeomDataAPI_Point2D> anEndAttr =
+ boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_ID()));
+ anEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
+ myIsUpdated = false;
+ }
+}
/// \param thePoint the point
virtual double distanceToPoint(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+ /// Called on change of any argument-attribute of this object
+ SKETCHPLUGIN_EXPORT virtual void attributeChanged();
+
/// Use plugin manager for features creation
SketchPlugin_Line();
};
return boost::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aSum));
}
+boost::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Sketch::to2D(
+ const boost::shared_ptr<GeomAPI_Pnt>& thePnt)
+{
+ boost::shared_ptr<GeomDataAPI_Point> aC = boost::dynamic_pointer_cast<GeomDataAPI_Point>(
+ data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+ boost::shared_ptr<GeomDataAPI_Dir> aX = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
+ boost::shared_ptr<GeomDataAPI_Dir> aY = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
+ return thePnt->to2D(aC->pnt(), aX->dir(), aY->dir());
+}
+
+
bool SketchPlugin_Sketch::isPlaneSet()
{
boost::shared_ptr<GeomDataAPI_Dir> aNormal = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
/// Construction result is allways recomuted on the fly
SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;}
+ /// Returns the point projected into the sketch plane
+ boost::shared_ptr<GeomAPI_Pnt2d> to2D(const boost::shared_ptr<GeomAPI_Pnt>& thePnt);
+
protected:
/// Creates a plane and append it to the list
/// \param theX the X normal value