diff --git a/src/Mod/TechDraw/App/Cosmetic.h b/src/Mod/TechDraw/App/Cosmetic.h
index 91cbf02a25..2f1f9f4b7d 100644
--- a/src/Mod/TechDraw/App/Cosmetic.h
+++ b/src/Mod/TechDraw/App/Cosmetic.h
@@ -120,7 +120,6 @@ protected:
//********** CosmeticEdge ******************************************************
-//?? should this inherit BaseGeom or have a BaseGeom member?
class TechDrawExport CosmeticEdge : public Base::Persistence, public TechDraw::BaseGeom
{
TYPESYSTEM_HEADER();
@@ -147,7 +146,7 @@ public:
CosmeticEdge* copy(void) const;
CosmeticEdge* clone(void) const;
- Base::Vector3d permaStart; //persistent unscaled start/end points in View coords?
+ Base::Vector3d permaStart; //persistent unscaled start/end points in View coords
Base::Vector3d permaEnd;
double permaRadius;
// void unscaleEnds(double scale);
diff --git a/src/Mod/TechDraw/App/CosmeticEdgePy.xml b/src/Mod/TechDraw/App/CosmeticEdgePy.xml
index 76583a8cd3..ea534e2338 100644
--- a/src/Mod/TechDraw/App/CosmeticEdgePy.xml
+++ b/src/Mod/TechDraw/App/CosmeticEdgePy.xml
@@ -37,18 +37,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Gives the position of one end of this CosmeticEdge as vector.
+
+
+
+
+
+ Gives the position of one end of this CosmeticEdge as vector.
+
+
+
+
+
+ Gives the position of center point of this CosmeticEdge as vector.
+
+
+
+
+
+ Gives the radius of CosmeticEdge in mm.
+
+
+
+
+
diff --git a/src/Mod/TechDraw/App/CosmeticEdgePyImp.cpp b/src/Mod/TechDraw/App/CosmeticEdgePyImp.cpp
index e0edbd6d90..03c40c4f19 100644
--- a/src/Mod/TechDraw/App/CosmeticEdgePyImp.cpp
+++ b/src/Mod/TechDraw/App/CosmeticEdgePyImp.cpp
@@ -26,6 +26,11 @@
# include
#endif
+#include
+#include
+#include
+#include
+
#include
@@ -206,59 +211,135 @@ Py::String CosmeticEdgePy::getTag(void) const
// }
//}
-//Py::Object CosmeticEdgePy::getStart(void) const
-//{
-// Base::Vector3d point = getCosmeticEdgePtr()->permaStart;
-// point = DrawUtil::invertY(point);
-// return Py::asObject(new Base::VectorPy(point));
-//}
+Py::Object CosmeticEdgePy::getStart(void) const
+{
+ Base::Vector3d point = getCosmeticEdgePtr()->permaStart;
+ return Py::asObject(new Base::VectorPy(point));
+}
-//void CosmeticEdgePy::setStart(Py::Object arg)
-//{
-// PyObject* p = arg.ptr();
-// if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
-// Base::Vector3d point = static_cast(p)->value();
-// getCosmeticEdgePtr()->permaStart =
-// DrawUtil::invertY(point);
-// }
-// else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
-// Base::Vector3d point = Base::getVectorFromTuple(p);
-// getCosmeticEdgePtr()->permaStart =
-// DrawUtil::invertY(point);
-// }
-// else {
-// std::string error = std::string("type must be 'Vector', not ");
-// error += p->ob_type->tp_name;
-// throw Py::TypeError(error);
-// }
-//}
+void CosmeticEdgePy::setStart(Py::Object arg)
+{
+ PyObject* p = arg.ptr();
+ Base::Vector3d pNew;
+ if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
+ pNew = static_cast(p)->value();
+ }
+ else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
+ pNew = Base::getVectorFromTuple(p);
+ }
+ else {
+ std::string error = std::string("type must be 'Vector', not ");
+ error += p->ob_type->tp_name;
+ throw Py::TypeError(error);
+ }
-//Py::Object CosmeticEdgePy::getEnd(void) const
-//{
-// Base::Vector3d point = getCosmeticEdgePtr()->permaEnd;
-// point = DrawUtil::invertY(point);
-// return Py::asObject(new Base::VectorPy(point));
-//}
+ pNew = DrawUtil::invertY(pNew);
+ Base::Vector3d pEnd = getCosmeticEdgePtr()->permaEnd;
+ pEnd = DrawUtil::invertY(pEnd);
+ gp_Pnt gp1(pNew.x,pNew.y,pNew.z);
+ gp_Pnt gp2(pEnd.x,pEnd.y,pEnd.z);
+ TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp1, gp2);
+ auto oldGeom = getCosmeticEdgePtr()->m_geometry;
+ getCosmeticEdgePtr()->m_geometry = TechDraw::BaseGeom::baseFactory(e);
+ getCosmeticEdgePtr()->permaStart = pNew;
+ delete oldGeom;
+}
-//void CosmeticEdgePy::setEnd(Py::Object arg)
-//{
-// PyObject* p = arg.ptr();
-// if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
-// Base::Vector3d point = static_cast(p)->value();
-// getCosmeticEdgePtr()->permaEnd =
-// DrawUtil::invertY(point);
-// }
-// else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
-// Base::Vector3d point = Base::getVectorFromTuple(p);
-// getCosmeticEdgePtr()->permaEnd =
-// DrawUtil::invertY(point);
-// }
-// else {
-// std::string error = std::string("type must be 'Vector', not ");
-// error += p->ob_type->tp_name;
-// throw Py::TypeError(error);
-// }
-//}
+Py::Object CosmeticEdgePy::getEnd(void) const
+{
+ Base::Vector3d point = getCosmeticEdgePtr()->permaEnd;
+ return Py::asObject(new Base::VectorPy(point));
+}
+
+void CosmeticEdgePy::setEnd(Py::Object arg)
+{
+ PyObject* p = arg.ptr();
+ Base::Vector3d pNew;
+ if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
+ pNew = static_cast(p)->value();
+ }
+ else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
+ pNew = Base::getVectorFromTuple(p);
+ }
+ else {
+ std::string error = std::string("type must be 'Vector', not ");
+ error += p->ob_type->tp_name;
+ throw Py::TypeError(error);
+ }
+
+ pNew = DrawUtil::invertY(pNew);
+ Base::Vector3d pStart = getCosmeticEdgePtr()->permaStart;
+ pStart = DrawUtil::invertY(pStart);
+ gp_Pnt gp1(pNew.x,pNew.y,pNew.z);
+ gp_Pnt gp2(pStart.x,pStart.y,pStart.z);
+ TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp2, gp1);
+ auto oldGeom = getCosmeticEdgePtr()->m_geometry;
+ getCosmeticEdgePtr()->m_geometry = TechDraw::BaseGeom::baseFactory(e);
+ getCosmeticEdgePtr()->permaEnd = pNew;
+ delete oldGeom;
+}
+
+Py::Object CosmeticEdgePy::getRadius(void) const
+{
+ double r = getCosmeticEdgePtr()->permaRadius;
+ return Py::asObject(PyFloat_FromDouble(r));
+}
+
+void CosmeticEdgePy::setRadius(Py::Object arg)
+{
+ //TODO: check if the edge has a radius attrib
+ PyObject* p = arg.ptr();
+ double r;
+ if (PyObject_TypeCheck(p, &PyFloat_Type)) {
+ r = PyFloat_AsDouble(p);
+ }
+ else if (PyObject_TypeCheck(p, &PyLong_Type)) {
+ r = (double) PyLong_AsLong(p);
+ }
+ else {
+ std::string error = std::string("type must be 'Float' or 'Int', not ");
+ error += p->ob_type->tp_name;
+ throw Py::TypeError(error);
+ }
+
+ getCosmeticEdgePtr()->permaRadius = r;
+ auto oldGeom = getCosmeticEdgePtr()->m_geometry;
+ getCosmeticEdgePtr()->m_geometry = new TechDraw::Circle(getCosmeticEdgePtr()->permaStart, r);
+ delete oldGeom;
+}
+
+Py::Object CosmeticEdgePy::getCenter(void) const
+{
+ Base::Vector3d point = getCosmeticEdgePtr()->permaStart;
+ return Py::asObject(new Base::VectorPy(point));
+}
+
+void CosmeticEdgePy::setCenter(Py::Object arg)
+{
+ PyObject* p = arg.ptr();
+ Base::Vector3d pNew;
+ if (PyObject_TypeCheck(p, &(Base::VectorPy::Type))) {
+ pNew = static_cast(p)->value();
+ }
+ else if (PyObject_TypeCheck(p, &PyTuple_Type)) {
+ pNew = Base::getVectorFromTuple(p);
+ }
+ else {
+ std::string error = std::string("type must be 'Vector', not ");
+ error += p->ob_type->tp_name;
+ throw Py::TypeError(error);
+ }
+
+ pNew = DrawUtil::invertY(pNew);
+ auto oldGeom = getCosmeticEdgePtr()->m_geometry;
+ TechDraw::Circle* oldCircle = dynamic_cast(oldGeom);
+
+ getCosmeticEdgePtr()->permaStart = pNew;
+ getCosmeticEdgePtr()->permaEnd = pNew;
+ getCosmeticEdgePtr()->permaRadius = oldCircle->radius;
+ getCosmeticEdgePtr()->m_geometry = new TechDraw::Circle(getCosmeticEdgePtr()->permaStart, oldCircle->radius);
+ delete oldGeom;
+}
PyObject *CosmeticEdgePy::getCustomAttributes(const char* /*attr*/) const
{
diff --git a/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp b/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp
index 548ffd894a..04bd0603c7 100644
--- a/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp
+++ b/src/Mod/TechDraw/App/DrawViewPartPyImp.cpp
@@ -348,8 +348,8 @@ PyObject* DrawViewPartPy::makeCosmeticCircle(PyObject *args)
{
PyObject* pPnt1 = nullptr;
double radius = 5.0;
- double angle1 = 0.0;
- double angle2 = 360.0;
+// double angle1 = 0.0;
+// double angle2 = 360.0;
int style = LineFormat::getDefEdgeStyle();
double weight = LineFormat::getDefEdgeWidth();
App::Color defCol = LineFormat::getDefEdgeColor();
@@ -364,22 +364,13 @@ PyObject* DrawViewPartPy::makeCosmeticCircle(PyObject *args)
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = DrawUtil::invertY(static_cast(pPnt1)->value());
- gp_Pnt loc(pnt1.x, pnt1.y, pnt1.z);
- gp_Dir dir(0,0,1);
- gp_Ax1 axis(loc, dir);
- gp_Circ circle;
- circle.SetAxis(axis);
- circle.SetRadius(radius);
-
- Handle(Geom_Circle) hCircle = new Geom_Circle (circle);
- BRepBuilderAPI_MakeEdge aMakeEdge(hCircle, angle1*(M_PI/180), angle2*(M_PI/180));
- TopoDS_Edge edge = aMakeEdge.Edge();
- TechDraw::BaseGeom* bg = TechDraw::BaseGeom::baseFactory(edge);
+ TechDraw::BaseGeom* bg = new TechDraw::Circle(pnt1, radius);
std::string newTag = dvp->addCosmeticEdge(bg);
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce != nullptr) {
ce->permaStart = pnt1;
ce->permaEnd = pnt1;
+ ce->permaRadius = radius;
ce->m_format.m_style = style;
ce->m_format.m_weight = weight;
if (pColor == nullptr) {
@@ -418,25 +409,13 @@ PyObject* DrawViewPartPy::makeCosmeticCircleArc(PyObject *args)
//from here on is almost duplicate of makeCosmeticCircle
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = DrawUtil::invertY(static_cast(pPnt1)->value());
- gp_Pnt loc(pnt1.x, pnt1.y, pnt1.z);
- gp_Dir dir(0,0,1);
- gp_Ax1 axis(loc, dir);
- gp_Circ circle;
- circle.SetAxis(axis);
- circle.SetRadius(radius); //full circle @ right loc
- Handle(Geom_Circle) hCircle = new Geom_Circle (circle);
- BRepBuilderAPI_MakeEdge aMakeEdge(hCircle, -angle2*(M_PI/180), -angle1*(M_PI/180)); //hack!
- // right result, but ugly:
- // Qt angles are cw, OCC angles are CCW
- // Qt -y is up, OCC -y is down
-
- TopoDS_Edge edge = aMakeEdge.Edge();
- TechDraw::BaseGeom* bg = TechDraw::BaseGeom::baseFactory(edge);
+ TechDraw::BaseGeom* bg = new TechDraw::AOC(pnt1, radius, angle1, angle2);
std::string newTag = dvp->addCosmeticEdge(bg);
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce != nullptr) {
ce->permaStart = pnt1;
ce->permaEnd = pnt1;
+ ce->permaRadius = radius;
ce->m_format.m_style = style;
ce->m_format.m_weight = weight;
if (pColor == nullptr) {
diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp
index 5b6e1a9413..a242ee9298 100644
--- a/src/Mod/TechDraw/App/Geometry.cpp
+++ b/src/Mod/TechDraw/App/Geometry.cpp
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -584,6 +585,25 @@ Ellipse::Ellipse(const TopoDS_Edge &e)
angle = xaxis.AngleWithRef(gp_Dir(1, 0, 0), gp_Dir(0, 0, -1));
}
+Ellipse::Ellipse(Base::Vector3d c, double mnr, double mjr)
+{
+ geomType = ELLIPSE;
+ center = c;
+ major = mjr;
+ minor = mnr;
+ angle = 0;
+
+ GC_MakeEllipse me(gp_Ax2(gp_Pnt(c.x,c.y,c.z), gp_Dir(0.0,0.0,1.0)),
+ major, minor);
+ if (!me.IsDone()) {
+ Base::Console().Message("G:Ellipse - failed to make Ellipse\n");
+ }
+ const Handle(Geom_Ellipse) gEllipse = me.Value();
+ BRepBuilderAPI_MakeEdge mkEdge(gEllipse, 0.0, 2 * M_PI);
+ if (mkEdge.IsDone()) {
+ occEdge = mkEdge.Edge();
+ }
+}
AOE::AOE(const TopoDS_Edge &e) : Ellipse(e)
{
@@ -629,6 +649,27 @@ Circle::Circle(void)
center = Base::Vector3d(0.0, 0.0, 0.0);
}
+Circle::Circle(Base::Vector3d c, double r)
+{
+ geomType = CIRCLE;
+ radius = r;
+ center = c;
+ gp_Pnt loc(c.x, c.y, c.z);
+ gp_Dir dir(0,0,1);
+ gp_Ax1 axis(loc, dir);
+ gp_Circ circle;
+ circle.SetAxis(axis);
+ circle.SetRadius(r);
+ double angle1 = 0.0;
+ double angle2 = 360.0;
+
+ Handle(Geom_Circle) hCircle = new Geom_Circle (circle);
+ BRepBuilderAPI_MakeEdge aMakeEdge(hCircle, angle1*(M_PI/180), angle2*(M_PI/180));
+ TopoDS_Edge edge = aMakeEdge.Edge();
+ occEdge = edge;
+}
+
+
Circle::Circle(const TopoDS_Edge &e)
{
geomType = CIRCLE; //center, radius
@@ -706,6 +747,50 @@ AOC::AOC(const TopoDS_Edge &e) : Circle(e)
}
}
+AOC::AOC(Base::Vector3d c, double r, double sAng, double eAng) : Circle()
+{
+ geomType = ARCOFCIRCLE;
+
+ radius = r;
+ center = c;
+ gp_Pnt loc(c.x, c.y, c.z);
+ gp_Dir dir(0,0,1);
+ gp_Ax1 axis(loc, dir);
+ gp_Circ circle;
+ circle.SetAxis(axis);
+ circle.SetRadius(r);
+
+ Handle(Geom_Circle) hCircle = new Geom_Circle (circle);
+ BRepBuilderAPI_MakeEdge aMakeEdge(hCircle, sAng*(M_PI/180), eAng*(M_PI/180));
+ TopoDS_Edge edge = aMakeEdge.Edge();
+ occEdge = edge;
+
+ BRepAdaptor_Curve adp(edge);
+
+ double f = adp.FirstParameter();
+ double l = adp.LastParameter();
+ gp_Pnt s = adp.Value(f);
+ gp_Pnt m = adp.Value((l+f)/2.0);
+ gp_Pnt ePt = adp.Value(l); //if start == end, it isn't an arc!
+ gp_Vec v1(m,s); //vector mid to start
+ gp_Vec v2(m,ePt); //vector mid to end
+ gp_Vec v3(0,0,1); //stdZ
+ double a = v3.DotCross(v1,v2); //error if v1 = v2?
+
+ startAngle = fmod(f,2.0*M_PI);
+ endAngle = fmod(l,2.0*M_PI);
+ cw = (a < 0) ? true: false;
+ largeArc = (fabs(l-f) > M_PI) ? true : false;
+
+ startPnt = Base::Vector3d(s.X(), s.Y(), s.Z());
+ endPnt = Base::Vector3d(ePt.X(), ePt.Y(), s.Z());
+ midPnt = Base::Vector3d(m.X(), m.Y(), s.Z());
+ if (edge.Orientation() == TopAbs_REVERSED) {
+ reversed = true;
+ }
+}
+
+
AOC::AOC(void) : Circle()
{
geomType = ARCOFCIRCLE;
diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h
index d1f587e579..29db108b31 100644
--- a/src/Mod/TechDraw/App/Geometry.h
+++ b/src/Mod/TechDraw/App/Geometry.h
@@ -133,8 +133,9 @@ typedef std::vector BaseGeomPtrVector; //obs?
class TechDrawExport Circle: public BaseGeom
{
public:
- Circle(const TopoDS_Edge &e);
Circle(void);
+ Circle(const TopoDS_Edge &e);
+ Circle(Base::Vector3d center, double radius);
~Circle() = default;
public:
@@ -150,7 +151,8 @@ class TechDrawExport Circle: public BaseGeom
class TechDrawExport Ellipse: public BaseGeom
{
public:
- Ellipse(const TopoDS_Edge &e);
+ Ellipse(const TopoDS_Edge &e);
+ Ellipse(Base::Vector3d c, double mnr, double mjr);
~Ellipse() = default;
public:
@@ -188,6 +190,7 @@ class TechDrawExport AOC: public Circle
{
public:
AOC(const TopoDS_Edge &e);
+ AOC(Base::Vector3d c, double r, double s, double e);
AOC(void);
~AOC() = default;