[TD]initial implementation of cosmetic cicle command

This commit is contained in:
wandererfan
2023-09-19 08:41:22 -04:00
committed by WandererFan
parent 3a0582b507
commit 0b191c477b
12 changed files with 1141 additions and 5 deletions

View File

@@ -73,6 +73,16 @@
<UserDocu>tag = makeCosmeticCircleArc(center, radius, start, end) - add a CosmeticEdge at center with radius radius(View coordinates) from start angle to end angle. Returns tag of new CosmeticEdge.</UserDocu>
</Documentation>
</Methode>
<Methode Name="makeCosmeticCircle3d">
<Documentation>
<UserDocu>tag = makeCosmeticCircle3d(center, radius) - add a CosmeticEdge at center (3d point) with radius. Returns tag of new CosmeticEdge.</UserDocu>
</Documentation>
</Methode>
<Methode Name="makeCosmeticCircleArc3d">
<Documentation>
<UserDocu>tag = makeCosmeticCircleArc3d(center, radius, start, end) - add a CosmeticEdge at center (3d point) with radius from start angle to end angle. Returns tag of new CosmeticEdge.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getCosmeticEdge">
<Documentation>
<UserDocu>ce = getCosmeticEdge(id) - returns CosmeticEdge with unique id.</UserDocu>

View File

@@ -388,9 +388,9 @@ PyObject* DrawViewPartPy::makeCosmeticCircle(PyObject *args)
}
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = DrawUtil::invertY(static_cast<Base::VectorPy*>(pPnt1)->value());
Base::Vector3d pnt1 = static_cast<Base::VectorPy*>(pPnt1)->value();
TechDraw::BaseGeomPtr bg = std::make_shared<TechDraw::Circle> (pnt1, radius);
std::string newTag = dvp->addCosmeticEdge(bg);
std::string newTag = dvp->addCosmeticEdge(bg->inverted());
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce) {
ce->permaRadius = radius;
@@ -428,9 +428,97 @@ PyObject* DrawViewPartPy::makeCosmeticCircleArc(PyObject *args)
//from here on is almost duplicate of makeCosmeticCircle
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = DrawUtil::invertY(static_cast<Base::VectorPy*>(pPnt1)->value());
Base::Vector3d pnt1 = static_cast<Base::VectorPy*>(pPnt1)->value();
TechDraw::BaseGeomPtr bg = std::make_shared<TechDraw::AOC> (pnt1, radius, angle1, angle2);
std::string newTag = dvp->addCosmeticEdge(bg);
std::string newTag = dvp->addCosmeticEdge(bg->inverted());
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce) {
ce->permaRadius = radius;
ce->m_format.m_style = style;
ce->m_format.m_weight = weight;
if (!pColor)
ce->m_format.m_color = defCol;
else
ce->m_format.m_color = DrawUtil::pyTupleToColor(pColor);
}
else {
PyErr_SetString(PyExc_RuntimeError, "DVPPI:makeCosmeticCircleArc - arc creation failed");
return nullptr;
}
//int link =
dvp->add1CEToGE(newTag);
dvp->requestPaint();
return PyUnicode_FromString(newTag.c_str()); //return tag for new CE
}
PyObject* DrawViewPartPy::makeCosmeticCircle3d(PyObject *args)
{
PyObject* pPnt1 = nullptr;
double radius = 5.0;
int style = LineFormat::getDefEdgeStyle();
double weight = LineFormat::getDefEdgeWidth();
App::Color defCol = LineFormat::getDefEdgeColor();
PyObject* pColor = nullptr;
if (!PyArg_ParseTuple(args, "O!d|idO!", &(Base::VectorPy::Type), &pPnt1,
&radius,
&style, &weight,
&PyTuple_Type, &pColor)) {
return nullptr;
}
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = static_cast<Base::VectorPy*>(pPnt1)->value();
// center, project and invert the 3d point
Base::Vector3d centroid = dvp->getOriginalCentroid();
pnt1 = DrawUtil::invertY(dvp->projectPoint(pnt1 - centroid));
TechDraw::BaseGeomPtr bg = std::make_shared<TechDraw::Circle> (pnt1, radius);
std::string newTag = dvp->addCosmeticEdge(bg->inverted());
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce) {
ce->permaRadius = radius;
ce->m_format.m_style = style;
ce->m_format.m_weight = weight;
ce->m_format.m_color = pColor ? DrawUtil::pyTupleToColor(pColor) : defCol;
}
else {
PyErr_SetString(PyExc_RuntimeError, "DVPPI:makeCosmeticCircle - circle creation failed");
return nullptr;
}
//int link =
dvp->add1CEToGE(newTag);
dvp->requestPaint();
return PyUnicode_FromString(newTag.c_str()); //return tag for new CE
}
PyObject* DrawViewPartPy::makeCosmeticCircleArc3d(PyObject *args)
{
PyObject* pPnt1 = nullptr;
double radius = 5.0;
double angle1 = 0.0;
double angle2 = 360.0;
int style = LineFormat::getDefEdgeStyle();
double weight = LineFormat::getDefEdgeWidth();
App::Color defCol = LineFormat::getDefEdgeColor();
PyObject* pColor = nullptr;
if (!PyArg_ParseTuple(args, "O!ddd|idO!", &(Base::VectorPy::Type), &pPnt1,
&radius, &angle1, &angle2,
&style, &weight, &PyTuple_Type, &pColor)) {
return nullptr;
}
//from here on is almost duplicate of makeCosmeticCircle
DrawViewPart* dvp = getDrawViewPartPtr();
Base::Vector3d pnt1 = static_cast<Base::VectorPy*>(pPnt1)->value();
// center, project and invert the 3d point
Base::Vector3d centroid = dvp->getOriginalCentroid();
pnt1 = DrawUtil::invertY(dvp->projectPoint(pnt1 - centroid));
TechDraw::BaseGeomPtr bg = std::make_shared<TechDraw::AOC> (pnt1, radius, angle1, angle2);
std::string newTag = dvp->addCosmeticEdge(bg->inverted());
TechDraw::CosmeticEdge* ce = dvp->getCosmeticEdge(newTag);
if (ce) {
ce->permaRadius = radius;

View File

@@ -423,7 +423,7 @@ bool BaseGeom::closed()
// return a BaseGeom similar to this, but inverted with respect to Y axis
BaseGeomPtr BaseGeom::inverted()
{
Base::Console().Message("BG::inverted()\n");
// Base::Console().Message("BG::inverted()\n");
TopoDS_Shape invertedShape = ShapeUtils::invertGeometry(occEdge);
TopoDS_Edge invertedEdge = TopoDS::Edge(invertedShape);
return baseFactory(invertedEdge);

View File

@@ -147,6 +147,11 @@ class TechDrawExport BaseGeom : public std::enable_shared_from_this<BaseGeom>
void setCosmeticTag(std::string t) { cosmeticTag = t; }
Part::TopoShape asTopoShape(double scale);
virtual double getStartAngle() { return 0.0; }
virtual double getEndAngle() { return 0.0; }
virtual bool clockwiseAngle() { return false; }
virtual void clockwiseAngle(bool direction) { (void) direction; }
protected:
void createNewTag();
@@ -217,6 +222,10 @@ class TechDrawExport AOE: public Ellipse
~AOE() override = default;
public:
double getStartAngle() override { return startAngle; }
double getEndAngle() override { return endAngle; }
bool clockwiseAngle() override { return cw; }
void clockwiseAngle(bool direction) override { cw = direction; }
Base::Vector3d startPnt; //TODO: The points are used for drawing, the angles for bounding box calcs - seems redundant
Base::Vector3d endPnt;
Base::Vector3d midPnt;
@@ -241,6 +250,11 @@ class TechDrawExport AOC: public Circle
~AOC() override = default;
public:
double getStartAngle() override { return startAngle; }
double getEndAngle() override { return endAngle; }
bool clockwiseAngle() override { return cw; }
void clockwiseAngle(bool direction) override { cw = direction; }
std::string toString() const override;
void Save(Base::Writer& w) const override;
void Restore(Base::XMLReader& r) override;
@@ -284,6 +298,9 @@ class TechDrawExport BSpline: public BaseGeom
~BSpline() override = default;
public:
double getStartAngle() override { return startAngle; }
double getEndAngle() override { return endAngle; }
Base::Vector3d startPnt;
Base::Vector3d endPnt;
Base::Vector3d midPnt;

View File

@@ -87,6 +87,7 @@ set(TechDrawGui_UIC_SRCS
TaskProjection.ui
TaskComplexSection.ui
TaskDimRepair.ui
TaskCosmeticCircle.ui
)
@@ -228,6 +229,9 @@ SET(TechDrawGui_SRCS
TaskDimRepair.cpp
TaskDimRepair.h
TaskDimRepair.ui
TaskCosmeticCircle.cpp
TaskCosmeticCircle.h
TaskCosmeticCircle.ui
Widgets/CompassDialWidget.cpp
Widgets/CompassDialWidget.h
Widgets/CompassWidget.cpp

View File

@@ -57,6 +57,7 @@
#include "TaskRichAnno.h"
#include "TaskSurfaceFinishSymbols.h"
#include "TaskWeldingSymbol.h"
#include "TaskCosmeticCircle.h"
#include "ViewProviderViewPart.h"
@@ -73,6 +74,7 @@ void execCenterLine(Gui::Command* cmd);
void exec2LineCenterLine(Gui::Command* cmd);
void exec2PointCenterLine(Gui::Command* cmd);
void execLine2Points(Gui::Command* cmd);
void execCosmeticCircle(Gui::Command* cmd);
std::vector<std::string> getSelectedSubElements(Gui::Command* cmd,
TechDraw::DrawViewPart* &dvp,
std::string subType = "Edge");
@@ -1110,6 +1112,153 @@ void execLine2Points(Gui::Command* cmd)
is3d));
}
//===========================================================================
// TechDraw_CosmeticCircle
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawCosmeticCircle)
CmdTechDrawCosmeticCircle::CmdTechDrawCosmeticCircle()
: Command("TechDraw_CosmeticCircle")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Add Cosmetic Circle");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_CosmeticCircle";
sStatusTip = sToolTipText;
sPixmap = "actions/TechDraw_CosmeticCircle";
}
void CmdTechDrawCosmeticCircle::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
execCosmeticCircle(this);
updateActive();
Gui::Selection().clearSelection();
}
bool CmdTechDrawCosmeticCircle::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, true);
return (havePage && haveView);
}
void execCosmeticCircle(Gui::Command* cmd)
{
TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd);
if (!page) {
return;
}
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
TechDraw::DrawViewPart* baseFeat = nullptr;
std::vector<std::string> subNames2D;
std::vector< std::pair<Part::Feature*, std::string> > objs3D;
if (selection.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("Selection is empty."));
return;
}
for (auto& so: selection) {
if (so.getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
baseFeat = static_cast<TechDraw::DrawViewPart*> (so.getObject());
subNames2D = so.getSubNames();
} else if (so.getObject()->isDerivedFrom(Part::Feature::getClassTypeId())) {
std::vector<std::string> subNames3D = so.getSubNames();
for (auto& sub3D: subNames3D) {
std::pair<Part::Feature*, std::string> temp;
temp.first = static_cast<Part::Feature*>(so.getObject());
temp.second = sub3D;
objs3D.push_back(temp);
}
} else {
//garbage
}
}
if (!baseFeat) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("You must select a base View for the circle."));
return;
}
std::vector<std::string> edgeNames;
std::vector<std::string> vertexNames;
for (auto& s: subNames2D) {
std::string geomType = DrawUtil::getGeomTypeFromName(s);
if (geomType == "Vertex") {
vertexNames.push_back(s);
} else if (geomType == "Edge") {
edgeNames.push_back(s);
}
}
//check if editing existing edge
if (!edgeNames.empty() && (edgeNames.size() == 1)) {
TechDraw::CosmeticEdge* ce = baseFeat->getCosmeticEdgeBySelection(edgeNames.front());
if (!ce) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("Selection is not a Cosmetic edge."));
return;
}
Gui::Control().showDialog(new TaskDlgCosmeticCircle(baseFeat,
edgeNames.front()));
return;
}
std::vector<Base::Vector3d> points;
std::vector<bool> is3d;
//get the 2D points
if (!vertexNames.empty()) {
for (auto& v2d: vertexNames) {
int idx = DrawUtil::getIndexFromName(v2d);
TechDraw::VertexPtr v = baseFeat->getProjVertexByIndex(idx);
if (v) {
points.push_back(v->point());
is3d.push_back(false);
}
}
}
//get the 3D points
if (!objs3D.empty()) {
for (auto& o3D: objs3D) {
int idx = DrawUtil::getIndexFromName(o3D.second);
Part::TopoShape s = o3D.first->Shape.getShape();
TopoDS_Vertex v = TopoDS::Vertex(s.getSubShape(TopAbs_VERTEX, idx));
Base::Vector3d p = DrawUtil::vertex2Vector(v);
points.push_back(p);
is3d.push_back(true);
}
}
if (points.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong Selection"),
QObject::tr("Please select a center for the circle."));
return;
}
bool centerIs3d = false;
if (!is3d.empty()) {
centerIs3d = is3d.front();
}
Gui::Control().showDialog(new TaskDlgCosmeticCircle(baseFeat,
points.front(),
centerIs3d));
}
//===========================================================================
// TechDraw_CosmeticEraser
//===========================================================================
@@ -1500,6 +1649,7 @@ void CreateTechDrawCommandsAnnotate()
rcCmdMgr.addCommand(new CmdTechDraw2LineCenterLine());
rcCmdMgr.addCommand(new CmdTechDraw2PointCenterLine());
rcCmdMgr.addCommand(new CmdTechDraw2PointCosmeticLine());
rcCmdMgr.addCommand(new CmdTechDrawCosmeticCircle());
rcCmdMgr.addCommand(new CmdTechDrawAnnotation());
rcCmdMgr.addCommand(new CmdTechDrawCosmeticEraser());
rcCmdMgr.addCommand(new CmdTechDrawDecorateLine());

View File

@@ -54,6 +54,7 @@
<file>icons/actions/TechDraw_WeldSymbol.svg</file>
<file>icons/actions/TechDraw_SurfaceFinishSymbols.svg</file>
<file>icons/actions/TechDraw_ComplexSection.svg</file>
<file>icons/actions/TechDraw_CosmeticCircle.svg</file>
<file>icons/arrow-ccw.svg</file>
<file>icons/arrow-cw.svg</file>
<file>icons/arrow-down.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,304 @@
/***************************************************************************
* Copyright (c) 2023 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cmath>
# include <BRepBuilderAPI_MakeEdge.hxx>
#endif
#include <Base/Console.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/Cosmetic.h>
#include <Mod/TechDraw/App/Geometry.h>
#include "ui_TaskCosmeticCircle.h"
#include "TaskCosmeticCircle.h"
using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
using DU = DrawUtil;
//ctor for edit
TaskCosmeticCircle::TaskCosmeticCircle(TechDraw::DrawViewPart* partFeat,
std::string circleName) :
ui(new Ui_TaskCosmeticCircle),
m_partFeat(partFeat),
m_circleName(circleName),
m_ce(nullptr),
m_saveCE(nullptr),
m_createMode(false)
{
//existence of partFeat is checked in calling command
m_ce = m_partFeat->getCosmeticEdgeBySelection(m_circleName);
if (!m_ce) {
Base::Console().Error("TaskCosmeticCircle - bad parameters. Can not proceed.\n");
return;
}
ui->setupUi(this);
setUiEdit();
}
//ctor for creation
TaskCosmeticCircle::TaskCosmeticCircle(TechDraw::DrawViewPart* partFeat,
Base::Vector3d center, bool is3d) :
ui(new Ui_TaskCosmeticCircle),
m_partFeat(partFeat),
m_ce(nullptr),
m_saveCE(nullptr),
m_center(center),
m_createMode(true),
m_is3d(is3d)
{
//existence of partFeat is checked in calling command
ui->setupUi(this);
setUiPrimary();
}
TaskCosmeticCircle::~TaskCosmeticCircle()
{
if (m_saveCE) {
delete m_saveCE;
}
}
void TaskCosmeticCircle::updateTask()
{
// blockUpdate = true;
// blockUpdate = false;
}
void TaskCosmeticCircle::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
}
void TaskCosmeticCircle::setUiPrimary()
{
setWindowTitle(QObject::tr("Create Cosmetic Line"));
// Base::Console().Message("TCC::setUiPrimary() - m_center: %s is3d: %d\n",
// DU::formatVector(m_center).c_str(), m_is3d);
double rotDeg = m_partFeat->Rotation.getValue();
double rotRad = rotDeg * M_PI / 180.0;
Base::Vector3d centroid = m_partFeat->getCurrentCentroid();
Base::Vector3d p1;
if (m_is3d) {
// center, project and invert the 3d point
p1 = DrawUtil::invertY(m_partFeat->projectPoint(m_center - centroid));
ui->rb2d1->setChecked(false);
ui->rb3d1->setChecked(true);
} else {
// invert, unscale and unrotate the selected 2d point
// shift by centroid?
p1 = DU::invertY(m_center) / m_partFeat->getScale();
if (rotDeg != 0.0) {
// we always rotate around the origin.
p1.RotateZ(-rotRad);
}
ui->rb2d1->setChecked(true);
ui->rb3d1->setChecked(false);
}
ui->qsbCenterX->setUnit(Base::Unit::Length);
ui->qsbCenterX->setValue(p1.x);
ui->qsbCenterY->setUnit(Base::Unit::Length);
ui->qsbCenterY->setValue(p1.y);
ui->qsbCenterY->setUnit(Base::Unit::Length);
ui->qsbCenterZ->setValue(p1.z);
}
void TaskCosmeticCircle::setUiEdit()
{
setWindowTitle(QObject::tr("Edit Cosmetic Line"));
ui->rb2d1->setChecked(true);
ui->rb3d1->setChecked(false);
Base::Vector3d p1 = DrawUtil::invertY(m_ce->permaStart);
ui->qsbCenterX->setValue(p1.x);
ui->qsbCenterY->setValue(p1.y);
ui->qsbCenterZ->setValue(p1.z);
ui->qsbRadius->setValue(m_ce->permaRadius);
double angleDeg = m_ce->m_geometry->getStartAngle() * 180.0 / M_PI;
ui->qsbStartAngle->setValue(angleDeg);
angleDeg = m_ce->m_geometry->getEndAngle() * 180.0 / M_PI;
ui->qsbEndAngle->setValue(angleDeg);
}
//******************************************************************************
void TaskCosmeticCircle::createCosmeticCircle(void)
{
// Base::Console().Message("TCL::createCosmeticCircle()\n");
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Cosmetic Line"));
double x = ui->qsbCenterX->value().getValue();
double y = ui->qsbCenterY->value().getValue();
double z = ui->qsbCenterZ->value().getValue();
Base::Vector3d p0(x, y, z);
TechDraw::BaseGeomPtr bg;
if (ui->qsbStartAngle->value().getValue() == 0.0 &&
ui->qsbEndAngle->value().getValue() == 0.0) {
bg = std::make_shared<TechDraw::Circle> (p0, ui->qsbRadius->value().getValue());
} else {
bg = std::make_shared<TechDraw::AOC>(p0, ui->qsbRadius->value().getValue(),
ui->qsbStartAngle->value().getValue(),
ui->qsbEndAngle->value().getValue());
}
// note cEdges are inverted when added to the dvp geometry, so we need to
// invert them here
m_tag = m_partFeat->addCosmeticEdge(bg->inverted());
m_ce = m_partFeat->getCosmeticEdge(m_tag);
Gui::Command::commitCommand();
}
void TaskCosmeticCircle::updateCosmeticCircle(void)
{
// Base::Console().Message("TCL::updateCosmeticCircle()\n");
double x = ui->qsbCenterX->value().getValue();
double y = ui->qsbCenterY->value().getValue();
double z = ui->qsbCenterZ->value().getValue();
Base::Vector3d p0(x, y, z);
//replace the geometry
m_ce->permaRadius = ui->qsbRadius->value().getValue();
TechDraw::BaseGeomPtr bg;
if (ui->qsbStartAngle->value().getValue() == 0.0 &&
ui->qsbEndAngle->value().getValue() == 0.0) {
bg = std::make_shared<TechDraw::Circle> (p0, m_ce->permaRadius);
} else {
bg = std::make_shared<TechDraw::AOC>(p0, ui->qsbRadius->value().getValue(),
ui->qsbStartAngle->value().getValue(),
ui->qsbEndAngle->value().getValue());
}
m_ce->m_geometry = bg->inverted();
p0 = DU::invertY(p0);
m_ce->permaStart = p0;
m_ce->permaEnd = p0;
}
//******************************************************************************
bool TaskCosmeticCircle::accept()
{
if (m_createMode) {
createCosmeticCircle();
m_partFeat->add1CEToGE(m_tag);
m_partFeat->refreshCEGeoms();
m_partFeat->requestPaint();
} else {
//update mode
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update CosmeticCircle"));
updateCosmeticCircle();
m_partFeat->refreshCEGeoms();
m_partFeat->requestPaint();
Gui::Command::updateActive();
Gui::Command::commitCommand();
}
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return true;
}
bool TaskCosmeticCircle::reject()
{
//there's nothing to do.
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return false;
}
////////////////////////////////////////////////////////////////////////////////
TaskDlgCosmeticCircle::TaskDlgCosmeticCircle(TechDraw::DrawViewPart* partFeat,
Base::Vector3d point,
bool is3d)
: TaskDialog()
{
widget = new TaskCosmeticCircle(partFeat, point, is3d);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_CosmeticCircle"),
widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskDlgCosmeticCircle::TaskDlgCosmeticCircle(TechDraw::DrawViewPart* partFeat,
std::string circleName)
: TaskDialog()
{
widget = new TaskCosmeticCircle(partFeat, circleName);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_CosmeticCircle"),
widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskDlgCosmeticCircle::~TaskDlgCosmeticCircle()
{
}
void TaskDlgCosmeticCircle::update()
{
// widget->updateTask();
}
//==== calls from the TaskView ===============================================================
void TaskDlgCosmeticCircle::open()
{
}
void TaskDlgCosmeticCircle::clicked(int)
{
}
bool TaskDlgCosmeticCircle::accept()
{
widget->accept();
return true;
}
bool TaskDlgCosmeticCircle::reject()
{
widget->reject();
return true;
}
#include <Mod/TechDraw/Gui/moc_TaskCosmeticCircle.cpp>

View File

@@ -0,0 +1,128 @@
/***************************************************************************
* Copyright (c) 2023 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef TECHDRAWGUI_TASKCOSMETICCIRCLE_H
#define TECHDRAWGUI_TASKCOSMETICCIRCLE_H
#include <Base/Vector3D.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <Mod/TechDraw/TechDrawGlobal.h>
namespace TechDraw
{
class DrawPage;
class DrawView;
class DrawViewPart;
class CosmeticEdge;
class Face;
class LineFormat;
}
namespace TechDrawGui
{
class QGSPage;
class QGVPage;
class QGIView;
class QGIPrimPath;
class MDIViewPage;
class ViewProviderViewPart;
class Ui_TaskCosmeticCircle;
class TaskCosmeticCircle : public QWidget
{
Q_OBJECT
public:
TaskCosmeticCircle(TechDraw::DrawViewPart* partFeat,
Base::Vector3d center, bool is3d);
TaskCosmeticCircle(TechDraw::DrawViewPart* partFeat,
std::string circleName);
~TaskCosmeticCircle() override;
virtual bool accept();
virtual bool reject();
void updateTask();
protected:
void changeEvent(QEvent *e) override;
void setUiPrimary();
void setUiEdit();
void createCosmeticCircle();
void updateCosmeticCircle();
private:
std::unique_ptr<Ui_TaskCosmeticCircle> ui;
TechDraw::DrawViewPart* m_partFeat;
std::string m_circleName;
TechDraw::CosmeticEdge* m_ce;
TechDraw::CosmeticEdge* m_saveCE;
Base::Vector3d m_center;
double m_radius;
bool m_createMode;
std::string m_tag;
bool m_is3d;
};
class TaskDlgCosmeticCircle : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDlgCosmeticCircle(TechDraw::DrawViewPart* partFeat,
Base::Vector3d center, bool is3d);
TaskDlgCosmeticCircle(TechDraw::DrawViewPart* partFeat,
std::string circleName)
; ~TaskDlgCosmeticCircle() override;
public:
/// is called the TaskView when the dialog is opened
void open() override;
/// is called by the framework if an button is clicked which has no accept or reject role
void clicked(int) override;
/// is called by the framework if the dialog is accepted (Ok)
bool accept() override;
/// is called by the framework if the dialog is rejected (Cancel)
bool reject() override;
/// is called by the framework if the user presses the help button
void helpRequested() override { return;}
bool isAllowedAlterDocument() const override
{ return false; }
void update();
protected:
private:
TaskCosmeticCircle* widget;
Gui::TaskView::TaskBox* taskbox;
};
} //namespace TechDrawGui
#endif // #ifndef TECHDRAWGUI_TASKCOSMETICCIRCLE_H

View File

@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TechDrawGui::TaskCosmeticCircle</class>
<widget class="QWidget" name="TechDrawGui::TaskCosmeticCircle">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>368</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Cosmetic Circle</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>View</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="le_View">
<property name="enabled">
<bool>false</bool>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QRadioButton" name="rb2d1">
<property name="toolTip">
<string>Treat the center point as a 2d point within the parent View. Z coordinate is ignored.</string>
</property>
<property name="text">
<string>2d Point</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="rb3d1">
<property name="toolTip">
<string>Treat the center point as a 3d point and project it onto the parent View.</string>
</property>
<property name="text">
<string>3d Point</string>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Circle Center</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,4">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>X:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbCenterX">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Y:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbCenterY">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Z:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbCenterZ">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,4">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Radius:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbRadius">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5" columnstretch="1,0">
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Start Angle:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbEndAngle">
<property name="toolTip">
<string>End angle (conventional) of arc in degrees.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>End Angle:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::QuantitySpinBox" name="qsbStartAngle">
<property name="toolTip">
<string>Start angle (conventional) of arc in degrees. </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Arc of Circle</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::QuantitySpinBox</class>
<extends>QWidget</extends>
<header>Gui/QuantitySpinBox.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="Resources/TechDraw.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -176,6 +176,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
*lines << "TechDraw_2LineCenterLine";
*lines << "TechDraw_2PointCenterLine";
*lines << "TechDraw_2PointCosmeticLine";
*lines << "TechDraw_CosmeticCircle";
*lines << "Separator";
*lines << "TechDraw_DecorateLine";
*lines << "TechDraw_ShowAll";
@@ -376,6 +377,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
*anno << "TechDraw_CosmeticVertexGroup";
*anno << "TechDraw_CenterLineGroup";
*anno << "TechDraw_2PointCosmeticLine";
*anno << "TechDraw_CosmeticCircle";
*anno << "TechDraw_CosmeticEraser";
*anno << "TechDraw_DecorateLine";
*anno << "TechDraw_ShowAll";
@@ -485,6 +487,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
*anno << "TechDraw_CosmeticVertexGroup";
*anno << "TechDraw_CenterLineGroup";
*anno << "TechDraw_2PointCosmeticLine";
*anno << "TechDraw_CosmeticCircle";
*anno << "TechDraw_CosmeticEraser";
*anno << "TechDraw_DecorateLine";
*anno << "TechDraw_ShowAll";