[Part]add scale command & feature
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
#include "FeatureChamfer.h"
|
||||
#include "FeatureCompound.h"
|
||||
#include "FeatureExtrusion.h"
|
||||
#include "FeatureScale.h"
|
||||
#include "FeatureFace.h"
|
||||
#include "FeatureFillet.h"
|
||||
#include "FeatureGeometrySet.h"
|
||||
@@ -440,6 +441,7 @@ PyMOD_INIT_FUNC(Part)
|
||||
Part::Compound ::init();
|
||||
Part::Compound2 ::init();
|
||||
Part::Extrusion ::init();
|
||||
Part::Scale ::init();
|
||||
Part::Revolution ::init();
|
||||
Part::Mirroring ::init();
|
||||
Part::ImportStep ::init();
|
||||
|
||||
@@ -189,6 +189,8 @@ SET(Features_SRCS
|
||||
FeatureCompound.h
|
||||
FeatureExtrusion.cpp
|
||||
FeatureExtrusion.h
|
||||
FeatureScale.cpp
|
||||
FeatureScale.h
|
||||
FeatureFace.cpp
|
||||
FeatureFace.h
|
||||
FeatureFillet.cpp
|
||||
|
||||
162
src/Mod/Part/App/FeatureScale.cpp
Normal file
162
src/Mod/Part/App/FeatureScale.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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 <BRepBuilderAPI_GTransform.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Precision.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include "FeatureScale.h"
|
||||
|
||||
using namespace Part;
|
||||
|
||||
PROPERTY_SOURCE(Part::Scale, Part::Feature)
|
||||
|
||||
Scale::Scale()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Base, (nullptr), "Scale", App::Prop_None, "Shape to scale");
|
||||
ADD_PROPERTY_TYPE(Uniform, (true), "Scale", App::Prop_None, "If true, scale equally in all directions");
|
||||
ADD_PROPERTY_TYPE(UniformScale, (1.0), "Scale", App::Prop_None, "Uniform scale factor - 1.0 means no scaling");
|
||||
ADD_PROPERTY_TYPE(XScale, (1.0), "Scale", App::Prop_None, "Scale factor in X direction - 1.0 means no scaling");
|
||||
ADD_PROPERTY_TYPE(YScale, (1.0), "Scale", App::Prop_None, "Scale factor in Y direction - 1.0 means no scaling");
|
||||
ADD_PROPERTY_TYPE(ZScale, (1.0), "Scale", App::Prop_None, "Scale factor in Z direction - 1.0 means no scaling");
|
||||
}
|
||||
|
||||
short Scale::mustExecute() const
|
||||
{
|
||||
if (Base.isTouched() ||
|
||||
Uniform.isTouched() ||
|
||||
UniformScale.isTouched() ||
|
||||
XScale.isTouched() ||
|
||||
YScale.isTouched() ||
|
||||
ZScale.isTouched()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scale::ScaleParameters Scale::computeFinalParameters()
|
||||
{
|
||||
Scale::ScaleParameters result;
|
||||
result.uniform = Uniform.getValue();
|
||||
result.uniformScale = UniformScale.getValue();
|
||||
result.XScale = XScale.getValue();
|
||||
result.YScale = YScale.getValue();
|
||||
result.ZScale = ZScale.getValue();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TopoShape Scale::scaleShape(const TopoShape& source, const Scale::ScaleParameters& params)
|
||||
{
|
||||
TopoShape result;
|
||||
|
||||
if (params.uniform) {
|
||||
result = uniformScale(source, params.uniformScale);
|
||||
return result;
|
||||
}
|
||||
|
||||
return nonuniformScale(source, params);
|
||||
}
|
||||
|
||||
TopoShape Scale::uniformScale(const TopoShape& source, const double& factor)
|
||||
{
|
||||
// Base::Console().Message("FS::uniformScale()\n");
|
||||
TopoDS_Shape transShape;
|
||||
TopoShape transTopo;
|
||||
try {
|
||||
gp_Trsf scaleTransform;
|
||||
scaleTransform.SetScale(gp_Pnt(0, 0, 0), factor);
|
||||
|
||||
BRepBuilderAPI_Transform mkTrf(source.getShape(), scaleTransform);
|
||||
transShape = mkTrf.Shape();
|
||||
}
|
||||
catch (...) {
|
||||
return transTopo;
|
||||
}
|
||||
transTopo.setShape(transShape);
|
||||
return transTopo;
|
||||
}
|
||||
|
||||
TopoShape Scale::nonuniformScale(const TopoShape& source, const Scale::ScaleParameters& params)
|
||||
{
|
||||
// Base::Console().Message("FS::nonuniformScale()\n");
|
||||
Base::Matrix4D matScale;
|
||||
matScale.scale(params.XScale, params.YScale, params.ZScale);
|
||||
|
||||
// copy the FreeCAD matrix cell values to an OCC matrix
|
||||
gp_GTrsf mat;
|
||||
mat.SetValue(1,1,matScale[0][0]);
|
||||
mat.SetValue(2,1,matScale[1][0]);
|
||||
mat.SetValue(3,1,matScale[2][0]);
|
||||
mat.SetValue(1,2,matScale[0][1]);
|
||||
mat.SetValue(2,2,matScale[1][1]);
|
||||
mat.SetValue(3,2,matScale[2][1]);
|
||||
mat.SetValue(1,3,matScale[0][2]);
|
||||
mat.SetValue(2,3,matScale[1][2]);
|
||||
mat.SetValue(3,3,matScale[2][2]);
|
||||
mat.SetValue(1,4,matScale[0][3]);
|
||||
mat.SetValue(2,4,matScale[1][3]);
|
||||
mat.SetValue(3,4,matScale[2][3]);
|
||||
|
||||
// this copy step seems to eliminate Part.OCCError: gp_GTrsf::Trsf() - non-orthogonal GTrsf
|
||||
// which may to be related to the tesselation of the input shape. See Github issue #9651
|
||||
// for more detail.
|
||||
BRepBuilderAPI_Copy copier(source.getShape());
|
||||
TopoShape transTopo;
|
||||
try {
|
||||
BRepBuilderAPI_GTransform mkTrf(copier.Shape(), mat, true);
|
||||
transTopo.setShape(mkTrf.Shape());
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Warning("FeatureScale failed on nonuniform scale\n");
|
||||
return transTopo;
|
||||
}
|
||||
return transTopo;
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn* Scale::execute()
|
||||
{
|
||||
// Base::Console().Message("FS::execute()\n");
|
||||
App::DocumentObject* link = Base.getValue();
|
||||
if (!link)
|
||||
return new App::DocumentObjectExecReturn("No object linked");
|
||||
|
||||
try {
|
||||
Scale::ScaleParameters params = computeFinalParameters();
|
||||
TopoShape result = scaleShape(Feature::getShape(link), params);
|
||||
this->Shape.setValue(result);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
}
|
||||
}
|
||||
|
||||
90
src/Mod/Part/App/FeatureScale.h
Normal file
90
src/Mod/Part/App/FeatureScale.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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 PART_FEATURESCALE_H
|
||||
#define PART_FEATURESCALE_H
|
||||
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyUnits.h>
|
||||
|
||||
#include "FaceMakerCheese.h"
|
||||
#include "PartFeature.h"
|
||||
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
||||
class PartExport Scale : public Part::Feature
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Part::Scale);
|
||||
|
||||
public:
|
||||
Scale();
|
||||
|
||||
App::PropertyLink Base;
|
||||
App::PropertyBool Uniform;
|
||||
App::PropertyFloat UniformScale;
|
||||
App::PropertyFloat XScale;
|
||||
App::PropertyFloat YScale;
|
||||
App::PropertyFloat ZScale;
|
||||
|
||||
/**
|
||||
* @brief The ScaleParameters struct is supposed to be filled with final
|
||||
* scale parameters, after resolving links, applying mode logic,
|
||||
* reversing, etc., and be passed to scaleShape.
|
||||
*/
|
||||
struct ScaleParameters {
|
||||
bool uniform;
|
||||
double uniformScale{1.0};
|
||||
double XScale{1.0};
|
||||
double YScale{1.0};
|
||||
double ZScale{1.0};
|
||||
};
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
/// recalculate the feature
|
||||
App::DocumentObjectExecReturn *execute() override;
|
||||
short mustExecute() const override;
|
||||
/// returns the type name of the view provider
|
||||
const char* getViewProviderName() const override {
|
||||
return "PartGui::ViewProviderScale";
|
||||
}
|
||||
//@}
|
||||
Scale::ScaleParameters computeFinalParameters();
|
||||
|
||||
/**
|
||||
* @brief scaleShape powers the extrusion feature.
|
||||
* @param source: the shape to be scaled
|
||||
* @param params: scale parameters
|
||||
* @return result of scaling
|
||||
*/
|
||||
static TopoShape scaleShape(const TopoShape& source, const ScaleParameters& params);
|
||||
static TopoShape uniformScale(const TopoShape& source, const double& factor);
|
||||
static TopoShape nonuniformScale(const TopoShape& source, const Scale::ScaleParameters& params);
|
||||
};
|
||||
|
||||
} //namespace Part
|
||||
|
||||
|
||||
#endif // PART_FEATURESCALE_H
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "ViewProviderEllipseParametric.h"
|
||||
#include "ViewProviderExt.h"
|
||||
#include "ViewProviderExtrusion.h"
|
||||
#include "ViewProviderScale.h"
|
||||
#include "ViewProviderHelixParametric.h"
|
||||
#include "ViewProviderPrimitive.h"
|
||||
#include "ViewProviderPython.h"
|
||||
@@ -171,6 +172,7 @@ PyMOD_INIT_FUNC(PartGui)
|
||||
PartGui::ViewProviderImport ::init();
|
||||
PartGui::ViewProviderCurveNet ::init();
|
||||
PartGui::ViewProviderExtrusion ::init();
|
||||
PartGui::ViewProviderScale ::init();
|
||||
PartGui::ViewProvider2DObject ::init();
|
||||
PartGui::ViewProvider2DObjectPython ::init();
|
||||
PartGui::ViewProvider2DObjectGrid ::init();
|
||||
|
||||
@@ -49,6 +49,7 @@ set(PartGui_UIC_SRCS
|
||||
DlgExportStep.ui
|
||||
DlgExportHeaderStep.ui
|
||||
DlgExtrusion.ui
|
||||
DlgScale.ui
|
||||
DlgImportStep.ui
|
||||
DlgFilletEdges.ui
|
||||
DlgImportExportIges.ui
|
||||
@@ -101,6 +102,9 @@ SET(PartGui_SRCS
|
||||
DlgExtrusion.cpp
|
||||
DlgExtrusion.h
|
||||
DlgExtrusion.ui
|
||||
DlgScale.cpp
|
||||
DlgScale.h
|
||||
DlgScale.ui
|
||||
DlgFilletEdges.cpp
|
||||
DlgFilletEdges.h
|
||||
DlgFilletEdges.ui
|
||||
@@ -204,6 +208,8 @@ SET(PartGui_SRCS
|
||||
ViewProviderImport.h
|
||||
ViewProviderExtrusion.cpp
|
||||
ViewProviderExtrusion.h
|
||||
ViewProviderScale.cpp
|
||||
ViewProviderScale.h
|
||||
ViewProvider2DObject.cpp
|
||||
ViewProvider2DObject.h
|
||||
ViewProviderMirror.cpp
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "CrossSections.h"
|
||||
#include "DlgBooleanOperation.h"
|
||||
#include "DlgExtrusion.h"
|
||||
#include "DlgScale.h"
|
||||
#include "DlgFilletEdges.h"
|
||||
#include "DlgPrimitives.h"
|
||||
#include "DlgProjectionOnSurface.h"
|
||||
@@ -1294,6 +1295,35 @@ bool CmdPartExtrude::isActive()
|
||||
return (hasActiveDocument() && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Part_Scale
|
||||
//===========================================================================
|
||||
DEF_STD_CMD_A(CmdPartScale)
|
||||
|
||||
CmdPartScale::CmdPartScale()
|
||||
:Command("Part_Scale")
|
||||
{
|
||||
sAppModule = "Part";
|
||||
sGroup = QT_TR_NOOP("Part");
|
||||
sMenuText = QT_TR_NOOP("Scale...");
|
||||
sToolTipText = QT_TR_NOOP("Scale a selected shape");
|
||||
sWhatsThis = "Part_Scale";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Part_Scale";
|
||||
}
|
||||
|
||||
void CmdPartScale::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Control().showDialog(new PartGui::TaskScale());
|
||||
}
|
||||
|
||||
bool CmdPartScale::isActive()
|
||||
{
|
||||
return (hasActiveDocument() && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Part_MakeFace
|
||||
//===========================================================================
|
||||
@@ -2425,6 +2455,7 @@ void CreatePartCommands()
|
||||
rcCmdMgr.addCommand(new CmdPartReverseShape());
|
||||
rcCmdMgr.addCommand(new CmdPartBoolean());
|
||||
rcCmdMgr.addCommand(new CmdPartExtrude());
|
||||
rcCmdMgr.addCommand(new CmdPartScale());
|
||||
rcCmdMgr.addCommand(new CmdPartMakeFace());
|
||||
rcCmdMgr.addCommand(new CmdPartMirror());
|
||||
rcCmdMgr.addCommand(new CmdPartRevolve());
|
||||
|
||||
363
src/Mod/Part/Gui/DlgScale.cpp
Normal file
363
src/Mod/Part/Gui/DlgScale.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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 <BRepAdaptor_Curve.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <Precision.hxx>
|
||||
# include <ShapeExtend_Explorer.hxx>
|
||||
# include <TopExp_Explorer.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopTools_HSequenceOfShape.hxx>
|
||||
# include <QKeyEvent>
|
||||
# include <QMessageBox>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Link.h>
|
||||
#include <App/Part.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Utilities.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include "ui_DlgScale.h"
|
||||
#include "DlgScale.h"
|
||||
|
||||
|
||||
FC_LOG_LEVEL_INIT("Part",true,true)
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
DlgScale::DlgScale(QWidget* parent, Qt::WindowFlags fl)
|
||||
: QDialog(parent, fl), ui(new Ui_DlgScale)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setupConnections();
|
||||
|
||||
ui->dsbUniformScale->setDecimals(Base::UnitsApi::getDecimals());
|
||||
ui->dsbXScale->setDecimals(Base::UnitsApi::getDecimals());
|
||||
ui->dsbYScale->setDecimals(Base::UnitsApi::getDecimals());
|
||||
ui->dsbZScale->setDecimals(Base::UnitsApi::getDecimals());
|
||||
findShapes();
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the object and frees any allocated resources
|
||||
*/
|
||||
DlgScale::~DlgScale()
|
||||
{
|
||||
// no need to delete child widgets, Qt does it all for us
|
||||
}
|
||||
|
||||
void DlgScale::setupConnections()
|
||||
{
|
||||
connect(ui->rbUniform, &QRadioButton::toggled,
|
||||
this, &DlgScale::onUniformScaleToggled);
|
||||
}
|
||||
|
||||
void DlgScale::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
QDialog::changeEvent(e);
|
||||
}
|
||||
|
||||
void DlgScale::onUniformScaleToggled(bool state)
|
||||
{
|
||||
// Base::Console().Message("DS::onUniformScaleToggled()\n");
|
||||
if (state) {
|
||||
// this is uniform scaling, so hide the non-uniform input fields
|
||||
ui->dsbUniformScale->setEnabled(true);
|
||||
ui->dsbXScale->setEnabled(false);
|
||||
ui->dsbYScale->setEnabled(false);
|
||||
ui->dsbZScale->setEnabled(false);
|
||||
} else {
|
||||
// this is non-uniform scaling, so hide the uniform input fields
|
||||
ui->dsbUniformScale->setEnabled(false);
|
||||
ui->dsbXScale->setEnabled(true);
|
||||
ui->dsbYScale->setEnabled(true);
|
||||
ui->dsbZScale->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
App::DocumentObject& DlgScale::getShapeToScale() const
|
||||
{
|
||||
// Base::Console().Message("DS::getShapeToScale()\n");
|
||||
std::vector<App::DocumentObject*> objs = this->getShapesToScale();
|
||||
if (objs.empty())
|
||||
throw Base::ValueError("No shapes selected");
|
||||
return *(objs[0]);
|
||||
}
|
||||
|
||||
void DlgScale::findShapes()
|
||||
{
|
||||
// Base::Console().Message("DS::findShapes()\n");
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc)
|
||||
return;
|
||||
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
|
||||
m_document = activeDoc->getName();
|
||||
m_label = activeDoc->Label.getValue();
|
||||
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (auto obj : objs) {
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(obj);
|
||||
if (topoShape.isNull()) {
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape shape = topoShape.getShape();
|
||||
if (shape.IsNull()) continue;
|
||||
if (canScale(shape)) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget);
|
||||
item->setText(0, QString::fromUtf8(obj->Label.getValue()));
|
||||
item->setData(0, Qt::UserRole, QString::fromLatin1(obj->getNameInDocument()));
|
||||
Gui::ViewProvider* vp = activeGui->getViewProvider(obj);
|
||||
if (vp)
|
||||
item->setIcon(0, vp->getIcon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DlgScale::canScale(const TopoDS_Shape& shape) const
|
||||
{
|
||||
if (shape.IsNull()) {
|
||||
return false;
|
||||
}
|
||||
// if the shape is a solid or a compound containing shapes, then we can scale it
|
||||
TopAbs_ShapeEnum type = shape.ShapeType();
|
||||
|
||||
if (type == TopAbs_VERTEX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == TopAbs_COMPOUND ||
|
||||
type == TopAbs_COMPSOLID) {
|
||||
TopExp_Explorer xp;
|
||||
xp.Init(shape, TopAbs_SHAPE);
|
||||
for ( ; xp.More() ; xp.Next()) {
|
||||
// there is at least 1 sub shape inside the compound
|
||||
if (!xp.Current().IsNull()) {
|
||||
// found a non-null shape
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// did not find a non-null shape
|
||||
return false;
|
||||
} else {
|
||||
// not a Vertex, Compound or CompSolid, must be one of Edge, Wire, Face, Shell or
|
||||
// Solid, all of which we can scale.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DlgScale::accept()
|
||||
{
|
||||
// Base::Console().Message("DS::accept()\n");
|
||||
try{
|
||||
apply();
|
||||
QDialog::accept();
|
||||
} catch (Base::AbortException&){
|
||||
Base::Console().Message("DS::accept - apply failed!\n");
|
||||
};
|
||||
}
|
||||
|
||||
void DlgScale::apply()
|
||||
{
|
||||
// Base::Console().Message("DS::apply()\n");
|
||||
try{
|
||||
if (!validate()) {
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
tr("No scalable shapes selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::WaitCursor wc;
|
||||
App::Document* activeDoc = App::GetApplication().getDocument(m_document.c_str());
|
||||
if (!activeDoc) {
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
tr("The document '%1' doesn't exist.").arg(QString::fromUtf8(m_label.c_str())));
|
||||
return;
|
||||
}
|
||||
activeDoc->openTransaction("Scale");
|
||||
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part");
|
||||
bool addBaseName = hGrp->GetBool("AddBaseObjectName", false);
|
||||
|
||||
std::vector<App::DocumentObject*> objects = this->getShapesToScale();
|
||||
for (App::DocumentObject* sourceObj: objects) {
|
||||
assert(sourceObj);
|
||||
|
||||
if (Part::Feature::getTopoShape(sourceObj).isNull()){
|
||||
FC_ERR("Object " << sourceObj->getFullName()
|
||||
<< " is not Part object (has no OCC shape). Can't scale it.");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
name = sourceObj->getDocument()->getUniqueObjectName("Scale").c_str();
|
||||
if (addBaseName) {
|
||||
//FIXME: implement
|
||||
//QString baseName = QString::fromLatin1("Scale_%1").arg(sourceObjectName);
|
||||
//label = QString::fromLatin1("%1_Scale").arg((*it)->text(0));
|
||||
}
|
||||
|
||||
FCMD_OBJ_DOC_CMD(sourceObj,"addObject('Part::Scale','" << name << "')");
|
||||
auto newObj = sourceObj->getDocument()->getObject(name.c_str());
|
||||
|
||||
this->writeParametersToFeature(*newObj, sourceObj);
|
||||
|
||||
Gui::Command::copyVisual(newObj, "ShapeColor", sourceObj);
|
||||
Gui::Command::copyVisual(newObj, "LineColor", sourceObj);
|
||||
Gui::Command::copyVisual(newObj, "PointColor", sourceObj);
|
||||
|
||||
FCMD_OBJ_HIDE(sourceObj);
|
||||
}
|
||||
|
||||
activeDoc->commitTransaction();
|
||||
Gui::Command::updateActive();
|
||||
}
|
||||
catch (Base::AbortException&){
|
||||
throw;
|
||||
}
|
||||
catch (Base::Exception &err){
|
||||
QMessageBox::critical(this,
|
||||
windowTitle(),
|
||||
tr("Creating Scale failed.\n%1")
|
||||
.arg(QCoreApplication::translate("Exception", err.what())));
|
||||
return;
|
||||
}
|
||||
catch(...) {
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
tr("Creating Scale failed.\n%1").arg(QString::fromUtf8("Unknown error")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DlgScale::reject()
|
||||
{
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> DlgScale::getShapesToScale() const
|
||||
{
|
||||
// Base::Console().Message("DS::getShapesToScale()\n");
|
||||
QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
|
||||
App::Document* doc = App::GetApplication().getDocument(m_document.c_str());
|
||||
if (!doc)
|
||||
throw Base::RuntimeError("Document lost");
|
||||
|
||||
std::vector<App::DocumentObject*> objects;
|
||||
for (auto item : items) {
|
||||
App::DocumentObject* obj = doc->getObject(item->data(0, Qt::UserRole).toString().toLatin1());
|
||||
if (!obj)
|
||||
throw Base::RuntimeError("Object not found");
|
||||
objects.push_back(obj);
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
bool DlgScale::validate()
|
||||
{
|
||||
QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
|
||||
App::Document* doc = App::GetApplication().getDocument(m_document.c_str());
|
||||
if (!doc)
|
||||
throw Base::RuntimeError("Document lost");
|
||||
|
||||
std::vector<App::DocumentObject*> objects;
|
||||
for (auto item : items) {
|
||||
App::DocumentObject* obj = doc->getObject(item->data(0, Qt::UserRole).toString().toLatin1());
|
||||
if (!obj)
|
||||
throw Base::RuntimeError("Object not found");
|
||||
objects.push_back(obj);
|
||||
}
|
||||
return !objects.empty();
|
||||
}
|
||||
|
||||
void DlgScale::writeParametersToFeature(App::DocumentObject &feature, App::DocumentObject* base) const
|
||||
{
|
||||
// Base::Console().Message("DS::writeParametersToFeature()\n");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f = App.getDocument('%s').getObject('%s')", feature.getDocument()->getName(), feature.getNameInDocument());
|
||||
|
||||
if (!base) {
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.Base = App.getDocument('%s').getObject('%s')", base->getDocument()->getName(), base->getNameInDocument());
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.Uniform = %s", ui->rbUniform->isChecked() ? "True" : "False");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.UniformScale = %.7f", ui->dsbUniformScale->value());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.XScale = %.7f", ui->dsbXScale->value());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.YScale = %.7f", ui->dsbYScale->value());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"f.ZScale = %.7f", ui->dsbZScale->value());
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
TaskScale::TaskScale()
|
||||
{
|
||||
widget = new DlgScale();
|
||||
taskbox = new Gui::TaskView::TaskBox(
|
||||
Gui::BitmapFactory().pixmap("Part_Scale"),
|
||||
widget->windowTitle(), true, nullptr);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
bool TaskScale::accept()
|
||||
{
|
||||
widget->accept();
|
||||
return (widget->result() == QDialog::Accepted);
|
||||
}
|
||||
|
||||
bool TaskScale::reject()
|
||||
{
|
||||
widget->reject();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TaskScale::clicked(int id)
|
||||
{
|
||||
if (id == QDialogButtonBox::Apply) {
|
||||
try{
|
||||
widget->apply();
|
||||
} catch (Base::AbortException&){
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_DlgScale.cpp"
|
||||
94
src/Mod/Part/Gui/DlgScale.h
Normal file
94
src/Mod/Part/Gui/DlgScale.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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 PARTGUI_DLGSCALE_H
|
||||
#define PARTGUI_DLGSCALE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <string>
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Mod/Part/App/FeatureScale.h>
|
||||
|
||||
class TopoDS_Shape;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class Ui_DlgScale;
|
||||
class DlgScale : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DlgScale(QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
|
||||
~DlgScale() override;
|
||||
void accept() override;
|
||||
void apply();
|
||||
void reject() override;
|
||||
|
||||
std::vector<App::DocumentObject*> getShapesToScale() const;
|
||||
|
||||
bool validate();
|
||||
|
||||
void writeParametersToFeature(App::DocumentObject& feature, App::DocumentObject* base) const;
|
||||
|
||||
protected:
|
||||
void findShapes();
|
||||
bool canScale(const TopoDS_Shape&) const;
|
||||
void changeEvent(QEvent *e) override;
|
||||
|
||||
private:
|
||||
void setupConnections();
|
||||
void onUniformScaleToggled(bool on);
|
||||
|
||||
private:
|
||||
///returns link to any of selected source shapes. Throws if nothing is selected for scaling.
|
||||
App::DocumentObject& getShapeToScale() const;
|
||||
|
||||
std::unique_ptr<Ui_DlgScale> ui;
|
||||
std::string m_document, m_label;
|
||||
};
|
||||
|
||||
class TaskScale : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskScale();
|
||||
|
||||
public:
|
||||
bool accept() override;
|
||||
bool reject() override;
|
||||
void clicked(int) override;
|
||||
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{ return QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Close; }
|
||||
|
||||
private:
|
||||
DlgScale* widget;
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
#endif // PARTGUI_DLGSCALE_H
|
||||
231
src/Mod/Part/Gui/DlgScale.ui
Normal file
231
src/Mod/Part/Gui/DlgScale.ui
Normal file
@@ -0,0 +1,231 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PartGui::DlgScale</class>
|
||||
<widget class="QDialog" name="PartGui::DlgScale">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>319</width>
|
||||
<height>360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Scale</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>X Factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbYScale">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2147480000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Z Factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbUniform">
|
||||
<property name="toolTip">
|
||||
<string>Scale the object by a single factor in all directions.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Uniform Scaling</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbXScale">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2147480000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Y Factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="rbNonUniform">
|
||||
<property name="toolTip">
|
||||
<string>Specify a different scale factor for each cardinal direction.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Non-Uniform Scaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbUniformScale">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2147480000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbZScale">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>2147480000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="toolTip">
|
||||
<string>Select shape(s) that should be scaled</string>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Shape</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -65,6 +65,7 @@
|
||||
<file>icons/tools/Part_ColorFace.svg</file>
|
||||
<file>icons/tools/Part_Element_Copy.svg</file>
|
||||
<file>icons/tools/Part_Extrude.svg</file>
|
||||
<file>icons/tools/Part_Scale.svg</file>
|
||||
<file>icons/tools/Part_Fillet.svg</file>
|
||||
<file>icons/tools/Part_Loft.svg</file>
|
||||
<file>icons/tools/Part_MakeFace.svg</file>
|
||||
|
||||
243
src/Mod/Part/Gui/Resources/icons/tools/Part_Scale.svg
Normal file
243
src/Mod/Part/Gui/Resources/icons/tools/Part_Scale.svg
Normal file
@@ -0,0 +1,243 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2766"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2768">
|
||||
<linearGradient
|
||||
id="linearGradient3856">
|
||||
<stop
|
||||
style="stop-color:#3465a4;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3858" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3860" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3824">
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3826" />
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3828" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3787">
|
||||
<stop
|
||||
id="stop3789"
|
||||
offset="0"
|
||||
style="stop-color:#0619c0;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3791"
|
||||
offset="1"
|
||||
style="stop-color:#379cfb;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3864">
|
||||
<stop
|
||||
id="stop3866"
|
||||
offset="0"
|
||||
style="stop-color:#0619c0;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3868"
|
||||
offset="1"
|
||||
style="stop-color:#379cfb;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientTransform="matrix(0,-1.4500001,1.4705882,0,-15.05882,91.45)"
|
||||
y2="36.079998"
|
||||
x2="21.689653"
|
||||
y1="29.279999"
|
||||
x1="56.172409"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3036"
|
||||
xlink:href="#linearGradient3895" />
|
||||
<linearGradient
|
||||
id="linearGradient3895">
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3897" />
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3899" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="43.940212"
|
||||
x2="32.329041"
|
||||
y1="18.865765"
|
||||
x1="44.058071"
|
||||
gradientTransform="matrix(0.38366341,-0.38366341,0.41875298,0.41875298,12.196434,25.003375)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3012"
|
||||
xlink:href="#linearGradient3895" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3824"
|
||||
id="linearGradient3830"
|
||||
x1="591.59064"
|
||||
y1="103.1946"
|
||||
x2="599.1272"
|
||||
y2="128.1946"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-0.9420628,1.000004)" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3856"
|
||||
id="linearGradient3862"
|
||||
x1="613.25824"
|
||||
y1="135.1946"
|
||||
x2="595.35895"
|
||||
y2="68.194603"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<g
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3518"
|
||||
transform="matrix(1.0614931,0,0,1,-612.96941,-69.194602)">
|
||||
<path
|
||||
id="rect3446"
|
||||
d="m 580.28581,72.194602 3e-5,14 5.65241,0 0,-8 1.88414,0 0,-6 z m 11.30486,0 0,6 7.53655,0 0,-6 z m 11.30483,0 0,6 7.53655,0 0,-6 z m 11.30483,0 0,6 7.53655,0 0,-6 z m 11.30483,0 0,6 3.76828,0 0,4 5.65241,0 0,-10 z m 3.76828,14 0,8 5.65241,0 0,-8 z m -48.9876,4 0,8 5.65241,0 0,-8 z m 48.9876,8 0,7.999998 5.65241,0 0,-7.999998 z m 0,11.999998 0,8 5.65241,0 0,-8 z m 0,12 0,2 -3.76828,0 0,6 9.42069,0 0,-8 z m -18.84139,2 0,6 11.30483,0 0,-6 z"
|
||||
style="fill:url(#linearGradient3862);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.94120501999999990;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
<path
|
||||
style="fill:none;stroke:#0b1521;stroke-width:7.7648201;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 583.11204,105.1946 0,22 20.72553,0 0,-22 z"
|
||||
id="path3018" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient3830);stroke-width:3.88241005;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 583.11204,105.1946 0,19.93618 0,2.06382 20.72553,0 0,-22 z"
|
||||
id="path3018-1" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:1.94120502;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 586.88032,126.1946 16.01518,0 0,-17 m 1.88413,-5 -22.60966,0 0,24"
|
||||
id="path3018-1-7" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 36,57 10,0"
|
||||
id="path3832"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 52,57 5,0 0,-2 3,0"
|
||||
id="path3834"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 57,48 0,-6"
|
||||
id="path3836"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 57,36 0,-6"
|
||||
id="path3838"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 57,24 0,-6"
|
||||
id="path3840"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 53,8 0,-3 7,0"
|
||||
id="path3842"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 46,5 40,5"
|
||||
id="path3844"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 34,5 28,5"
|
||||
id="path3846"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 22,5 16,5"
|
||||
id="path3848"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 10,5 5,5 5,16"
|
||||
id="path3850"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 5,22 0,6"
|
||||
id="path3852"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 57,12 57,9"
|
||||
id="path3854"
|
||||
transform="matrix(0.94206924,0,0,1,577.45963,69.194602)" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:url(#linearGradient3012);fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 35,15 39.062816,19.37832 31,27 l 6,6 7.71967,-7.964826 4.24264,4.242641 L 49,15 z"
|
||||
id="path3343" />
|
||||
<path
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 39.550023,17 2.32515,2.37832 -7.987667,7.653821 3.080353,3.112494 7.751811,-7.937888 2.221642,2.240472 L 47.000002,17 z"
|
||||
id="path3343-2" />
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata5370">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<cc:license
|
||||
rdf:resource="" />
|
||||
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[wmayer]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_Scale.svg</dc:identifier>
|
||||
<dc:relation>http://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>square</rdf:li>
|
||||
<rdf:li>arrow</rdf:li>
|
||||
<rdf:li>dotted line</rdf:li>
|
||||
<rdf:li />
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
<dc:description>A small square in the bottom left corner of a large dotted box with an arrow pointing from the top left corner of the inner box to the top left corner of the outer box</dc:description>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.7 KiB |
47
src/Mod/Part/Gui/ViewProviderScale.cpp
Normal file
47
src/Mod/Part/Gui/ViewProviderScale.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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"
|
||||
|
||||
#include "ViewProviderScale.h"
|
||||
#include <Mod/Part/App/FeatureScale.h>
|
||||
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
PROPERTY_SOURCE(PartGui::ViewProviderScale,PartGui::ViewProviderPart)
|
||||
|
||||
ViewProviderScale::ViewProviderScale()
|
||||
{
|
||||
sPixmap = "Part_Scale.svg";
|
||||
}
|
||||
|
||||
ViewProviderScale::~ViewProviderScale() = default;
|
||||
|
||||
std::vector<App::DocumentObject*> ViewProviderScale::claimChildren()const
|
||||
{
|
||||
std::vector<App::DocumentObject*> temp;
|
||||
temp.push_back(static_cast<Part::Scale*>(getObject())->Base.getValue());
|
||||
|
||||
return temp;
|
||||
}
|
||||
49
src/Mod/Part/Gui/ViewProviderScale.h
Normal file
49
src/Mod/Part/Gui/ViewProviderScale.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Wanderer Fan <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 PARTGUI_VIEWPROVIDERSCALE_H
|
||||
#define PARTGUI_VIEWPROVIDERSCALE_H
|
||||
|
||||
#include "ViewProvider.h"
|
||||
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class PartGuiExport ViewProviderScale : public ViewProviderPart
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(PartGui::ViewProviderScale);
|
||||
|
||||
public:
|
||||
/// constructor
|
||||
ViewProviderScale();
|
||||
/// destructor
|
||||
~ViewProviderScale() override;
|
||||
|
||||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren() const override;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
|
||||
#endif // PARTGUI_VIEWPROVIDERSCALE_H
|
||||
@@ -122,6 +122,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
<< bop << join << split << compound
|
||||
<< "Separator"
|
||||
<< "Part_Extrude"
|
||||
<< "Part_Scale"
|
||||
<< "Part_Revolve"
|
||||
<< "Part_Mirror"
|
||||
<< "Part_Fillet"
|
||||
@@ -181,6 +182,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
Gui::ToolBarItem* tool = new Gui::ToolBarItem(root);
|
||||
tool->setCommand("Part tools");
|
||||
*tool << "Part_Extrude"
|
||||
<< "Part_Scale"
|
||||
<< "Part_Revolve"
|
||||
<< "Part_Mirror"
|
||||
<< "Part_Fillet"
|
||||
|
||||
Reference in New Issue
Block a user