Surface: apply clang format

This commit is contained in:
wmayer
2023-09-04 01:11:59 +02:00
committed by Chris Hennes
parent 016a3de360
commit 255ddb746c
45 changed files with 1398 additions and 1088 deletions

View File

@@ -43,7 +43,8 @@ namespace Surface
class Module: public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("Surface")
Module()
: Py::ExtensionModule<Module>("Surface")
{
initialize("This module is the Surface module.");// register with Python
}
@@ -51,7 +52,7 @@ public:
private:
};
PyObject *initModule()
PyObject* initModule()
{
return Base::Interpreter().addModule(new Module);
}
@@ -64,16 +65,17 @@ PyMOD_INIT_FUNC(Surface)
try {
Base::Interpreter().runString("import Part");
}
catch (const Base::Exception &e) {
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
PyMOD_Return(nullptr);
}
PyObject *mod = Surface::initModule();
PyObject* mod = Surface::initModule();
Base::Console().Log("Loading Surface module... done\n");
Base::Interpreter().addType(&Surface::BlendPointPy::Type, mod, "BlendPoint");
Base::Interpreter().addType(&Surface::BlendCurvePy::Type, mod, "BlendCurve");
// clang-format off
// Add types to module
Surface::Filling ::init();
Surface::Sewing ::init();
@@ -82,6 +84,7 @@ PyMOD_INIT_FUNC(Surface)
Surface::Extend ::init();
Surface::FeatureBlendCurve ::init();
Surface::Sections ::init();
// clang-format on
PyMOD_Return(mod);
}

View File

@@ -71,8 +71,9 @@ Handle(Geom_BezierCurve) BlendCurve::compute()
}
Handle(Geom_BezierCurve) curve;
if (num_poles > (curve->MaxDegree() + 1))// use Geom_BezierCurve max degree
if (num_poles > (curve->MaxDegree() + 1)) {// use Geom_BezierCurve max degree
Standard_Failure::Raise("number of constraints exceeds bezier curve capacity");
}
TColStd_Array1OfReal knots(1, 2 * num_poles);
for (int i = 1; i <= num_poles; ++i) {
@@ -89,7 +90,13 @@ Handle(Geom_BezierCurve) BlendCurve::compute()
for (size_t i = 0; i < nb_pts; ++i) {
math_Matrix bezier_eval(1, blendPoints[i].nbVectors(), 1, num_poles, 0.0);
Standard_Integer first_non_zero;
BSplCLib::EvalBsplineBasis(blendPoints[i].nbVectors() - 1, num_poles, knots, params(cons_idx), first_non_zero, bezier_eval, Standard_False);
BSplCLib::EvalBsplineBasis(blendPoints[i].nbVectors() - 1,
num_poles,
knots,
params(cons_idx),
first_non_zero,
bezier_eval,
Standard_False);
int idx2 = 1;
for (int it2 = 0; it2 < blendPoints[i].nbVectors(); ++it2) {
OCCmatrix.SetRow(row_idx, bezier_eval.Row(idx2));
@@ -104,14 +111,17 @@ Handle(Geom_BezierCurve) BlendCurve::compute()
}
math_Gauss gauss(OCCmatrix);
gauss.Solve(res_x);
if (!gauss.IsDone())
if (!gauss.IsDone()) {
Standard_Failure::Raise("Failed to solve equations");
}
gauss.Solve(res_y);
if (!gauss.IsDone())
if (!gauss.IsDone()) {
Standard_Failure::Raise("Failed to solve equations");
}
gauss.Solve(res_z);
if (!gauss.IsDone())
if (!gauss.IsDone()) {
Standard_Failure::Raise("Failed to solve equations");
}
TColgp_Array1OfPnt poles(1, num_poles);
for (int idx = 1; idx <= num_poles; ++idx) {
@@ -120,7 +130,7 @@ Handle(Geom_BezierCurve) BlendCurve::compute()
Handle(Geom_BezierCurve) bezier = new Geom_BezierCurve(poles);
return bezier;
}
catch (Standard_Failure &) {
catch (Standard_Failure&) {
PyErr_SetString(Base::PyExc_FC_CADKernelError, "Failed to compute bezier curve");
}
return nullptr;
@@ -136,7 +146,7 @@ void BlendCurve::setSize(int i, double f, bool relative)
}
blendPoints[i].setSize(size);
}
catch (Standard_Failure &e) {
catch (Standard_Failure& e) {
PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString());
}
}

View File

@@ -24,14 +24,14 @@
#define SURFACE_BLEND_CURVE_H
#include <Geom_BezierCurve.hxx>
#include <Mod/Surface/SurfaceGlobal.h>
#include <Mod/Surface/App/Blending/BlendPoint.h>
#include <Mod/Surface/SurfaceGlobal.h>
namespace Surface
{
/*!
* Create a BezierCurve interpolating a list of BlendPoints
*/
* Create a BezierCurve interpolating a list of BlendPoints
*/
class SurfaceExport BlendCurve
{
public:
@@ -39,25 +39,24 @@ public:
BlendCurve() = default;
/*!
* Constructor
*\param std::vector<BlendPoint>
*/
* Constructor
*\param std::vector<BlendPoint>
*/
explicit BlendCurve(const std::vector<BlendPoint>& blendPointsList);
~BlendCurve() = default;
/*!
* Perform the interpolate algorithm
*\return the BezierCurve
*/
* Perform the interpolate algorithm
*\return the BezierCurve
*/
Handle(Geom_BezierCurve) compute();
/*!
* Set the size of the first derivative of a BlendPoint
*\param int index of the BlendPoint to modify
*\param double new size
*\param bool interpret new size relative to chordlength
*/
* Set the size of the first derivative of a BlendPoint
*\param int index of the BlendPoint to modify
*\param double new size
*\param bool interpret new size relative to chordlength
*/
void setSize(int, double, bool);
};
}// namespace Surface
#endif

View File

@@ -22,9 +22,11 @@
#include "PreCompiled.h"
// clang-format off
#include "Blending/BlendCurvePy.h"
#include "Blending/BlendCurvePy.cpp"
#include "Blending/BlendPointPy.h"
// clang-format on
#include <Base/VectorPy.h>
#include <Mod/Part/App/BezierCurvePy.h>
@@ -35,44 +37,51 @@ std::string BlendCurvePy::representation() const
return "BlendCurve";
}
PyObject *BlendCurvePy::PyMake(struct _typeobject *, PyObject *, PyObject *)// Python wrapper
PyObject* BlendCurvePy::PyMake(struct _typeobject*, PyObject*, PyObject*)// Python wrapper
{
// create a new instance of BlendCurvePy
return new BlendCurvePy(new BlendCurve);
}
int BlendCurvePy::PyInit(PyObject *args, PyObject * /*kwds*/)
int BlendCurvePy::PyInit(PyObject* args, PyObject* /*kwds*/)
{
PyObject *b1;
PyObject *b2;
PyObject* b1;
PyObject* b2;
if (!PyArg_ParseTuple(args, "O!O!", &(Surface::BlendPointPy::Type), &b1, &(Surface::BlendPointPy::Type), &b2))
if (!PyArg_ParseTuple(args,
"O!O!",
&(Surface::BlendPointPy::Type),
&b1,
&(Surface::BlendPointPy::Type),
&b2)) {
return -1;
}
std::vector<BlendPoint> bpList;
BlendPoint *geom1 = static_cast<BlendPointPy *>(b1)->getBlendPointPtr();
BlendPoint *geom2 = static_cast<BlendPointPy *>(b2)->getBlendPointPtr();
BlendPoint* geom1 = static_cast<BlendPointPy*>(b1)->getBlendPointPtr();
BlendPoint* geom2 = static_cast<BlendPointPy*>(b2)->getBlendPointPtr();
bpList.emplace_back(*geom1);
bpList.emplace_back(*geom2);
this->getBlendCurvePtr()->blendPoints = bpList;
return 0;
}
PyObject *BlendCurvePy::compute(PyObject * args)
PyObject* BlendCurvePy::compute(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
BlendCurve *bc = getBlendCurvePtr();
BlendCurve* bc = getBlendCurvePtr();
Handle(Geom_BezierCurve) gc = bc->compute();
return new Part::BezierCurvePy(new Part::GeomBezierCurve(gc));
}
PyObject *BlendCurvePy::setSize(PyObject *args)
PyObject* BlendCurvePy::setSize(PyObject* args)
{
int i;
double size;
PyObject *relative = Py_True;
PyObject* relative = Py_True;
if (!PyArg_ParseTuple(args, "idO!", &i, &size, &PyBool_Type, &relative)) {
return nullptr;
}
@@ -80,18 +89,18 @@ PyObject *BlendCurvePy::setSize(PyObject *args)
getBlendCurvePtr()->setSize(i, size, Base::asBoolean(relative));
Py_Return;
}
catch (Standard_Failure &e) {
catch (Standard_Failure& e) {
PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString());
return nullptr;
}
}
PyObject *BlendCurvePy::getCustomAttributes(const char * /*attr*/) const
PyObject* BlendCurvePy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int BlendCurvePy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/)
int BlendCurvePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -33,9 +33,8 @@
using namespace Surface;
BlendPoint::BlendPoint(const std::vector<Base::Vector3d>& vectorList)
: vectors{vectorList}
{
}
: vectors {vectorList}
{}
BlendPoint::BlendPoint()
{

View File

@@ -24,8 +24,8 @@
#define SURFACE_BLEND_POINT_H
#include <Mod/Surface/SurfaceGlobal.h>
#include <Base/Vector3D.h>
#include <Mod/Surface/SurfaceGlobal.h>
#include <vector>
@@ -33,9 +33,9 @@ namespace Surface
{
/*!
* Create a list of vectors formed by a point and some derivatives
* obtained from a curve or surface
*/
* Create a list of vectors formed by a point and some derivatives
* obtained from a curve or surface
*/
class SurfaceExport BlendPoint
{
public:
@@ -43,29 +43,29 @@ public:
BlendPoint();
/*!
* Constructor
*\param std::vector<Base::Vector3d>
*/
* Constructor
*\param std::vector<Base::Vector3d>
*/
explicit BlendPoint(const std::vector<Base::Vector3d>& vectorList);
~BlendPoint() = default;
/*!
* Scale the blendpoint vectors
*\param double scaling factor
*/
* Scale the blendpoint vectors
*\param double scaling factor
*/
void multiply(double f);
/*!
* Resize the blendpoint vectors
* by setting the size of the first derivative
*\param double new size
*/
* Resize the blendpoint vectors
* by setting the size of the first derivative
*\param double new size
*/
void setSize(double f);
/*!
*\return continuity of this BlendPoint
*/
*\return continuity of this BlendPoint
*/
int getContinuity();
/*!
*\return Number of vectors of this BlendPoint
*/
*\return Number of vectors of this BlendPoint
*/
int nbVectors();
private:
@@ -73,4 +73,3 @@ private:
}// namespace Surface
#endif

View File

@@ -25,9 +25,13 @@
#include <BRepAdaptor_Curve.hxx>
#include <TopoDS.hxx>
#endif
// clang-format off
#include "Blending/BlendPoint.h"
#include "Blending/BlendPointPy.h"
#include "Blending/BlendPointPy.cpp"
// clang-format on
#include <Base/GeometryPyCXX.h>
#include <Base/VectorPy.h>
#include <Mod/Part/App/TopoShapePy.h>
@@ -47,15 +51,15 @@ std::string BlendPointPy::representation() const
return str.str();
}
PyObject *BlendPointPy::PyMake(struct _typeobject *, PyObject *, PyObject *)// Python wrapper
PyObject* BlendPointPy::PyMake(struct _typeobject*, PyObject*, PyObject*)// Python wrapper
{
// create a new instance of BlendPointPy
return new BlendPointPy(new BlendPoint);
}
int BlendPointPy::PyInit(PyObject *args, PyObject *)
int BlendPointPy::PyInit(PyObject* args, PyObject*)
{
PyObject *plist;
PyObject* plist;
std::vector<Base::Vector3d> vecs;
if (PyArg_ParseTuple(args, "O", &plist)) {
Py::Sequence list(plist);
@@ -82,14 +86,15 @@ int BlendPointPy::PyInit(PyObject *args, PyObject *)
double param;
int cont;
PyObject *pcObj;
PyObject* pcObj;
PyErr_Clear();
// Create a curve with an edge, parameter and continiuity.
if (PyArg_ParseTuple(args, "O!di", &(Part::TopoShapePy::Type), &pcObj, &param, &cont)) {
try {
gp_Pnt Pt;
TopoDS_Shape shape = static_cast<Part::TopoShapePy *>(pcObj)->getTopoShapePtr()->getShape();
const TopoDS_Edge &e = TopoDS::Edge(shape);
TopoDS_Shape shape =
static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->getShape();
const TopoDS_Edge& e = TopoDS::Edge(shape);
BRepAdaptor_Curve adapt(e);
if (param < adapt.FirstParameter() || param > adapt.LastParameter()) {
PyErr_Warn(PyExc_UserWarning, "BlendPoint: edge is not a closed curve");
@@ -109,39 +114,42 @@ int BlendPointPy::PyInit(PyObject *args, PyObject *)
this->getBlendPointPtr()->vectors = vecs;
return 0;
}
catch (const std::exception &e) {
catch (const std::exception& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
return -1;
}
}
PyErr_SetString(PyExc_TypeError, "supported signatures:\n"
PyErr_SetString(PyExc_TypeError,
"supported signatures:\n"
"BlendPoint()\n"
"BlendPoint(list of Vector)\n"
"BlendPoint(edge, parameter and continiuity)\n");
return -1;
}
PyObject *BlendPointPy::setSize(PyObject *args)
PyObject* BlendPointPy::setSize(PyObject* args)
{
double size = 1.0;
if (!PyArg_ParseTuple(args, "d", &size))
if (!PyArg_ParseTuple(args, "d", &size)) {
return nullptr;
}
try {
getBlendPointPtr()->setSize(size);
Py_Return;
}
catch (Standard_Failure &) {
catch (Standard_Failure&) {
PyErr_SetString(Base::PyExc_FC_CADKernelError, "Failed to set size");
return nullptr;
}
}
PyObject *BlendPointPy::getSize(PyObject *args)
PyObject* BlendPointPy::getSize(PyObject* args)
{
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "")) {
return nullptr;
}
int nb = getBlendPointPtr()->nbVectors();
if (nb >= 2) {
double bpTangentLength = getBlendPointPtr()->vectors[1].Length();
@@ -154,18 +162,18 @@ PyObject *BlendPointPy::getSize(PyObject *args)
Py::List BlendPointPy::getVectors() const
{
BlendPoint *bp = getBlendPointPtr();
BlendPoint* bp = getBlendPointPtr();
Py::List vecs;
for (const auto& p : bp->vectors) {
Base::VectorPy *vec = new Base::VectorPy(p);
Base::VectorPy* vec = new Base::VectorPy(p);
vecs.append(Py::asObject(vec));
}
return vecs;
}
PyObject *BlendPointPy::setvectors(PyObject *args)
PyObject* BlendPointPy::setvectors(PyObject* args)
{
PyObject *plist;
PyObject* plist;
if (!PyArg_ParseTuple(args, "O", &plist)) {
PyErr_SetString(PyExc_TypeError, "List of vectors required.");
return nullptr;
@@ -179,17 +187,17 @@ PyObject *BlendPointPy::setvectors(PyObject *args)
vecs.emplace_back(pole);
}
BlendPoint *bp = getBlendPointPtr();
BlendPoint* bp = getBlendPointPtr();
bp->vectors = vecs;
Py_Return;
}
PyObject *BlendPointPy::getCustomAttributes(const char * /*attr*/) const
PyObject* BlendPointPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int BlendPointPy::setCustomAttributes(const char * /*attr*/, PyObject * /*obj*/)
int BlendPointPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -30,9 +30,9 @@
#include <gp_Pnt.hxx>
#endif
#include <Base/Tools.h>
#include "Mod/Surface/App/Blending/BlendCurve.h"
#include "Mod/Surface/App/Blending/BlendPoint.h"
#include <Base/Tools.h>
#include "FeatureBlendCurve.h"
@@ -47,20 +47,52 @@ PROPERTY_SOURCE(Surface::FeatureBlendCurve, Part::Spline)
FeatureBlendCurve::FeatureBlendCurve()
{
ADD_PROPERTY_TYPE(StartEdge, (nullptr), "FirstEdge", App::Prop_None, "Edge support of the start point");
ADD_PROPERTY_TYPE(StartContinuity, (2), "FirstEdge", App::Prop_None, "Geometric continuity at start point");
ADD_PROPERTY_TYPE(StartEdge,
(nullptr),
"FirstEdge",
App::Prop_None,
"Edge support of the start point");
ADD_PROPERTY_TYPE(StartContinuity,
(2),
"FirstEdge",
App::Prop_None,
"Geometric continuity at start point");
StartContinuity.setConstraints(&ContinuityConstraint);
ADD_PROPERTY_TYPE(StartParameter, (0.0f), "FirstEdge", App::Prop_None, "Parameter of start point along edge");
ADD_PROPERTY_TYPE(StartParameter,
(0.0f),
"FirstEdge",
App::Prop_None,
"Parameter of start point along edge");
StartParameter.setConstraints(&ParameterConstraint);
ADD_PROPERTY_TYPE(StartSize, (1.0f), "FirstEdge", App::Prop_None, "Size of derivatives at start point");
ADD_PROPERTY_TYPE(StartSize,
(1.0f),
"FirstEdge",
App::Prop_None,
"Size of derivatives at start point");
StartSize.setConstraints(&SizeConstraint);
ADD_PROPERTY_TYPE(EndEdge, (nullptr), "SecondEdge", App::Prop_None, "Edge support of the end point");
ADD_PROPERTY_TYPE(EndContinuity, (2), "SecondEdge", App::Prop_None, "Geometric continuity at end point");
ADD_PROPERTY_TYPE(EndEdge,
(nullptr),
"SecondEdge",
App::Prop_None,
"Edge support of the end point");
ADD_PROPERTY_TYPE(EndContinuity,
(2),
"SecondEdge",
App::Prop_None,
"Geometric continuity at end point");
EndContinuity.setConstraints(&ContinuityConstraint);
ADD_PROPERTY_TYPE(EndParameter, (0.0f), "SecondEdge", App::Prop_None, "Parameter of end point along edge");
ADD_PROPERTY_TYPE(EndParameter,
(0.0f),
"SecondEdge",
App::Prop_None,
"Parameter of end point along edge");
EndParameter.setConstraints(&ParameterConstraint);
ADD_PROPERTY_TYPE(EndSize, (1.0f), "SecondEdge", App::Prop_None, "Size of derivatives at end point");
ADD_PROPERTY_TYPE(EndSize,
(1.0f),
"SecondEdge",
App::Prop_None,
"Size of derivatives at end point");
EndSize.setConstraints(&SizeConstraint);
Handle(Geom_BezierCurve) maxDegreeCurve;
@@ -69,42 +101,56 @@ FeatureBlendCurve::FeatureBlendCurve()
short FeatureBlendCurve::mustExecute() const
{
if (StartEdge.isTouched())
if (StartEdge.isTouched()) {
return 1;
if (StartParameter.isTouched())
}
if (StartParameter.isTouched()) {
return 1;
if (StartContinuity.isTouched())
}
if (StartContinuity.isTouched()) {
return 1;
if (StartSize.isTouched())
}
if (StartSize.isTouched()) {
return 1;
if (EndEdge.isTouched())
}
if (EndEdge.isTouched()) {
return 1;
if (EndParameter.isTouched())
}
if (EndParameter.isTouched()) {
return 1;
if (EndContinuity.isTouched())
}
if (EndContinuity.isTouched()) {
return 1;
if (EndSize.isTouched())
}
if (EndSize.isTouched()) {
return 1;
}
return 0;
}
BlendPoint FeatureBlendCurve::GetBlendPoint(App::PropertyLinkSub &link, App::PropertyFloatConstraint &param, App::PropertyIntegerConstraint &continuity)
BlendPoint FeatureBlendCurve::GetBlendPoint(App::PropertyLinkSub& link,
App::PropertyFloatConstraint& param,
App::PropertyIntegerConstraint& continuity)
{
auto linked = link.getValue();
TopoDS_Shape axEdge;
if (link.getSubValues().size() > 0 && link.getSubValues()[0].length() > 0) {
axEdge = Feature::getTopoShape(linked, link.getSubValues()[0].c_str(), true /*need element*/).getShape();
axEdge =
Feature::getTopoShape(linked, link.getSubValues()[0].c_str(), true /*need element*/)
.getShape();
}
else {
axEdge = Feature::getShape(linked);
}
if (axEdge.IsNull())
if (axEdge.IsNull()) {
throw Base::ValueError("DirLink shape is null");
if (axEdge.ShapeType() != TopAbs_EDGE)
}
if (axEdge.ShapeType() != TopAbs_EDGE) {
throw Base::TypeError("DirLink shape is not an edge");
const TopoDS_Edge &e = TopoDS::Edge(axEdge);
}
const TopoDS_Edge& e = TopoDS::Edge(axEdge);
BRepAdaptor_Curve adapt(e);
double fp = adapt.FirstParameter();
double lp = adapt.LastParameter();
@@ -129,7 +175,7 @@ BlendPoint FeatureBlendCurve::GetBlendPoint(App::PropertyLinkSub &link, App::Pro
return bp;
}
App::DocumentObjectExecReturn *FeatureBlendCurve::execute()
App::DocumentObjectExecReturn* FeatureBlendCurve::execute()
{
BlendPoint bp1 = GetBlendPoint(StartEdge, StartParameter, StartContinuity);
BlendPoint bp2 = GetBlendPoint(EndEdge, EndParameter, EndContinuity);
@@ -157,7 +203,7 @@ double FeatureBlendCurve::RelativeToRealParameters(double relativeValue, double
}
void FeatureBlendCurve::onChanged(const App::Property *prop)
void FeatureBlendCurve::onChanged(const App::Property* prop)
{
if (prop == &StartContinuity) {
long maxValue = maxDegree - 2 - EndContinuity.getValue();
@@ -171,9 +217,10 @@ void FeatureBlendCurve::onChanged(const App::Property *prop)
EndContinuity.setValue(maxValue);
}
}
if (prop == &StartContinuity || prop == &StartParameter || prop == &StartSize || prop == &EndContinuity || prop == &EndParameter || prop == &EndSize) {
if (prop == &StartContinuity || prop == &StartParameter || prop == &StartSize
|| prop == &EndContinuity || prop == &EndParameter || prop == &EndSize) {
if (!isRestoring()) {
App::DocumentObjectExecReturn *ret = recompute();
App::DocumentObjectExecReturn* ret = recompute();
delete ret;
}
}

View File

@@ -27,8 +27,8 @@
#include <App/PropertyStandard.h>
#include <App/PropertyUnits.h>
#include <Mod/Part/App/FeaturePartSpline.h>
#include <Mod/Surface/SurfaceGlobal.h>
#include <Mod/Surface/App/Blending/BlendPoint.h>
#include <Mod/Surface/SurfaceGlobal.h>
namespace Surface
{
@@ -38,7 +38,6 @@ class SurfaceExport FeatureBlendCurve: public Part::Spline
PROPERTY_HEADER_WITH_OVERRIDE(Surface::FeatureBlendCurve);
public:
FeatureBlendCurve();
App::PropertyLinkSub StartEdge;
@@ -53,21 +52,23 @@ public:
Standard_Integer maxDegree;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
short mustExecute() const override;
const char *getViewProviderName() const override
const char* getViewProviderName() const override
{
return "SurfaceGui::ViewProviderBlendCurve";
}
private:
BlendPoint GetBlendPoint(App::PropertyLinkSub &link, App::PropertyFloatConstraint &param, App::PropertyIntegerConstraint &Continuity);
BlendPoint GetBlendPoint(App::PropertyLinkSub& link,
App::PropertyFloatConstraint& param,
App::PropertyIntegerConstraint& Continuity);
double RelativeToRealParameters(double, double, double);
protected:
void onChanged(const App::Property *prop) override;
void onChanged(const App::Property* prop) override;
};
}//Namespace Surface
}// Namespace Surface
#endif

View File

@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
#include <TopoDS.hxx>
#endif
#include "FeatureCut.h"
@@ -34,41 +34,43 @@ PROPERTY_SOURCE(Surface::Cut, Part::Feature)
Cut::Cut()
{
ADD_PROPERTY(ShapeList,(nullptr,"TopoDS_Shape"));
ADD_PROPERTY(ShapeList, (nullptr, "TopoDS_Shape"));
ShapeList.setScope(App::LinkScope::Global);
}
//Check if any components of the surface have been modified
// Check if any components of the surface have been modified
short Cut::mustExecute() const
{
if (ShapeList.isTouched())
if (ShapeList.isTouched()) {
return 1;
}
return 0;
}
App::DocumentObjectExecReturn *Cut::execute()
App::DocumentObjectExecReturn* Cut::execute()
{
//Perform error checking
// Perform error checking
try {
std::vector<App::DocumentObject*> shapes = ShapeList.getValues();
if (shapes.size() != 2){
return new App::DocumentObjectExecReturn("Two shapes must be entered at a time for a cut operation");
if (shapes.size() != 2) {
return new App::DocumentObjectExecReturn(
"Two shapes must be entered at a time for a cut operation");
}
Part::TopoShape ts1;
Part::TopoShape ts2;
//Get first toposhape
// Get first toposhape
if (shapes[0]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts1 = static_cast<Part::Feature*>(shapes[0])->Shape.getShape(); //Part::TopoShape 1
ts1 = static_cast<Part::Feature*>(shapes[0])->Shape.getShape();// Part::TopoShape 1
}
else {
return new App::DocumentObjectExecReturn("Shape1 not from Part::Feature");
}
//Get second toposhape
// Get second toposhape
if (shapes[1]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts2 = static_cast<Part::Feature*>(shapes[1])->Shape.getShape();
}
@@ -76,12 +78,12 @@ App::DocumentObjectExecReturn *Cut::execute()
return new App::DocumentObjectExecReturn("Shape2 not from Part::Feature");
}
//Cut Shape1 by Shape2
// Cut Shape1 by Shape2
TopoDS_Shape aCutShape;
aCutShape = ts1.cut(ts2.getShape());
//Check if resulting shell is null
if (aCutShape.IsNull()){
// Check if resulting shell is null
if (aCutShape.IsNull()) {
return new App::DocumentObjectExecReturn("Resulting shape is null");
}

View File

@@ -31,25 +31,24 @@
namespace Surface
{
class SurfaceExport Cut : public Part::Feature
class SurfaceExport Cut: public Part::Feature
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::Cut);
public:
Cut();
App::PropertyLinkSubList ShapeList; //Shapes to be cut.
App::PropertyLinkSubList ShapeList;// Shapes to be cut.
// recalculate the feature
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
short mustExecute() const override;
/// returns the type name of the view provider
// const char* getViewProviderName(void) const {
// return "SurfaceGui::ViewProviderCut";
// }
// const char* getViewProviderName(void) const {
// return "SurfaceGui::ViewProviderCut";
// }
};
}//Namespace Surface
}// Namespace Surface
#endif

View File

@@ -22,17 +22,17 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAdaptor_Surface.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <BRepLProp_SLProps.hxx>
# include <Geom_BSplineSurface.hxx>
# include <GeomAPI_PointsToBSplineSurface.hxx>
# include <gp_Pnt.hxx>
# include <Precision.hxx>
# include <Standard_Version.hxx>
# include <TColgp_Array2OfPnt.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepLProp_SLProps.hxx>
#include <GeomAPI_PointsToBSplineSurface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Precision.hxx>
#include <Standard_Version.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <gp_Pnt.hxx>
#endif
#include <Base/Tools.h>
@@ -49,7 +49,7 @@ PROPERTY_SOURCE(Surface::Extend, Part::Spline)
Extend::Extend()
{
ADD_PROPERTY(Face,(nullptr));
ADD_PROPERTY(Face, (nullptr));
Face.setScope(App::LinkScope::Global);
ADD_PROPERTY(Tolerance, (0.1));
Tolerance.setConstraints(&ToleranceRange);
@@ -74,32 +74,40 @@ Extend::Extend()
short Extend::mustExecute() const
{
if (Face.isTouched())
if (Face.isTouched()) {
return 1;
if (ExtendUNeg.isTouched())
}
if (ExtendUNeg.isTouched()) {
return 1;
if (ExtendUPos.isTouched())
return 1;
if (ExtendVNeg.isTouched())
}
if (ExtendUPos.isTouched()) {
return 1;
if (ExtendVPos.isTouched())
return 1;
}
if (ExtendVNeg.isTouched()) {
return 1;
}
if (ExtendVPos.isTouched()) {
return 1;
}
return 0;
}
App::DocumentObjectExecReturn *Extend::execute()
App::DocumentObjectExecReturn* Extend::execute()
{
App::DocumentObject* part = Face.getValue();
if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
return new App::DocumentObjectExecReturn("No shape linked.");
}
const auto& faces = Face.getSubValues();
if (faces.size() != 1)
if (faces.size() != 1) {
return new App::DocumentObjectExecReturn("Not exactly one sub-shape linked.");
}
TopoDS_Shape shape = static_cast<Part::Feature*>(part)
->Shape.getShape().getSubShape(faces[0].c_str());
if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE)
TopoDS_Shape shape =
static_cast<Part::Feature*>(part)->Shape.getShape().getSubShape(faces[0].c_str());
if (shape.IsNull() || shape.ShapeType() != TopAbs_FACE) {
return new App::DocumentObjectExecReturn("Sub-shape is not a face.");
}
const TopoDS_Face& face = TopoDS::Face(shape);
BRepAdaptor_Surface adapt(face);
@@ -110,23 +118,23 @@ App::DocumentObjectExecReturn *Extend::execute()
double ur = u2 - u1;
double vr = v2 - v1;
double eu1 = u1 - ur*ExtendUNeg.getValue();
double eu2 = u2 + ur*ExtendUPos.getValue();
double ev1 = v1 - vr*ExtendVNeg.getValue();
double ev2 = v2 + vr*ExtendVPos.getValue();
double eu1 = u1 - ur * ExtendUNeg.getValue();
double eu2 = u2 + ur * ExtendUPos.getValue();
double ev1 = v1 - vr * ExtendVNeg.getValue();
double ev2 = v2 + vr * ExtendVPos.getValue();
double eur = eu2 - eu1;
double evr = ev2 - ev1;
long numU = SampleU.getValue();
long numV = SampleV.getValue();
TColgp_Array2OfPnt approxPoints(1, numU, 1, numV);
for (long u=0; u<numU; u++) {
double uu = eu1 + u * eur / (numU-1);
for (long v=0; v<numV; v++) {
double vv = ev1 + v * evr / (numV-1);
BRepLProp_SLProps prop(adapt,uu,vv,0,Precision::Confusion());
for (long u = 0; u < numU; u++) {
double uu = eu1 + u * eur / (numU - 1);
for (long v = 0; v < numV; v++) {
double vv = ev1 + v * evr / (numV - 1);
BRepLProp_SLProps prop(adapt, uu, vv, 0, Precision::Confusion());
const gp_Pnt& pnt = prop.Value();
approxPoints(u+1, v+1) = pnt;
approxPoints(u + 1, v + 1) = pnt;
}
}
@@ -150,30 +158,25 @@ App::DocumentObjectExecReturn *Extend::execute()
void Extend::onChanged(const App::Property* prop)
{
// using a mutex and lock to protect a recursive calling when setting the new values
if (lockOnChangeMutex)
if (lockOnChangeMutex) {
return;
}
Base::StateLocker lock(lockOnChangeMutex);
if (ExtendUSymetric.getValue())
{
if (prop == &ExtendUNeg || prop == &ExtendUPos)
{
if (ExtendUSymetric.getValue()) {
if (prop == &ExtendUNeg || prop == &ExtendUPos) {
auto changedValue = dynamic_cast<const App::PropertyFloat*>(prop);
if (changedValue)
{
if (changedValue) {
ExtendUNeg.setValue(changedValue->getValue());
ExtendUPos.setValue(changedValue->getValue());
}
}
}
if (ExtendVSymetric.getValue())
{
if (prop == &ExtendVNeg || prop == &ExtendVPos)
{
if (ExtendVSymetric.getValue()) {
if (prop == &ExtendVNeg || prop == &ExtendVPos) {
auto changedValue = dynamic_cast<const App::PropertyFloat*>(prop);
if (changedValue)
{
if (changedValue) {
ExtendVNeg.setValue(changedValue->getValue());
ExtendVPos.setValue(changedValue->getValue());
}
@@ -182,18 +185,20 @@ void Extend::onChanged(const App::Property* prop)
Part::Spline::onChanged(prop);
}
void Extend::handleChangedPropertyName(Base::XMLReader &reader,
const char * TypeName,
const char *PropName)
void Extend::handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName)
{
Base::Type type = Base::Type::fromName(TypeName);
if (App::PropertyFloatConstraint::getClassTypeId() == type && strcmp(PropName, "ExtendU") == 0) {
if (App::PropertyFloatConstraint::getClassTypeId() == type
&& strcmp(PropName, "ExtendU") == 0) {
App::PropertyFloatConstraint v;
v.Restore(reader);
ExtendUNeg.setValue(v.getValue());
ExtendUPos.setValue(v.getValue());
}
else if (App::PropertyFloatConstraint::getClassTypeId() == type && strcmp(PropName, "ExtendV") == 0) {
else if (App::PropertyFloatConstraint::getClassTypeId() == type
&& strcmp(PropName, "ExtendV") == 0) {
App::PropertyFloatConstraint v;
v.Restore(reader);
ExtendVNeg.setValue(v.getValue());

View File

@@ -31,7 +31,7 @@
namespace Surface
{
class SurfaceExport Extend : public Part::Spline
class SurfaceExport Extend: public Part::Spline
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::Extend);
@@ -42,31 +42,32 @@ public:
App::PropertyFloatConstraint Tolerance;
App::PropertyFloatConstraint ExtendUNeg;
App::PropertyFloatConstraint ExtendUPos;
App::PropertyBool ExtendUSymetric;
App::PropertyBool ExtendUSymetric;
App::PropertyFloatConstraint ExtendVNeg;
App::PropertyFloatConstraint ExtendVPos;
App::PropertyBool ExtendVSymetric;
App::PropertyBool ExtendVSymetric;
App::PropertyIntegerConstraint SampleU;
App::PropertyIntegerConstraint SampleV;
// recalculate the feature
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
short mustExecute() const override;
/// returns the type name of the view provider
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "SurfaceGui::ViewProviderExtend";
}
protected:
void onChanged(const App::Property* prop) override;
void handleChangedPropertyName(Base::XMLReader &reader,
const char * TypeName,
const char *PropName) override;
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;
private:
bool lockOnChangeMutex{false};
bool lockOnChangeMutex {false};
};
}//Namespace Surface
}// Namespace Surface
#endif

View File

@@ -22,14 +22,14 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <string>
#include <string>
# include <BRepBuilderAPI_MakeWire.hxx>
# include <BRepFill_Filling.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepFill_Filling.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <gp_Pnt.hxx>
#endif
#include "FeatureFilling.h"
@@ -39,17 +39,23 @@ using namespace Surface;
PROPERTY_SOURCE(Surface::Filling, Part::Spline)
//Initial values
// Initial values
Filling::Filling()
{
ADD_PROPERTY_TYPE(BoundaryEdges,(nullptr,""), "Filling", App::Prop_None, "Boundary Edges (C0 is required for edges without a corresponding face)");
// clang-format off
ADD_PROPERTY_TYPE(BoundaryEdges,(nullptr,""), "Filling", App::Prop_None,
"Boundary Edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(BoundaryFaces,(""), "Filling", App::Prop_None, "Boundary Faces");
ADD_PROPERTY_TYPE(BoundaryOrder,(-1), "Filling", App::Prop_None, "Order of constraint on boundary faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(BoundaryOrder,(-1), "Filling", App::Prop_None,
"Order of constraint on boundary faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(UnboundEdges,(nullptr,""), "Filling", App::Prop_None, "Unbound constraint edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(UnboundFaces,(""), "Filling", App::Prop_None, "Unbound constraint faces");
ADD_PROPERTY_TYPE(UnboundOrder,(-1), "Filling", App::Prop_None, "Order of constraint on curve faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(UnboundEdges,(nullptr,""), "Filling", App::Prop_None,
"Unbound constraint edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(UnboundFaces,(""), "Filling", App::Prop_None,
"Unbound constraint faces");
ADD_PROPERTY_TYPE(UnboundOrder,(-1), "Filling", App::Prop_None,
"Order of constraint on curve faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(FreeFaces,(nullptr,""), "Filling", App::Prop_None, "Free constraint on a face");
ADD_PROPERTY_TYPE(FreeOrder,(0), "Filling", App::Prop_None, "Order of constraint on free faces");
@@ -58,7 +64,8 @@ Filling::Filling()
ADD_PROPERTY_TYPE(InitialFace,(nullptr), "Filling", App::Prop_None, "Initial surface to use");
ADD_PROPERTY_TYPE(Degree,(3), "Filling", App::Prop_None, "Starting degree");
ADD_PROPERTY_TYPE(PointsOnCurve,(15), "Filling", App::Prop_None, "Number of points on an edge for constraint");
ADD_PROPERTY_TYPE(PointsOnCurve,(15), "Filling", App::Prop_None,
"Number of points on an edge for constraint");
ADD_PROPERTY_TYPE(Iterations,(2), "Filling", App::Prop_None, "Number of iterations");
ADD_PROPERTY_TYPE(Anisotropy,(false), "Filling", App::Prop_None, "Anisotropy");
ADD_PROPERTY_TYPE(Tolerance2d,(0.00001), "Filling", App::Prop_None, "2D Tolerance");
@@ -67,6 +74,7 @@ Filling::Filling()
ADD_PROPERTY_TYPE(TolCurvature,(0.1), "Filling", App::Prop_None, "G2 tolerance");
ADD_PROPERTY_TYPE(MaximumDegree,(8), "Filling", App::Prop_None, "Maximum curve degree");
ADD_PROPERTY_TYPE(MaximumSegments,(9), "Filling", App::Prop_None, "Maximum number of segments");
// clang-format on
BoundaryEdges.setScope(App::LinkScope::Global);
UnboundEdges.setScope(App::LinkScope::Global);
@@ -87,27 +95,15 @@ Filling::Filling()
short Filling::mustExecute() const
{
if (BoundaryEdges.isTouched() ||
BoundaryFaces.isTouched() ||
BoundaryOrder.isTouched() ||
UnboundEdges.isTouched() ||
UnboundFaces.isTouched() ||
UnboundOrder.isTouched() ||
FreeFaces.isTouched() ||
FreeOrder.isTouched() ||
Points.isTouched() ||
InitialFace.isTouched() ||
Degree.isTouched() ||
PointsOnCurve.isTouched() ||
Iterations.isTouched() ||
Anisotropy.isTouched() ||
Tolerance2d.isTouched() ||
Tolerance3d.isTouched() ||
TolAngular.isTouched() ||
TolCurvature.isTouched() ||
MaximumDegree.isTouched() ||
MaximumSegments.isTouched())
if (BoundaryEdges.isTouched() || BoundaryFaces.isTouched() || BoundaryOrder.isTouched()
|| UnboundEdges.isTouched() || UnboundFaces.isTouched() || UnboundOrder.isTouched()
|| FreeFaces.isTouched() || FreeOrder.isTouched() || Points.isTouched()
|| InitialFace.isTouched() || Degree.isTouched() || PointsOnCurve.isTouched()
|| Iterations.isTouched() || Anisotropy.isTouched() || Tolerance2d.isTouched()
|| Tolerance3d.isTouched() || TolAngular.isTouched() || TolCurvature.isTouched()
|| MaximumDegree.isTouched() || MaximumSegments.isTouched()) {
return 1;
}
return 0;
}
@@ -137,7 +133,8 @@ void Filling::addConstraints(BRepFill_Filling& builder,
if (edge_obj.size() == edge_sub.size()) {
// BRepFill_Filling crashes if the boundary edges are not added in a consecutive order.
// these edges are first added to a test wire to check that they can be securely added to the Filling algo
// these edges are first added to a test wire to check that they can be securely added to
// the Filling algo
BRepBuilderAPI_MakeWire testWire;
for (std::size_t index = 0; index < edge_obj.size(); index++) {
// get the part object
@@ -167,7 +164,8 @@ void Filling::addConstraints(BRepFill_Filling& builder,
builder.Add(TopoDS::Edge(edge), cont, bnd);
}
else {
Standard_Failure::Raise("Boundary edges must be added in a consecutive order");
Standard_Failure::Raise(
"Boundary edges must be added in a consecutive order");
}
}
}
@@ -185,7 +183,8 @@ void Filling::addConstraints(BRepFill_Filling& builder,
builder.Add(TopoDS::Edge(edge), TopoDS::Face(face), cont, bnd);
}
else {
Standard_Failure::Raise("Boundary edges must be added in a consecutive order");
Standard_Failure::Raise(
"Boundary edges must be added in a consecutive order");
}
}
}
@@ -214,8 +213,7 @@ void Filling::addConstraints(BRepFill_Filling& builder,
auto face_sub = faces.getSubValues();
auto contvals = orders.getValues();
if (face_obj.size() == face_sub.size() &&
face_obj.size() == contvals.size()) {
if (face_obj.size() == face_sub.size() && face_obj.size() == contvals.size()) {
for (std::size_t index = 0; index < face_obj.size(); index++) {
App::DocumentObject* obj = face_obj[index];
const std::string& sub = face_sub[index];
@@ -237,8 +235,7 @@ void Filling::addConstraints(BRepFill_Filling& builder,
}
}
void Filling::addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& pointsList)
void Filling::addConstraints(BRepFill_Filling& builder, const App::PropertyLinkSubList& pointsList)
{
auto points = pointsList.getSubListValues();
for (const auto& it : points) {
@@ -257,12 +254,12 @@ void Filling::addConstraints(BRepFill_Filling& builder,
}
}
App::DocumentObjectExecReturn *Filling::execute()
App::DocumentObjectExecReturn* Filling::execute()
{
//Assign Variables
unsigned int degree = Degree.getValue();
// Assign Variables
unsigned int degree = Degree.getValue();
unsigned int ptsoncurve = PointsOnCurve.getValue();
unsigned int numIter = Iterations.getValue();
unsigned int numIter = Iterations.getValue();
bool anisotropy = Anisotropy.getValue();
double tol2d = Tolerance2d.getValue();
double tol3d = Tolerance3d.getValue();
@@ -272,11 +269,20 @@ App::DocumentObjectExecReturn *Filling::execute()
unsigned int maxseg = MaximumSegments.getValue();
try {
BRepFill_Filling builder(degree, ptsoncurve, numIter, anisotropy, tol2d,
tol3d, tolG1, tolG2, maxdeg, maxseg);
BRepFill_Filling builder(degree,
ptsoncurve,
numIter,
anisotropy,
tol2d,
tol3d,
tolG1,
tolG2,
maxdeg,
maxseg);
if ((BoundaryEdges.getSize()) < 1) {
return new App::DocumentObjectExecReturn("Border must have at least one curve defined.");
return new App::DocumentObjectExecReturn(
"Border must have at least one curve defined.");
}
// Load the initial surface if set
@@ -312,14 +318,15 @@ App::DocumentObjectExecReturn *Filling::execute()
addConstraints(builder, Points);
}
//Build the face
if (numBoundaries > 1)
// Build the face
if (numBoundaries > 1) {
builder.Build();
}
if (!builder.IsDone()) {
Standard_Failure::Raise("Failed to create a face from constraints");
}
//Return the face
// Return the face
TopoDS_Face aFace = builder.Face();
this->Shape.setValue(aFace);
return App::DocumentObject::StdReturn;

View File

@@ -33,42 +33,45 @@ class BRepFill_Filling;
namespace Surface
{
class SurfaceExport Filling : public Part::Spline
class SurfaceExport Filling: public Part::Spline
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::Filling);
public:
Filling();
//Properties of Curves
App::PropertyLinkSubList BoundaryEdges; // Boundary Edges (C0 is required for edges without a corresponding face)
App::PropertyStringList BoundaryFaces; // Boundary Faces (C0, G1 and G2 are possible)
App::PropertyIntegerList BoundaryOrder; // Order of constraint on border faces
App::PropertyLinkSubList UnboundEdges; // Unbound constraint edges (C0 is required for edges without a corresponding face)
App::PropertyStringList UnboundFaces; // Unbound constraint faces (C0, G1 and G2 are possible)
App::PropertyIntegerList UnboundOrder; // Order of constraint on curve faces
App::PropertyLinkSubList FreeFaces; // Free constraint faces
App::PropertyIntegerList FreeOrder; // Order of constraint on free faces
App::PropertyLinkSubList Points; // Constraint Points (on Surface)
App::PropertyLinkSub InitialFace; // Initial Face to use
// Properties of Curves
App::PropertyLinkSubList
BoundaryEdges;// Boundary Edges (C0 is required for edges without a corresponding face)
App::PropertyStringList BoundaryFaces; // Boundary Faces (C0, G1 and G2 are possible)
App::PropertyIntegerList BoundaryOrder;// Order of constraint on border faces
App::PropertyLinkSubList UnboundEdges; // Unbound constraint edges (C0 is required for edges
// without a corresponding face)
App::PropertyStringList UnboundFaces; // Unbound constraint faces (C0, G1 and G2 are possible)
App::PropertyIntegerList UnboundOrder; // Order of constraint on curve faces
App::PropertyLinkSubList FreeFaces; // Free constraint faces
App::PropertyIntegerList FreeOrder; // Order of constraint on free faces
App::PropertyLinkSubList Points; // Constraint Points (on Surface)
App::PropertyLinkSub InitialFace; // Initial Face to use
//Algorithm Variables
App::PropertyInteger Degree; //Starting degree
App::PropertyInteger PointsOnCurve; //Number of points on an edge for constraint
App::PropertyInteger Iterations; //Number of iterations
App::PropertyBool Anisotropy; //Anisotropy
App::PropertyFloat Tolerance2d; //2D Tolerance
App::PropertyFloat Tolerance3d; //3D Tolerance
App::PropertyFloat TolAngular; //G1 tolerance
App::PropertyFloat TolCurvature; //G2 tolerance
App::PropertyInteger MaximumDegree; //Maximum curve degree
App::PropertyInteger MaximumSegments; //Maximum number of segments
// Algorithm Variables
App::PropertyInteger Degree; // Starting degree
App::PropertyInteger PointsOnCurve; // Number of points on an edge for constraint
App::PropertyInteger Iterations; // Number of iterations
App::PropertyBool Anisotropy; // Anisotropy
App::PropertyFloat Tolerance2d; // 2D Tolerance
App::PropertyFloat Tolerance3d; // 3D Tolerance
App::PropertyFloat TolAngular; // G1 tolerance
App::PropertyFloat TolCurvature; // G2 tolerance
App::PropertyInteger MaximumDegree; // Maximum curve degree
App::PropertyInteger MaximumSegments;// Maximum number of segments
// recalculate the feature
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
short mustExecute() const override;
/// returns the type name of the view provider
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "SurfaceGui::ViewProviderFilling";
}
@@ -81,10 +84,9 @@ private:
void addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& faces,
const App::PropertyIntegerList& orders);
void addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& points);
void addConstraints(BRepFill_Filling& builder, const App::PropertyLinkSubList& points);
};
} //Namespace Surface
}// Namespace Surface
#endif

View File

@@ -24,22 +24,21 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <BRep_Tool.hxx>
#include <GeomConvert.hxx>
#include <GeomFill.hxx>
#include <GeomFill_BezierCurves.hxx>
#include <GeomFill_BSplineCurves.hxx>
#include <gp_Trsf.hxx>
#include <GeomFill_BezierCurves.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <ShapeConstruct_Curve.hxx>
#include <ShapeFix_Wire.hxx>
#include <ShapeExtend_WireData.hxx>
#include <ShapeFix_Wire.hxx>
#include <Standard_ConstructionError.hxx>
#include <StdFail_NotDone.hxx>
#include <TopExp_Explorer.hxx>
@@ -47,6 +46,7 @@
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Trsf.hxx>
#endif
#include "FeatureGeomFillSurface.h"
@@ -56,7 +56,7 @@ using namespace Surface;
ShapeValidator::ShapeValidator()
{
initValidator();
initValidator();
}
void ShapeValidator::initValidator()
@@ -72,12 +72,13 @@ void ShapeValidator::checkEdge(const TopoDS_Shape& shape)
Standard_Failure::Raise("Shape is not an edge.\n");
}
TopoDS_Edge etmp = TopoDS::Edge(shape); //Curve TopoDS_Edge
TopLoc_Location heloc; // this will be output
Standard_Real u0;// contains output
Standard_Real u1;// contains output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(etmp,heloc,u0,u1); //The geometric curve
Handle(Geom_BezierCurve) bez_geom = Handle(Geom_BezierCurve)::DownCast(c_geom); //Try to get Bezier curve
TopoDS_Edge etmp = TopoDS::Edge(shape); // Curve TopoDS_Edge
TopLoc_Location heloc; // this will be output
Standard_Real u0; // contains output
Standard_Real u1; // contains output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(etmp, heloc, u0, u1);// The geometric curve
Handle(Geom_BezierCurve) bez_geom =
Handle(Geom_BezierCurve)::DownCast(c_geom);// Try to get Bezier curve
// if not a Bezier then try to create a B-spline surface from the edges
if (bez_geom.IsNull()) {
@@ -87,7 +88,7 @@ void ShapeValidator::checkEdge(const TopoDS_Shape& shape)
edgeCount++;
}
void ShapeValidator::checkAndAdd(const TopoDS_Shape &shape, Handle(ShapeExtend_WireData) *aWD)
void ShapeValidator::checkAndAdd(const TopoDS_Shape& shape, Handle(ShapeExtend_WireData) * aWD)
{
checkEdge(shape);
if (aWD) {
@@ -97,11 +98,13 @@ void ShapeValidator::checkAndAdd(const TopoDS_Shape &shape, Handle(ShapeExtend_W
}
}
void ShapeValidator::checkAndAdd(const Part::TopoShape &ts, const char *subName, Handle(ShapeExtend_WireData) *aWD)
void ShapeValidator::checkAndAdd(const Part::TopoShape& ts,
const char* subName,
Handle(ShapeExtend_WireData) * aWD)
{
try {
if (subName && *subName != '\0') {
//we want only the subshape which is linked
// we want only the subshape which is linked
checkAndAdd(ts.getSubShape(subName), aWD);
}
else if (!ts.getShape().IsNull() && ts.getShape().ShapeType() == TopAbs_WIRE) {
@@ -114,7 +117,7 @@ void ShapeValidator::checkAndAdd(const Part::TopoShape &ts, const char *subName,
checkAndAdd(ts.getShape(), aWD);
}
}
catch (Standard_Failure&) { // any OCC exception means an inappropriate shape in the selection
catch (Standard_Failure&) {// any OCC exception means an inappropriate shape in the selection
Standard_Failure::Raise("Wrong shape type.\n");
}
}
@@ -122,9 +125,10 @@ void ShapeValidator::checkAndAdd(const Part::TopoShape &ts, const char *subName,
PROPERTY_SOURCE(Surface::GeomFillSurface, Part::Spline)
const char* GeomFillSurface::FillTypeEnums[] = {"Stretched", "Coons", "Curved", nullptr};
const char* GeomFillSurface::FillTypeEnums[] = {"Stretched", "Coons", "Curved", nullptr};
GeomFillSurface::GeomFillSurface(): Spline()
GeomFillSurface::GeomFillSurface()
: Spline()
{
ADD_PROPERTY(FillType, ((long)0));
ADD_PROPERTY(BoundaryList, (nullptr, "Dummy"));
@@ -134,12 +138,10 @@ GeomFillSurface::GeomFillSurface(): Spline()
}
//Check if any components of the surface have been modified
// Check if any components of the surface have been modified
short GeomFillSurface::mustExecute() const
{
if (BoundaryList.isTouched() ||
ReversedList.isTouched() ||
FillType.isTouched()) {
if (BoundaryList.isTouched() || ReversedList.isTouched() || FillType.isTouched()) {
return 1;
}
return Spline::mustExecute();
@@ -158,12 +160,12 @@ void GeomFillSurface::onChanged(const App::Property* prop)
Part::Spline::onChanged(prop);
}
App::DocumentObjectExecReturn *GeomFillSurface::execute()
App::DocumentObjectExecReturn* GeomFillSurface::execute()
{
try {
TopoDS_Wire aWire;
//Gets the healed wire
// Gets the healed wire
if (getWire(aWire)) {
createBezierSurface(aWire);
}
@@ -178,7 +180,8 @@ App::DocumentObjectExecReturn *GeomFillSurface::execute()
return new App::DocumentObjectExecReturn("Curves are disjoint.");
}
catch (StdFail_NotDone&) {
return new App::DocumentObjectExecReturn("A curve was not a B-spline and could not be converted into one.");
return new App::DocumentObjectExecReturn(
"A curve was not a B-spline and could not be converted into one.");
}
catch (Standard_Failure& e) {
return new App::DocumentObjectExecReturn(e.GetMessageString());
@@ -187,15 +190,16 @@ App::DocumentObjectExecReturn *GeomFillSurface::execute()
GeomFill_FillingStyle GeomFillSurface::getFillingStyle()
{
//Identify filling style
// Identify filling style
switch (FillType.getValue()) {
case GeomFill_StretchStyle:
case GeomFill_CoonsStyle:
case GeomFill_CurvedStyle:
return static_cast<GeomFill_FillingStyle>(FillType.getValue());
default:
Standard_Failure::Raise("Filling style must be 0 (Stretch), 1 (Coons), or 2 (Curved).\n");
return GeomFill_StretchStyle; // this is to shut up the compiler
case GeomFill_StretchStyle:
case GeomFill_CoonsStyle:
case GeomFill_CurvedStyle:
return static_cast<GeomFill_FillingStyle>(FillType.getValue());
default:
Standard_Failure::Raise(
"Filling style must be 0 (Stretch), 1 (Coons), or 2 (Curved).\n");
return GeomFill_StretchStyle;// this is to shut up the compiler
}
}
@@ -210,10 +214,11 @@ bool GeomFillSurface::getWire(TopoDS_Wire& aWire)
}
ShapeValidator validator;
for(const auto& set : boundary) {
for (const auto& set : boundary) {
if (set.first->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
for (const auto& jt : set.second) {
const Part::TopoShape &ts = static_cast<Part::Feature*>(set.first)->Shape.getShape();
const Part::TopoShape& ts =
static_cast<Part::Feature*>(set.first)->Shape.getShape();
validator.checkAndAdd(ts, jt.c_str(), &aWD);
}
}
@@ -226,16 +231,16 @@ bool GeomFillSurface::getWire(TopoDS_Wire& aWire)
Standard_Failure::Raise("Only 2-4 curves are allowed\n");
}
//Reorder the curves and fix the wire if required
// Reorder the curves and fix the wire if required
aShFW->Load(aWD); //Load in the wire
aShFW->FixReorder(); //Fix the order of the edges if required
aShFW->ClosedWireMode() = Standard_True; //Enables closed wire mode
aShFW->FixConnected(); //Fix connection between wires
aShFW->FixSelfIntersection(); //Fix Self Intersection
aShFW->Perform(); //Perform the fixes
aShFW->Load(aWD); // Load in the wire
aShFW->FixReorder(); // Fix the order of the edges if required
aShFW->ClosedWireMode() = Standard_True;// Enables closed wire mode
aShFW->FixConnected(); // Fix connection between wires
aShFW->FixSelfIntersection(); // Fix Self Intersection
aShFW->Perform(); // Perform the fixes
aWire = aShFW->Wire(); //Healed Wire
aWire = aShFW->Wire();// Healed Wire
if (aWire.IsNull()) {
Standard_Failure::Raise("Wire unable to be constructed\n");
@@ -244,7 +249,7 @@ bool GeomFillSurface::getWire(TopoDS_Wire& aWire)
return validator.isBezier();
}
void GeomFillSurface::createFace(const Handle(Geom_BoundedSurface) &aSurface)
void GeomFillSurface::createFace(const Handle(Geom_BoundedSurface) & aSurface)
{
BRepBuilderAPI_MakeFace aFaceBuilder;
Standard_Real u1, u2, v1, v2;
@@ -268,18 +273,19 @@ void GeomFillSurface::createBezierSurface(TopoDS_Wire& aWire)
std::vector<Handle(Geom_BezierCurve)> curves;
curves.reserve(4);
Standard_Real u1, u2; // contains output
TopExp_Explorer anExp (aWire, TopAbs_EDGE);
Standard_Real u1, u2;// contains output
TopExp_Explorer anExp(aWire, TopAbs_EDGE);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Edge hedge = TopoDS::Edge (anExp.Current());
TopLoc_Location heloc; // this will be output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(hedge, heloc, u1, u2); //The geometric curve
Handle(Geom_BezierCurve) bezier = Handle(Geom_BezierCurve)::DownCast(c_geom); //Try to get Bezier curve
const TopoDS_Edge hedge = TopoDS::Edge(anExp.Current());
TopLoc_Location heloc; // this will be output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(hedge, heloc, u1, u2);// The geometric curve
Handle(Geom_BezierCurve) bezier =
Handle(Geom_BezierCurve)::DownCast(c_geom);// Try to get Bezier curve
if (!bezier.IsNull()) {
gp_Trsf transf = heloc.Transformation();
bezier->Transform(transf); // apply original transformation to control points
//Store Underlying Geometry
bezier->Transform(transf);// apply original transformation to control points
// Store Underlying Geometry
curves.push_back(bezier);
}
else {
@@ -288,14 +294,15 @@ void GeomFillSurface::createBezierSurface(TopoDS_Wire& aWire)
}
GeomFill_FillingStyle fstyle = getFillingStyle();
GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder
GeomFill_BezierCurves aSurfBuilder;// Create Surface Builder
std::size_t edgeCount = curves.size();
const boost::dynamic_bitset<>& booleans = ReversedList.getValues();
if (edgeCount == booleans.size()) {
for (std::size_t i=0; i<edgeCount; i++) {
if (booleans[i])
for (std::size_t i = 0; i < edgeCount; i++) {
if (booleans[i]) {
curves[i]->Reverse();
}
}
}
@@ -316,17 +323,18 @@ void GeomFillSurface::createBSplineSurface(TopoDS_Wire& aWire)
{
std::vector<Handle(Geom_BSplineCurve)> curves;
curves.reserve(4);
Standard_Real u1, u2; // contains output
TopExp_Explorer anExp (aWire, TopAbs_EDGE);
Standard_Real u1, u2;// contains output
TopExp_Explorer anExp(aWire, TopAbs_EDGE);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Edge& edge = TopoDS::Edge (anExp.Current());
TopLoc_Location heloc; // this will be output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(edge, heloc, u1, u2); //The geometric curve
Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c_geom); //Try to get BSpline curve
const TopoDS_Edge& edge = TopoDS::Edge(anExp.Current());
TopLoc_Location heloc; // this will be output
Handle(Geom_Curve) c_geom = BRep_Tool::Curve(edge, heloc, u1, u2);// The geometric curve
Handle(Geom_BSplineCurve) bspline =
Handle(Geom_BSplineCurve)::DownCast(c_geom);// Try to get BSpline curve
gp_Trsf transf = heloc.Transformation();
if (!bspline.IsNull()) {
bspline->Transform(transf); // apply original transformation to control points
//Store Underlying Geometry
bspline->Transform(transf);// apply original transformation to control points
// Store Underlying Geometry
curves.push_back(bspline);
}
else {
@@ -338,30 +346,34 @@ void GeomFillSurface::createBSplineSurface(TopoDS_Wire& aWire)
Convert_ParameterisationType paratype = Convert_Polynomial;
Handle(Geom_BSplineCurve) bspline2 = conv.CurveToBSplineCurve(trim, paratype);
if (!bspline2.IsNull()) {
bspline2->Transform(transf); // apply original transformation to control points
bspline2->Transform(transf);// apply original transformation to control points
curves.push_back(bspline2);
}
else {
// GeomConvert failed, try ShapeConstruct_Curve now
ShapeConstruct_Curve scc;
Handle(Geom_BSplineCurve) spline = scc.ConvertToBSpline(c_geom, u1, u2, Precision::Confusion());
if (spline.IsNull())
Standard_Failure::Raise("A curve was not a B-spline and could not be converted into one.");
spline->Transform(transf); // apply original transformation to control points
Handle(Geom_BSplineCurve) spline =
scc.ConvertToBSpline(c_geom, u1, u2, Precision::Confusion());
if (spline.IsNull()) {
Standard_Failure::Raise(
"A curve was not a B-spline and could not be converted into one.");
}
spline->Transform(transf);// apply original transformation to control points
curves.push_back(spline);
}
}
}
GeomFill_FillingStyle fstyle = getFillingStyle();
GeomFill_BSplineCurves aSurfBuilder; //Create Surface Builder
GeomFill_BSplineCurves aSurfBuilder;// Create Surface Builder
std::size_t edgeCount = curves.size();
const boost::dynamic_bitset<>& booleans = ReversedList.getValues();
if (edgeCount == booleans.size()) {
for (std::size_t i=0; i<edgeCount; i++) {
if (booleans[i])
for (std::size_t i = 0; i < edgeCount; i++) {
if (booleans[i]) {
curves[i]->Reverse();
}
}
}
if (edgeCount == 2) {

View File

@@ -28,8 +28,8 @@
#include <Mod/Part/App/FeaturePartSpline.h>
#include <Mod/Surface/SurfaceGlobal.h>
#include <Geom_BoundedSurface.hxx>
#include <GeomFill_FillingStyle.hxx>
#include <Geom_BoundedSurface.hxx>
#include <ShapeExtend_WireData.hxx>
@@ -46,33 +46,38 @@ public:
ShapeValidator();
void initValidator();
void checkEdge(const TopoDS_Shape& shape);
void checkAndAdd(const TopoDS_Shape &shape, Handle(ShapeExtend_WireData) *aWD = nullptr);
void checkAndAdd(const Part::TopoShape &ts, const char *subName, Handle(ShapeExtend_WireData) *aWire = nullptr);
void checkAndAdd(const TopoDS_Shape& shape, Handle(ShapeExtend_WireData) * aWD = nullptr);
void checkAndAdd(const Part::TopoShape& ts,
const char* subName,
Handle(ShapeExtend_WireData) * aWire = nullptr);
bool isBezier() const {
bool isBezier() const
{
return willBezier;
}
int numEdges() const {
int numEdges() const
{
return edgeCount;
}
};
class GeomFillSurface : public Part::Spline
class GeomFillSurface: public Part::Spline
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::GeomFillSurface);
PROPERTY_HEADER_WITH_OVERRIDE(Surface::GeomFillSurface);
public:
GeomFillSurface();
App::PropertyLinkSubList BoundaryList; // Curves to be turned into a face (2-4 curves allowed).
App::PropertyBoolList ReversedList; // Booleans to handle orientation of the curves
App::PropertyEnumeration FillType; // Fill method (1, 2, or 3 for Stretch, Coons, and Curved)
App::PropertyLinkSubList BoundaryList;// Curves to be turned into a face (2-4 curves allowed).
App::PropertyBoolList ReversedList; // Booleans to handle orientation of the curves
App::PropertyEnumeration FillType; // Fill method (1, 2, or 3 for Stretch, Coons, and Curved)
short mustExecute() const override;
void onChanged(const App::Property*) override;
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
/// returns the type name of the view provider
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "SurfaceGui::ViewProviderGeomFillSurface";
}
@@ -80,7 +85,7 @@ protected:
GeomFill_FillingStyle getFillingStyle();
/// True means that all edges have Bezier curves
bool getWire(TopoDS_Wire& aWire);
void createFace(const Handle(Geom_BoundedSurface) &aSurface);
void createFace(const Handle(Geom_BoundedSurface) & aSurface);
void createBezierSurface(TopoDS_Wire& aWire);
void createBSplineSurface(TopoDS_Wire& aWire);
@@ -88,6 +93,6 @@ private:
static const char* FillTypeEnums[];
};
}
}// namespace Surface
#endif // FEATUREGEOMFILLSURFACE_H
#endif// FEATUREGEOMFILLSURFACE_H

View File

@@ -22,15 +22,15 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAdaptor_Curve.hxx>
# include <BRepBuilderAPI_MakeFace.hxx>
# include <Geom_BSplineSurface.hxx>
# include <Geom_TrimmedCurve.hxx>
# include <GeomFill_NSections.hxx>
# include <Precision.hxx>
# include <Standard_Version.hxx>
# include <TopLoc_Location.hxx>
# include <TopoDS.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <GeomFill_NSections.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Precision.hxx>
#include <Standard_Version.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#endif
#include "FeatureSections.h"
@@ -42,11 +42,11 @@ PROPERTY_SOURCE(Surface::Sections, Part::Spline)
Sections::Sections()
{
ADD_PROPERTY_TYPE(NSections,(nullptr), "Sections", App::Prop_None, "Section curves");
ADD_PROPERTY_TYPE(NSections, (nullptr), "Sections", App::Prop_None, "Section curves");
NSections.setScope(App::LinkScope::Global);
}
App::DocumentObjectExecReturn *Sections::execute()
App::DocumentObjectExecReturn* Sections::execute()
{
TColGeom_SequenceOfCurve curveSeq;
auto edge_obj = NSections.getValues();
@@ -63,9 +63,10 @@ App::DocumentObjectExecReturn *Sections::execute()
if (!edge.IsNull() && edge.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve curve_adapt(TopoDS::Edge(edge));
const TopLoc_Location& loc = edge.Location();
Handle(Geom_TrimmedCurve) hCurve = new Geom_TrimmedCurve(curve_adapt.Curve().Curve(),
curve_adapt.FirstParameter(),
curve_adapt.LastParameter());
Handle(Geom_TrimmedCurve) hCurve =
new Geom_TrimmedCurve(curve_adapt.Curve().Curve(),
curve_adapt.FirstParameter(),
curve_adapt.LastParameter());
if (!loc.IsIdentity()) {
hCurve->Transform(loc.Transformation());
}
@@ -75,17 +76,19 @@ App::DocumentObjectExecReturn *Sections::execute()
}
}
if (curveSeq.Length() < 2)
if (curveSeq.Length() < 2) {
return new App::DocumentObjectExecReturn("At least two sections are required.");
}
GeomFill_NSections fillOp(curveSeq);
fillOp.ComputeSurface();
Handle(Geom_BSplineSurface) aSurf = fillOp.BSplineSurface();
if (aSurf.IsNull())
if (aSurf.IsNull()) {
return new App::DocumentObjectExecReturn("Failed to create surface from sections.");
}
BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion() );
BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
Shape.setValue(mkFace.Face());
return StdReturn;

View File

@@ -31,7 +31,7 @@
namespace Surface
{
class SurfaceExport Sections : public Part::Spline
class SurfaceExport Sections: public Part::Spline
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::Sections);
@@ -41,13 +41,14 @@ public:
App::PropertyLinkSubList NSections;
// recalculate the feature
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
/// returns the type name of the view provider
const char* getViewProviderName() const override {
const char* getViewProviderName() const override
{
return "SurfaceGui::ViewProviderSections";
}
};
}//Namespace Surface
}// Namespace Surface
#endif

View File

@@ -22,9 +22,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepBuilderAPI_Sewing.hxx>
# include <Precision.hxx>
# include <TopoDS.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#endif
#include "FeatureSewing.h"
@@ -34,35 +34,40 @@ using namespace Surface;
PROPERTY_SOURCE(Surface::Sewing, Part::Feature)
//Initial values
// Initial values
Sewing::Sewing()
{
ADD_PROPERTY_TYPE(ShapeList,(nullptr,""), "Sewing", App::Prop_None, "Input shapes");
ADD_PROPERTY_TYPE(Tolerance,(Precision::Confusion()), "Sewing", App::Prop_None, "Sewing tolerance");
ADD_PROPERTY_TYPE(SewingOption,(true), "Sewing", App::Prop_None, "Sewing option");
ADD_PROPERTY_TYPE(DegenerateShape,(true), "Sewing", App::Prop_None, "Analysis of degenerated shapes");
ADD_PROPERTY_TYPE(CutFreeEdges,(true), "Sewing", App::Prop_None, "Cutting of free edges");
ADD_PROPERTY_TYPE(Nonmanifold,(false), "Sewing", App::Prop_None, "Non-manifold processing");
ADD_PROPERTY_TYPE(ShapeList, (nullptr, ""), "Sewing", App::Prop_None, "Input shapes");
ADD_PROPERTY_TYPE(Tolerance,
(Precision::Confusion()),
"Sewing",
App::Prop_None,
"Sewing tolerance");
ADD_PROPERTY_TYPE(SewingOption, (true), "Sewing", App::Prop_None, "Sewing option");
ADD_PROPERTY_TYPE(DegenerateShape,
(true),
"Sewing",
App::Prop_None,
"Analysis of degenerated shapes");
ADD_PROPERTY_TYPE(CutFreeEdges, (true), "Sewing", App::Prop_None, "Cutting of free edges");
ADD_PROPERTY_TYPE(Nonmanifold, (false), "Sewing", App::Prop_None, "Non-manifold processing");
ShapeList.setScope(App::LinkScope::Global);
}
short Sewing::mustExecute() const
{
if (ShapeList.isTouched() ||
Tolerance.isTouched() ||
SewingOption.isTouched() ||
DegenerateShape.isTouched() ||
CutFreeEdges.isTouched() ||
Nonmanifold.isTouched())
if (ShapeList.isTouched() || Tolerance.isTouched() || SewingOption.isTouched()
|| DegenerateShape.isTouched() || CutFreeEdges.isTouched() || Nonmanifold.isTouched()) {
return 1;
}
return 0;
}
App::DocumentObjectExecReturn *Sewing::execute()
App::DocumentObjectExecReturn* Sewing::execute()
{
//Assign Variables
// Assign Variables
double atol = Tolerance.getValue();
bool opt1 = SewingOption.getValue();
bool opt2 = DegenerateShape.getValue();
@@ -70,17 +75,17 @@ App::DocumentObjectExecReturn *Sewing::execute()
bool opt4 = Nonmanifold.getValue();
try {
BRepBuilderAPI_Sewing builder(atol,opt1,opt2,opt3,opt4);
BRepBuilderAPI_Sewing builder(atol, opt1, opt2, opt3, opt4);
std::vector<App::PropertyLinkSubList::SubSet> subset = ShapeList.getSubListValues();
for(const auto& it : subset) {
for (const auto& it : subset) {
// the subset has the documentobject and the element name which belongs to it,
// in our case for example the cube object and the "Edge1" string
if (it.first->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
//we get the shape of the document object which resemble the whole box
// we get the shape of the document object which resemble the whole box
Part::TopoShape ts = static_cast<Part::Feature*>(it.first)->Shape.getShape();
//we want only the subshape which is linked
// we want only the subshape which is linked
for (const auto& jt : it.second) {
TopoDS_Shape sub = ts.getSubShape(jt.c_str());
builder.Add(sub);
@@ -91,11 +96,12 @@ App::DocumentObjectExecReturn *Sewing::execute()
}
}
builder.Perform(); //Perform Sewing
builder.Perform();// Perform Sewing
TopoDS_Shape aShape = builder.SewedShape(); //Get Shape
if (aShape.IsNull())
TopoDS_Shape aShape = builder.SewedShape();// Get Shape
if (aShape.IsNull()) {
return new App::DocumentObjectExecReturn("Resulting shape is null");
}
this->Shape.setValue(aShape);
return StdReturn;
}

View File

@@ -31,26 +31,26 @@
namespace Surface
{
class SurfaceExport Sewing : public Part::Feature
class SurfaceExport Sewing: public Part::Feature
{
PROPERTY_HEADER_WITH_OVERRIDE(Surface::Sewing);
public:
Sewing();
App::PropertyLinkSubList ShapeList; //Shapes to be sewn.
App::PropertyLinkSubList ShapeList;// Shapes to be sewn.
App::PropertyFloat Tolerance;
App::PropertyBool SewingOption; //Option for sewing (if false only control)
App::PropertyBool DegenerateShape; //Option for analysis of degenerated shapes
App::PropertyBool CutFreeEdges; //Option for cutting of free edges
App::PropertyBool Nonmanifold; //Option for non-manifold processing
App::PropertyBool SewingOption; // Option for sewing (if false only control)
App::PropertyBool DegenerateShape;// Option for analysis of degenerated shapes
App::PropertyBool CutFreeEdges; // Option for cutting of free edges
App::PropertyBool Nonmanifold; // Option for non-manifold processing
// recalculate the feature
App::DocumentObjectExecReturn *execute() override;
App::DocumentObjectExecReturn* execute() override;
short mustExecute() const override;
};
}//Namespace Surface
}// Namespace Surface
#endif // SURFACE_FEATURESEWING_H
#endif// SURFACE_FEATURESEWING_H

View File

@@ -30,10 +30,9 @@
// STL
#include <string>
//opencascade
// opencascade
#include <Mod/Part/App/OpenCascadeAll.h>
#endif //_PreComp_
#endif//_PreComp_
#endif

View File

@@ -41,11 +41,13 @@
void CreateSurfaceCommands();
namespace SurfaceGui {
class Module : public Py::ExtensionModule<Module>
namespace SurfaceGui
{
class Module: public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("SurfaceGui")
Module()
: Py::ExtensionModule<Module>("SurfaceGui")
{
initialize("This module is the SurfaceGui module.");// register with Python
}
@@ -53,7 +55,8 @@ public:
private:
};
PyObject *initModule() {
PyObject* initModule()
{
return Base::Interpreter().addModule(new Module);
}
@@ -70,6 +73,7 @@ PyMOD_INIT_FUNC(SurfaceGui)
Base::Interpreter().runString("import Surface");
Base::Interpreter().runString("import PartGui");
// clang-format off
// instantiating the commands
CreateSurfaceCommands();
@@ -80,8 +84,9 @@ PyMOD_INIT_FUNC(SurfaceGui)
SurfaceGui::ViewProviderExtend ::init();
SurfaceGui::ViewProviderBlendCurve ::init();
// SurfaceGui::ViewProviderCut::init();
// clang-format on
PyObject *mod = SurfaceGui::initModule();
PyObject* mod = SurfaceGui::initModule();
Base::Console().Log("Loading GUI of Surface module... done\n");
PyMOD_Return(mod);
}

View File

@@ -22,8 +22,8 @@
#include "PreCompiled.h"
#include <Gui/BitmapFactory.h>
#include "ViewProviderBlendCurve.h"
#include <Gui/BitmapFactory.h>
PROPERTY_SOURCE(SurfaceGui::ViewProviderBlendCurve, PartGui::ViewProviderSpline)
@@ -35,4 +35,4 @@ QIcon ViewProviderBlendCurve::getIcon() const
return Gui::BitmapFactory().pixmap("Surface_BlendCurve");
}
}//namespace SurfaceGui
}// namespace SurfaceGui

View File

@@ -36,6 +36,6 @@ public:
QIcon getIcon() const override;
};
}//namespace SurfaceGui
}// namespace SurfaceGui
#endif// SURFACEGUI_VIEWPROVIDEREXTEND_H

View File

@@ -23,16 +23,17 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QApplication>
# include <QMessageBox>
#include <QApplication>
#include <QMessageBox>
#include <sstream>
# include <BRepAdaptor_Curve.hxx>
# include <GeomAPI_ProjectPointOnCurve.hxx>
# include <TopoDS_Edge.hxx>
# include <TopoDS_Shape.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#endif
#include "Mod/Part/App/PartFeature.h"
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
@@ -40,7 +41,6 @@
#include <Gui/MainWindow.h>
#include <Gui/SelectionFilter.h>
#include <Gui/SelectionObject.h>
#include "Mod/Part/App/PartFeature.h"
//===========================================================================
@@ -49,76 +49,76 @@
DEF_STD_CMD(CmdSurfaceCut)
CmdSurfaceCut::CmdSurfaceCut()
:Command("Surface_Cut")
: Command("Surface_Cut")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Surface Cut function");
sToolTipText = QT_TR_NOOP("Cuts a shape with another Shape.\n"
"It returns a modified version of the first shape");
sWhatsThis = "Surface_Cut";
sStatusTip = sToolTipText;
sPixmap = "Surface_Cut";
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Surface Cut function");
sToolTipText = QT_TR_NOOP("Cuts a shape with another Shape.\n"
"It returns a modified version of the first shape");
sWhatsThis = "Surface_Cut";
sStatusTip = sToolTipText;
sPixmap = "Surface_Cut";
// sAccel = "CTRL+H";
}
void CmdSurfaceCut::activated(int iMsg)
{
Q_UNUSED(iMsg);
/* std::vector<Gui::SelectionObject> Sel = getSelection().getSelectionEx(0, Part::Feature::getClassTypeId());
if (Sel.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Invalid selection"),
QObject::tr("Select two shapes please."));
return;
}
/* std::vector<Gui::SelectionObject> Sel = getSelection().getSelectionEx(0,
Part::Feature::getClassTypeId()); if (Sel.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Invalid selection"),
QObject::tr("Select two shapes please."));
return;
}
bool askUser = false;
for (std::vector<Gui::SelectionObject>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
App::DocumentObject* obj = it->getObject();
if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
const TopoDS_Shape& shape = static_cast<Part::Feature*>(obj)->Shape.getValue();
if (!PartGui::checkForSolids(shape) && !askUser) {
int ret = QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Non-solids selected"),
QObject::tr("The use of non-solids for boolean operations may lead to unexpected results.\n"
"Do you want to continue?"), QMessageBox::Yes, QMessageBox::No);
if (ret == QMessageBox::No)
return;
askUser = true;
bool askUser = false;
for (std::vector<Gui::SelectionObject>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
App::DocumentObject* obj = it->getObject();
if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
const TopoDS_Shape& shape = static_cast<Part::Feature*>(obj)->Shape.getValue();
if (!PartGui::checkForSolids(shape) && !askUser) {
int ret = QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Non-solids
selected"), QObject::tr("The use of non-solids for boolean operations may lead to unexpected
results.\n" "Do you want to continue?"), QMessageBox::Yes, QMessageBox::No); if (ret ==
QMessageBox::No) return; askUser = true;
}
}
}
}
std::string FeatName = getUniqueObjectName("Cut");
std::string BaseName = Sel[0].getFeatName();
std::string ToolName = Sel[1].getFeatName();
std::string FeatName = getUniqueObjectName("Cut");
std::string BaseName = Sel[0].getFeatName();
std::string ToolName = Sel[1].getFeatName();
openCommand(QT_TRANSLATE_NOOP("Command", "Part Cut"));
doCommand(Doc,"App.activeDocument().addObject(\"Part::Cut\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Base = App.activeDocument().%s",FeatName.c_str(),BaseName.c_str());
doCommand(Doc,"App.activeDocument().%s.Tool = App.activeDocument().%s",FeatName.c_str(),ToolName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",BaseName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",ToolName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", BaseName.c_str());
copyVisual(FeatName.c_str(), "DisplayMode", BaseName.c_str());
updateActive();
commitCommand();*/
openCommand(QT_TRANSLATE_NOOP("Command", "Part Cut"));
doCommand(Doc,"App.activeDocument().addObject(\"Part::Cut\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Base =
App.activeDocument().%s",FeatName.c_str(),BaseName.c_str());
doCommand(Doc,"App.activeDocument().%s.Tool =
App.activeDocument().%s",FeatName.c_str(),ToolName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",BaseName.c_str());
doCommand(Gui,"Gui.activeDocument().hide('%s')",ToolName.c_str());
copyVisual(FeatName.c_str(), "ShapeColor", BaseName.c_str());
copyVisual(FeatName.c_str(), "DisplayMode", BaseName.c_str());
updateActive();
commitCommand();*/
}
DEF_STD_CMD_A(CmdSurfaceFilling)
CmdSurfaceFilling::CmdSurfaceFilling()
:Command("Surface_Filling")
: Command("Surface_Filling")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Filling...");
sToolTipText = QT_TR_NOOP("Creates a surface from a series of picked boundary edges.\n"
"Additionally, the surface may be constrained by non-boundary edges\n"
"and non-boundary vertices.");
sStatusTip = sToolTipText;
sWhatsThis = "Surface_Filling";
sPixmap = "Surface_Filling";
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Filling...");
sToolTipText = QT_TR_NOOP("Creates a surface from a series of picked boundary edges.\n"
"Additionally, the surface may be constrained by non-boundary edges\n"
"and non-boundary vertices.");
sStatusTip = sToolTipText;
sWhatsThis = "Surface_Filling";
sPixmap = "Surface_Filling";
}
void CmdSurfaceFilling::activated(int iMsg)
@@ -144,13 +144,13 @@ DEF_STD_CMD_A(CmdSurfaceGeomFillSurface)
CmdSurfaceGeomFillSurface::CmdSurfaceGeomFillSurface()
: Command("Surface_GeomFillSurface")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Fill boundary curves");
sToolTipText = QT_TR_NOOP("Creates a surface from two, three or four boundary edges.");
sWhatsThis = "Surface_GeomFillSurface";
sStatusTip = sToolTipText;
sPixmap = "Surface_GeomFillSurface";
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Fill boundary curves");
sToolTipText = QT_TR_NOOP("Creates a surface from two, three or four boundary edges.");
sWhatsThis = "Surface_GeomFillSurface";
sStatusTip = sToolTipText;
sPixmap = "Surface_GeomFillSurface";
}
bool CmdSurfaceGeomFillSurface::isActive()
@@ -164,46 +164,48 @@ void CmdSurfaceGeomFillSurface::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Surface");
openCommand(QT_TRANSLATE_NOOP("Command", "Create surface"));
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::GeomFillSurface\",\"%s\")", FeatName.c_str());
doCommand(Doc,
"App.ActiveDocument.addObject(\"Surface::GeomFillSurface\",\"%s\")",
FeatName.c_str());
doCommand(Doc, "Gui.ActiveDocument.setEdit('%s',0)", FeatName.c_str());
}
DEF_STD_CMD_A(CmdSurfaceCurveOnMesh)
CmdSurfaceCurveOnMesh::CmdSurfaceCurveOnMesh()
: Command("Surface_CurveOnMesh")
: Command("Surface_CurveOnMesh")
{
sAppModule = "MeshPart";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Curve on mesh...");
sToolTipText = QT_TR_NOOP("Creates an approximated curve on top of a mesh.\n"
"This command only works with a 'mesh' object.");
sWhatsThis = "Surface_CurveOnMesh";
sStatusTip = sToolTipText;
sPixmap = "Surface_CurveOnMesh";
sAppModule = "MeshPart";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Curve on mesh...");
sToolTipText = QT_TR_NOOP("Creates an approximated curve on top of a mesh.\n"
"This command only works with a 'mesh' object.");
sWhatsThis = "Surface_CurveOnMesh";
sStatusTip = sToolTipText;
sPixmap = "Surface_CurveOnMesh";
}
void CmdSurfaceCurveOnMesh::activated(int)
{
doCommand(Doc, "import MeshPartGui, FreeCADGui\n"
"FreeCADGui.runCommand('MeshPart_CurveOnMesh')\n");
doCommand(Doc,
"import MeshPartGui, FreeCADGui\n"
"FreeCADGui.runCommand('MeshPart_CurveOnMesh')\n");
}
bool CmdSurfaceCurveOnMesh::isActive()
{
if (Gui::Control().activeDialog())
if (Gui::Control().activeDialog()) {
return false;
}
// Check for the selected mesh feature (all Mesh types)
Base::Type meshType = Base::Type::fromName("Mesh::Feature");
App::Document* doc = App::GetApplication().getActiveDocument();
if (doc && doc->countObjectsOfType(meshType) > 0)
if (doc && doc->countObjectsOfType(meshType) > 0) {
return true;
}
return false;
}
@@ -231,7 +233,8 @@ void CmdBlendCurve::activated(int)
std::string objName[2];
std::string edge[2];
std::string featName = getUniqueObjectName("BlendCurve");
std::vector<Gui::SelectionObject> sel = getSelection().getSelectionEx(nullptr, Part::Feature::getClassTypeId());
std::vector<Gui::SelectionObject> sel =
getSelection().getSelectionEx(nullptr, Part::Feature::getClassTypeId());
objName[0] = sel[0].getFeatName();
edge[0] = sel[0].getSubNames()[0];
@@ -245,9 +248,21 @@ void CmdBlendCurve::activated(int)
edge[1] = sel[1].getSubNames()[0];
}
openCommand(QT_TRANSLATE_NOOP("Command", "Blend Curve"));
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::FeatureBlendCurve\",\"%s\")", featName.c_str());
doCommand(Doc, "App.ActiveDocument.%s.StartEdge = (App.getDocument('%s').getObject('%s'),['%s'])", featName.c_str(), docName.c_str(), objName[0].c_str(), edge[0].c_str());
doCommand(Doc, "App.ActiveDocument.%s.EndEdge = (App.getDocument('%s').getObject('%s'),['%s'])", featName.c_str(), docName.c_str(), objName[1].c_str(), edge[1].c_str());
doCommand(Doc,
"App.ActiveDocument.addObject(\"Surface::FeatureBlendCurve\",\"%s\")",
featName.c_str());
doCommand(Doc,
"App.ActiveDocument.%s.StartEdge = (App.getDocument('%s').getObject('%s'),['%s'])",
featName.c_str(),
docName.c_str(),
objName[0].c_str(),
edge[0].c_str());
doCommand(Doc,
"App.ActiveDocument.%s.EndEdge = (App.getDocument('%s').getObject('%s'),['%s'])",
featName.c_str(),
docName.c_str(),
objName[1].c_str(),
edge[1].c_str());
updateActive();
commitCommand();
}
@@ -261,37 +276,42 @@ bool CmdBlendCurve::isActive()
DEF_STD_CMD_A(CmdSurfaceExtendFace)
CmdSurfaceExtendFace::CmdSurfaceExtendFace()
: Command("Surface_ExtendFace")
: Command("Surface_ExtendFace")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Extend face");
sToolTipText = QT_TR_NOOP("Extrapolates the selected face or surface at its boundaries\n"
"with its local U and V parameters.");
sWhatsThis = "Surface_ExtendFace";
sStatusTip = sToolTipText;
sPixmap = "Surface_ExtendFace";
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Extend face");
sToolTipText = QT_TR_NOOP("Extrapolates the selected face or surface at its boundaries\n"
"with its local U and V parameters.");
sWhatsThis = "Surface_ExtendFace";
sStatusTip = sToolTipText;
sPixmap = "Surface_ExtendFace";
}
void CmdSurfaceExtendFace::activated(int)
{
Gui::SelectionFilter faceFilter("SELECT Part::Feature SUBELEMENT Face COUNT 1");
if (faceFilter.match()) {
const std::vector<std::string> &sub = faceFilter.Result[0][0].getSubNames();
const std::vector<std::string>& sub = faceFilter.Result[0][0].getSubNames();
if (sub.size() == 1) {
openCommand(QT_TRANSLATE_NOOP("Command", "Extend surface"));
std::string FeatName = getUniqueObjectName("Surface");
std::string supportString = faceFilter.Result[0][0].getAsPropertyLinkSubString();
doCommand(Doc, "App.ActiveDocument.addObject(\"Surface::Extend\",\"%s\")", FeatName.c_str());
doCommand(Doc, "App.ActiveDocument.%s.Face = %s", FeatName.c_str(), supportString.c_str());
doCommand(Doc,
"App.ActiveDocument.addObject(\"Surface::Extend\",\"%s\")",
FeatName.c_str());
doCommand(Doc,
"App.ActiveDocument.%s.Face = %s",
FeatName.c_str(),
supportString.c_str());
updateActive();
commitCommand();
}
}
else {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("Surface_ExtendFace", "Wrong selection"),
qApp->translate("Surface_ExtendFace", "Select a single face"));
qApp->translate("Surface_ExtendFace", "Wrong selection"),
qApp->translate("Surface_ExtendFace", "Select a single face"));
}
}
@@ -303,15 +323,15 @@ bool CmdSurfaceExtendFace::isActive()
DEF_STD_CMD_A(CmdSurfaceSections)
CmdSurfaceSections::CmdSurfaceSections()
:Command("Surface_Sections")
: Command("Surface_Sections")
{
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Sections...");
sToolTipText = QT_TR_NOOP("Creates a surface from a series of sectional edges.");
sStatusTip = sToolTipText;
sWhatsThis = "Surface_Sections";
sPixmap = "Surface_Sections";
sAppModule = "Surface";
sGroup = QT_TR_NOOP("Surface");
sMenuText = QT_TR_NOOP("Sections...");
sToolTipText = QT_TR_NOOP("Creates a surface from a series of sectional edges.");
sStatusTip = sToolTipText;
sWhatsThis = "Surface_Sections";
sPixmap = "Surface_Sections";
}
void CmdSurfaceSections::activated(int iMsg)
@@ -331,10 +351,10 @@ bool CmdSurfaceSections::isActive()
void CreateSurfaceCommands()
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
/*
rcCmdMgr.addCommand(new CmdSurfaceCut());
*/
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
/*
rcCmdMgr.addCommand(new CmdSurfaceCut());
*/
rcCmdMgr.addCommand(new CmdSurfaceFilling());
rcCmdMgr.addCommand(new CmdSurfaceGeomFillSurface());
rcCmdMgr.addCommand(new CmdSurfaceSections());

View File

@@ -39,15 +39,15 @@
// OpenCasCade
#include <BRepAdaptor_Curve.hxx>
#include <GeomAbs_Shape.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAbs_Shape.hxx>
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#endif //_PreComp_
#endif//_PreComp_
#endif // GUI_PRECOMPILED_H
#endif// GUI_PRECOMPILED_H

View File

@@ -38,6 +38,6 @@ enum SelectionMode
RemoveVertexConstraint = 7,
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_SELECTIONMODE_H
#endif// SURFACEGUI_SELECTIONMODE_H

View File

@@ -22,16 +22,16 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QMenu>
# include <QMessageBox>
# include <QTimer>
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <QTimer>
# include <GeomAbs_Shape.hxx>
# include <TopExp.hxx>
# include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <TopTools_ListIteratorOfListOfShape.hxx>
#include <GeomAbs_Shape.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#endif
#include <App/Document.h>
@@ -45,16 +45,17 @@
#include <Mod/Part/Gui/ViewProvider.h>
#include "TaskFilling.h"
#include "ui_TaskFilling.h"
#include "TaskFillingEdge.h"
#include "TaskFillingVertex.h"
#include "ui_TaskFilling.h"
using namespace SurfaceGui;
PROPERTY_SOURCE(SurfaceGui::ViewProviderFilling, PartGui::ViewProviderSpline)
namespace SurfaceGui {
namespace SurfaceGui
{
void ViewProviderFilling::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
@@ -66,20 +67,21 @@ void ViewProviderFilling::setupContextMenu(QMenu* menu, QObject* receiver, const
bool ViewProviderFilling::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
if (ModNum == ViewProvider::Default) {
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Surface::Filling* obj = static_cast<Surface::Filling*>(this->getObject());
Surface::Filling* obj = static_cast<Surface::Filling*>(this->getObject());
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
// start the edit dialog
if (dlg) {
TaskFilling* tDlg = qobject_cast<TaskFilling*>(dlg);
if (tDlg)
if (tDlg) {
tDlg->setEditedObject(obj);
}
Gui::Control().showDialog(dlg);
}
else {
@@ -108,72 +110,78 @@ void ViewProviderFilling::highlightReferences(ShapeType type, const References&
Part::Feature* base = dynamic_cast<Part::Feature*>(it.first);
if (base) {
PartGui::ViewProviderPartExt* svp = dynamic_cast<PartGui::ViewProviderPartExt*>(
Gui::Application::Instance->getViewProvider(base));
Gui::Application::Instance->getViewProvider(base));
if (svp) {
switch (type) {
case ViewProviderFilling::Vertex:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_VERTEX, vMap);
colors.resize(vMap.Extent(), svp->PointColor.getValue());
case ViewProviderFilling::Vertex:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_VERTEX, vMap);
colors.resize(vMap.Extent(), svp->PointColor.getValue());
for (const auto& jt : it.second) {
// check again that the index is in range because it's possible that the
// sub-names are invalid
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(6)) - 1);
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
for (const auto& jt : it.second) {
// check again that the index is in range because it's possible that
// the sub-names are invalid
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(6)) - 1);
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
svp->setHighlightedPoints(colors);
}
svp->setHighlightedPoints(colors);
}
else {
svp->unsetHighlightedPoints();
}
break;
case ViewProviderFilling::Edge:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape eMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
colors.resize(eMap.Extent(), svp->LineColor.getValue());
for (const auto& jt : it.second) {
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that the
// sub-names are invalid
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
else {
svp->unsetHighlightedPoints();
}
break;
case ViewProviderFilling::Edge:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape eMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
colors.resize(eMap.Extent(), svp->LineColor.getValue());
svp->setHighlightedEdges(colors);
}
else {
svp->unsetHighlightedEdges();
}
break;
case ViewProviderFilling::Face:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape fMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
colors.resize(fMap.Extent(), svp->ShapeColor.getValue());
for (const auto& jt : it.second) {
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that
// the sub-names are invalid
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
for (const auto& jt : it.second) {
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that the
// sub-names are invalid
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
svp->setHighlightedEdges(colors);
}
else {
svp->unsetHighlightedEdges();
}
break;
case ViewProviderFilling::Face:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape fMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
colors.resize(fMap.Extent(), svp->ShapeColor.getValue());
svp->setHighlightedFaces(colors);
}
else {
svp->unsetHighlightedFaces();
}
break;
for (const auto& jt : it.second) {
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that
// the sub-names are invalid
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
svp->setHighlightedFaces(colors);
}
else {
svp->unsetHighlightedFaces();
}
break;
}
}
}
@@ -182,42 +190,44 @@ void ViewProviderFilling::highlightReferences(ShapeType type, const References&
// ----------------------------------------------------------------------------
class FillingPanel::ShapeSelection : public Gui::SelectionFilterGate
class FillingPanel::ShapeSelection: public Gui::SelectionFilterGate
{
public:
ShapeSelection(FillingPanel::SelectionMode& mode, Surface::Filling* editedObject)
: Gui::SelectionFilterGate(nullPointer())
, mode(mode)
, editedObject(editedObject)
{
}
{}
~ShapeSelection() override
{
mode = FillingPanel::None;
}
/**
* Allow the user to pick only edges.
*/
* Allow the user to pick only edges.
*/
bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
{
// don't allow references to itself
if (pObj == editedObject)
if (pObj == editedObject) {
return false;
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
}
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
return false;
}
if (!sSubName || sSubName[0] == '\0')
if (!sSubName || sSubName[0] == '\0') {
return false;
}
switch (mode) {
case FillingPanel::InitFace:
return allowFace(pObj, sSubName);
case FillingPanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case FillingPanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
case FillingPanel::InitFace:
return allowFace(pObj, sSubName);
case FillingPanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case FillingPanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
}
}
@@ -225,22 +235,25 @@ private:
bool allowFace(App::DocumentObject*, const char* sSubName)
{
std::string element(sSubName);
if (element.substr(0,4) != "Face")
if (element.substr(0, 4) != "Face") {
return false;
}
return true;
}
bool allowEdge(bool appendEdges, App::DocumentObject* pObj, const char* sSubName)
{
std::string element(sSubName);
if (element.substr(0,4) != "Edge")
if (element.substr(0, 4) != "Edge") {
return false;
}
auto links = editedObject->BoundaryEdges.getSubListValues();
for (const auto& it : links) {
if (it.first == pObj) {
for (const auto& jt : it.second) {
if (jt == sSubName)
if (jt == sSubName) {
return !appendEdges;
}
}
}
}
@@ -276,7 +289,10 @@ FillingPanel::FillingPanel(ViewProviderFilling* vp, Surface::Filling* obj)
connect(action, &QAction::triggered, this, &FillingPanel::onDeleteEdge);
ui->listBoundary->setContextMenuPolicy(Qt::ActionsContextMenu);
connect(ui->listBoundary->model(), &QAbstractItemModel::rowsMoved, this, &FillingPanel::onIndexesMoved);
// clang-format off
connect(ui->listBoundary->model(), &QAbstractItemModel::rowsMoved,
this, &FillingPanel::onIndexesMoved);
// clang-format on
}
/*
@@ -290,6 +306,7 @@ FillingPanel::~FillingPanel()
void FillingPanel::setupConnections()
{
// clang-format off
connect(ui->buttonInitFace, &QPushButton::clicked,
this, &FillingPanel::onButtonInitFaceClicked);
connect(ui->buttonEdgeAdd, &QToolButton::toggled,
@@ -304,6 +321,7 @@ void FillingPanel::setupConnections()
this, &FillingPanel::onButtonAcceptClicked);
connect(ui->buttonIgnore, &QPushButton::clicked,
this, &FillingPanel::onButtonIgnoreClicked);
// clang-format on
}
void FillingPanel::appendButtons(Gui::ButtonGroup* buttonGroup)
@@ -322,9 +340,9 @@ void FillingPanel::setEditedObject(Surface::Filling* fea)
App::DocumentObject* initFace = editedObject->InitialFace.getValue();
const std::vector<std::string>& subList = editedObject->InitialFace.getSubValues();
if (initFace && subList.size() == 1) {
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(initFace->Label.getValue()),
QString::fromStdString(subList.front()));
QString text =
QString::fromLatin1("%1.%2").arg(QString::fromUtf8(initFace->Label.getValue()),
QString::fromStdString(subList.front()));
ui->lineInitFaceName->setText(text);
}
@@ -348,7 +366,7 @@ void FillingPanel::setEditedObject(Surface::Filling* fea)
}
App::Document* doc = editedObject->getDocument();
for (std::size_t i=0; i<count; i++) {
for (std::size_t i = 0; i < count; i++) {
App::DocumentObject* obj = objects[i];
std::string edge = edges[i];
std::string face = faces[i];
@@ -356,9 +374,8 @@ void FillingPanel::setEditedObject(Surface::Filling* fea)
QListWidgetItem* item = new QListWidgetItem(ui->listBoundary);
ui->listBoundary->addItem(item);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
item->setText(text);
// The user data field of a list widget item
@@ -381,7 +398,7 @@ void FillingPanel::setEditedObject(Surface::Filling* fea)
attachDocument(Gui::Application::Instance->getDocument(doc));
}
void FillingPanel::changeEvent(QEvent *e)
void FillingPanel::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -397,12 +414,13 @@ void FillingPanel::open()
// highlight the boundary edges
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), true);
editedObject->BoundaryEdges.getSubListValues(),
true);
// highlight the referenced face
std::vector<App::PropertyLinkSubList::SubSet> links;
links.emplace_back(editedObject->InitialFace.getValue(),
editedObject->InitialFace.getSubValues());
editedObject->InitialFace.getSubValues());
this->vp->highlightReferences(ViewProviderFilling::Face, links, true);
Gui::Selection().clearSelection();
@@ -444,12 +462,13 @@ void FillingPanel::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj)
// referenced part objects. The dialog will be deleted later.
if (this->vp == &Obj) {
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), false);
editedObject->BoundaryEdges.getSubListValues(),
false);
// unhighlight the referenced face
std::vector<App::PropertyLinkSubList::SubSet> links;
links.emplace_back(editedObject->InitialFace.getValue(),
editedObject->InitialFace.getSubValues());
editedObject->InitialFace.getSubValues());
this->vp->highlightReferences(ViewProviderFilling::Face, links, false);
}
}
@@ -459,21 +478,24 @@ bool FillingPanel::accept()
selectionMode = None;
Gui::Selection().rmvSelectionGate();
if (editedObject->mustExecute())
if (editedObject->mustExecute()) {
editedObject->recomputeFeature();
}
if (!editedObject->isValid()) {
QMessageBox::warning(this, tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
QMessageBox::warning(this,
tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
return false;
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), false);
editedObject->BoundaryEdges.getSubListValues(),
false);
// unhighlight the referenced face
std::vector<App::PropertyLinkSubList::SubSet> links;
links.emplace_back(editedObject->InitialFace.getValue(),
editedObject->InitialFace.getSubValues());
editedObject->InitialFace.getSubValues());
this->vp->highlightReferences(ViewProviderFilling::Face, links, false);
return true;
@@ -483,12 +505,13 @@ bool FillingPanel::reject()
{
if (!editedObject.expired()) {
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), false);
editedObject->BoundaryEdges.getSubListValues(),
false);
// unhighlight the referenced face
std::vector<App::PropertyLinkSubList::SubSet> links;
links.emplace_back(editedObject->InitialFace.getValue(),
editedObject->InitialFace.getSubValues());
editedObject->InitialFace.getSubValues());
this->vp->highlightReferences(ViewProviderFilling::Face, links, false);
}
@@ -506,7 +529,7 @@ void FillingPanel::onLineInitFaceNameTextChanged(const QString& text)
// unhighlight the referenced face
std::vector<App::PropertyLinkSubList::SubSet> links;
links.emplace_back(editedObject->InitialFace.getValue(),
editedObject->InitialFace.getSubValues());
editedObject->InitialFace.getSubValues());
this->vp->highlightReferences(ViewProviderFilling::Face, links, false);
editedObject->InitialFace.setValue(nullptr);
@@ -569,7 +592,10 @@ void FillingPanel::onListBoundaryItemDoubleClicked(QListWidgetItem* item)
TopTools_IndexedMapOfShape faces;
TopExp::MapShapes(shape.getShape(), TopAbs_FACE, faces);
TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
TopExp::MapShapesAndAncestors(shape.getShape(), TopAbs_EDGE, TopAbs_FACE, edge2Face);
TopExp::MapShapesAndAncestors(shape.getShape(),
TopAbs_EDGE,
TopAbs_FACE,
edge2Face);
const TopTools_ListOfShape& adj_faces = edge2Face.FindFromKey(edge);
if (adj_faces.Extent() > 0) {
int n = adj_faces.Extent();
@@ -578,9 +604,12 @@ void FillingPanel::onListBoundaryItemDoubleClicked(QListWidgetItem* item)
// fill up the combo boxes
modifyBoundary(true);
ui->comboBoxFaces->addItem(tr("None"), QByteArray(""));
ui->comboBoxCont->addItem(QString::fromLatin1("C0"), static_cast<int>(GeomAbs_C0));
ui->comboBoxCont->addItem(QString::fromLatin1("G1"), static_cast<int>(GeomAbs_G1));
ui->comboBoxCont->addItem(QString::fromLatin1("G2"), static_cast<int>(GeomAbs_G2));
ui->comboBoxCont->addItem(QString::fromLatin1("C0"),
static_cast<int>(GeomAbs_C0));
ui->comboBoxCont->addItem(QString::fromLatin1("G1"),
static_cast<int>(GeomAbs_G1));
ui->comboBoxCont->addItem(QString::fromLatin1("G2"),
static_cast<int>(GeomAbs_G2));
TopTools_ListIteratorOfListOfShape it(adj_faces);
for (; it.More(); it.Next()) {
const TopoDS_Shape& F = it.Value();
@@ -613,16 +642,17 @@ void FillingPanel::onListBoundaryItemDoubleClicked(QListWidgetItem* item)
void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (selectionMode == None)
if (selectionMode == None) {
return;
}
if (msg.Type == Gui::SelectionChanges::AddSelection) {
checkOpenCommand();
if (selectionMode == InitFace) {
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
ui->lineInitFaceName->setText(text);
std::vector<std::string> subList;
@@ -642,9 +672,9 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listBoundary->addItem(item);
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
item->setText(text);
QList<QVariant> data;
@@ -675,7 +705,8 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), true);
editedObject->BoundaryEdges.getSubListValues(),
true);
}
else if (selectionMode == RemoveEdge) {
Gui::SelectionObject sel(msg);
@@ -685,10 +716,10 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pSubName);
// only the three first elements must match
for (int i=0; i<ui->listBoundary->count(); i++) {
for (int i = 0; i < ui->listBoundary->count(); i++) {
QListWidgetItem* item = ui->listBoundary->item(i);
QList<QVariant> userdata = item->data(Qt::UserRole).toList();
if (userdata.mid(0,3) == data) {
if (userdata.mid(0, 3) == data) {
ui->listBoundary->takeItem(i);
delete item;
break;
@@ -696,7 +727,8 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), false);
editedObject->BoundaryEdges.getSubListValues(),
false);
App::DocumentObject* obj = sel.getObject();
std::string sub = msg.pSubName;
auto objects = editedObject->BoundaryEdges.getValues();
@@ -729,7 +761,8 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), true);
editedObject->BoundaryEdges.getSubListValues(),
true);
}
editedObject->recomputeFeature();
@@ -756,7 +789,8 @@ void FillingPanel::onDeleteEdge()
auto it = objects.begin();
auto jt = element.begin();
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), false);
editedObject->BoundaryEdges.getSubListValues(),
false);
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
if (*it == obj && *jt == sub) {
std::size_t index = std::distance(objects.begin(), it);
@@ -782,7 +816,8 @@ void FillingPanel::onDeleteEdge()
}
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->BoundaryEdges.getSubListValues(), true);
editedObject->BoundaryEdges.getSubListValues(),
true);
editedObject->recomputeFeature();
}
@@ -791,8 +826,9 @@ void FillingPanel::onDeleteEdge()
void FillingPanel::onIndexesMoved()
{
QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
if (!model)
if (!model) {
return;
}
std::vector<App::DocumentObject*> objects;
std::vector<std::string> element;
@@ -909,17 +945,19 @@ TaskFilling::TaskFilling(ViewProviderFilling* vp, Surface::Filling* obj)
// first task box
widget1 = new FillingPanel(vp, obj);
widget1->appendButtons(buttonGroup);
Gui::TaskView::TaskBox* taskbox1 = new Gui::TaskView::TaskBox(
Gui::BitmapFactory().pixmap("Surface_Filling"),
widget1->windowTitle(), true, nullptr);
Gui::TaskView::TaskBox* taskbox1 =
new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Surface_Filling"),
widget1->windowTitle(),
true,
nullptr);
taskbox1->groupLayout()->addWidget(widget1);
Content.push_back(taskbox1);
// second task box
widget2 = new FillingEdgePanel(vp, obj);
widget2->appendButtons(buttonGroup);
Gui::TaskView::TaskBox* taskbox2 = new Gui::TaskView::TaskBox(
QPixmap(), widget2->windowTitle(), true, nullptr);
Gui::TaskView::TaskBox* taskbox2 =
new Gui::TaskView::TaskBox(QPixmap(), widget2->windowTitle(), true, nullptr);
taskbox2->groupLayout()->addWidget(widget2);
Content.push_back(taskbox2);
taskbox2->hideGroupBox();
@@ -927,8 +965,8 @@ TaskFilling::TaskFilling(ViewProviderFilling* vp, Surface::Filling* obj)
// third task box
widget3 = new FillingVertexPanel(vp, obj);
widget3->appendButtons(buttonGroup);
Gui::TaskView::TaskBox* taskbox3 = new Gui::TaskView::TaskBox(
QPixmap(), widget3->windowTitle(), true, nullptr);
Gui::TaskView::TaskBox* taskbox3 =
new Gui::TaskView::TaskBox(QPixmap(), widget3->windowTitle(), true, nullptr);
taskbox3->groupLayout()->addWidget(widget3);
Content.push_back(taskbox3);
taskbox3->hideGroupBox();
@@ -958,7 +996,7 @@ bool TaskFilling::accept()
widget2->reject();
widget3->reject();
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
}
@@ -972,13 +1010,13 @@ bool TaskFilling::reject()
widget2->reject();
widget3->reject();
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
}
return ok;
}
}
}// namespace SurfaceGui
#include "moc_TaskFilling.cpp"

View File

@@ -46,13 +46,18 @@ class FillingVertexPanel;
class FillingEdgePanel;
class Ui_TaskFilling;
class ViewProviderFilling : public PartGui::ViewProviderSpline
class ViewProviderFilling: public PartGui::ViewProviderSpline
{
PROPERTY_HEADER_WITH_OVERRIDE(SurfaceGui::ViewProviderFilling);
using References = std::vector<App::PropertyLinkSubList::SubSet>;
public:
enum ShapeType {Vertex, Edge, Face};
enum ShapeType
{
Vertex,
Edge,
Face
};
void setupContextMenu(QMenu*, QObject*, const char*) override;
bool setEdit(int ModNum) override;
void unsetEdit(int ModNum) override;
@@ -60,15 +65,14 @@ public:
void highlightReferences(ShapeType type, const References& refs, bool on);
};
class FillingPanel : public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
class FillingPanel: public QWidget, public Gui::SelectionObserver, public Gui::DocumentObserver
{
Q_OBJECT
protected:
class ShapeSelection;
enum SelectionMode {
enum SelectionMode
{
None = SurfaceGui::SelectionMode::None,
InitFace = SurfaceGui::SelectionMode::InitFace,
AppendEdge = SurfaceGui::SelectionMode::AppendEdge,
@@ -91,10 +95,10 @@ public:
bool accept();
bool reject();
void setEditedObject(Surface::Filling* obj);
void appendButtons(Gui::ButtonGroup *);
void appendButtons(Gui::ButtonGroup*);
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
/** Notifies on undo */
void slotUndoDocument(const Gui::Document& Doc) override;
@@ -121,7 +125,7 @@ private:
void exitSelectionMode();
};
class TaskFilling : public Gui::TaskView::TaskDialog
class TaskFilling: public Gui::TaskView::TaskDialog
{
Q_OBJECT
@@ -136,7 +140,9 @@ public:
bool reject() override;
QDialogButtonBox::StandardButtons getStandardButtons() const override
{ return QDialogButtonBox::Ok | QDialogButtonBox::Cancel; }
{
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
}
private:
Gui::ButtonGroup* buttonGroup;
@@ -145,6 +151,6 @@ private:
FillingVertexPanel* widget3;
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_TASKFILLING_H
#endif// SURFACEGUI_TASKFILLING_H

View File

@@ -23,15 +23,15 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QMessageBox>
# include <QTimer>
#include <QAction>
#include <QMessageBox>
#include <QTimer>
# include <GeomAbs_Shape.hxx>
# include <TopExp.hxx>
# include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <TopTools_ListIteratorOfListOfShape.hxx>
#include <GeomAbs_Shape.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#endif
#include <App/Document.h>
@@ -42,49 +42,52 @@
#include <Gui/Widgets.h>
#include <Mod/Part/Gui/ViewProvider.h>
#include "TaskFilling.h"
#include "TaskFillingEdge.h"
#include "ui_TaskFillingEdge.h"
#include "TaskFilling.h"
using namespace SurfaceGui;
namespace SurfaceGui {
namespace SurfaceGui
{
class FillingEdgePanel::ShapeSelection : public Gui::SelectionFilterGate
class FillingEdgePanel::ShapeSelection: public Gui::SelectionFilterGate
{
public:
ShapeSelection(FillingEdgePanel::SelectionMode& mode, Surface::Filling* editedObject)
: Gui::SelectionFilterGate(nullPointer())
, mode(mode)
, editedObject(editedObject)
{
}
{}
~ShapeSelection() override
{
mode = FillingEdgePanel::None;
}
/**
* Allow the user to pick only edges.
*/
* Allow the user to pick only edges.
*/
bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
{
// don't allow references to itself
if (pObj == editedObject)
if (pObj == editedObject) {
return false;
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
}
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
return false;
}
if (!sSubName || sSubName[0] == '\0')
if (!sSubName || sSubName[0] == '\0') {
return false;
}
switch (mode) {
case FillingEdgePanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case FillingEdgePanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
case FillingEdgePanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case FillingEdgePanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
}
}
@@ -92,15 +95,17 @@ private:
bool allowEdge(bool appendEdges, App::DocumentObject* pObj, const char* sSubName)
{
std::string element(sSubName);
if (element.substr(0,4) != "Edge")
if (element.substr(0, 4) != "Edge") {
return false;
}
auto links = editedObject->UnboundEdges.getSubListValues();
for (const auto& it : links) {
if (it.first == pObj) {
for (const auto& jt : it.second) {
if (jt == sSubName)
if (jt == sSubName) {
return !appendEdges;
}
}
}
}
@@ -147,16 +152,26 @@ FillingEdgePanel::~FillingEdgePanel()
void FillingEdgePanel::setupConnections()
{
connect(ui->buttonUnboundEdgeAdd, &QToolButton::toggled,
this, &FillingEdgePanel::onButtonUnboundEdgeAddToggled);
connect(ui->buttonUnboundEdgeRemove, &QToolButton::toggled,
this, &FillingEdgePanel::onButtonUnboundEdgeRemoveToggled);
connect(ui->listUnbound, &QListWidget::itemDoubleClicked,
this, &FillingEdgePanel::onListUnboundItemDoubleClicked);
connect(ui->buttonUnboundAccept, &QPushButton::clicked,
this, &FillingEdgePanel::onButtonUnboundAcceptClicked);
connect(ui->buttonUnboundIgnore, &QPushButton::clicked,
this, &FillingEdgePanel::onButtonUnboundIgnoreClicked);
connect(ui->buttonUnboundEdgeAdd,
&QToolButton::toggled,
this,
&FillingEdgePanel::onButtonUnboundEdgeAddToggled);
connect(ui->buttonUnboundEdgeRemove,
&QToolButton::toggled,
this,
&FillingEdgePanel::onButtonUnboundEdgeRemoveToggled);
connect(ui->listUnbound,
&QListWidget::itemDoubleClicked,
this,
&FillingEdgePanel::onListUnboundItemDoubleClicked);
connect(ui->buttonUnboundAccept,
&QPushButton::clicked,
this,
&FillingEdgePanel::onButtonUnboundAcceptClicked);
connect(ui->buttonUnboundIgnore,
&QPushButton::clicked,
this,
&FillingEdgePanel::onButtonUnboundIgnoreClicked);
}
void FillingEdgePanel::appendButtons(Gui::ButtonGroup* buttonGroup)
@@ -190,7 +205,7 @@ void FillingEdgePanel::setEditedObject(Surface::Filling* fea)
}
App::Document* doc = editedObject->getDocument();
for (std::size_t i=0; i<count; i++) {
for (std::size_t i = 0; i < count; i++) {
App::DocumentObject* obj = objects[i];
std::string edge = edges[i];
std::string face = faces[i];
@@ -198,9 +213,8 @@ void FillingEdgePanel::setEditedObject(Surface::Filling* fea)
QListWidgetItem* item = new QListWidgetItem(ui->listUnbound);
ui->listUnbound->addItem(item);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
item->setText(text);
// The user data field of a list widget item
@@ -223,7 +237,7 @@ void FillingEdgePanel::setEditedObject(Surface::Filling* fea)
attachDocument(Gui::Application::Instance->getDocument(doc));
}
void FillingEdgePanel::changeEvent(QEvent *e)
void FillingEdgePanel::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -239,7 +253,8 @@ void FillingEdgePanel::open()
// highlight the boundary edges
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), true);
editedObject->UnboundEdges.getSubListValues(),
true);
Gui::Selection().clearSelection();
}
@@ -275,7 +290,8 @@ void FillingEdgePanel::slotDeletedObject(const Gui::ViewProviderDocumentObject&
// referenced part objects. The dialog will be deleted later.
if (this->vp == &Obj) {
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), false);
editedObject->UnboundEdges.getSubListValues(),
false);
}
}
@@ -284,23 +300,27 @@ bool FillingEdgePanel::accept()
selectionMode = None;
Gui::Selection().rmvSelectionGate();
if (editedObject->mustExecute())
if (editedObject->mustExecute()) {
editedObject->recomputeFeature();
}
if (!editedObject->isValid()) {
QMessageBox::warning(this, tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
QMessageBox::warning(this,
tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
return false;
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), false);
editedObject->UnboundEdges.getSubListValues(),
false);
return true;
}
bool FillingEdgePanel::reject()
{
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), false);
editedObject->UnboundEdges.getSubListValues(),
false);
selectionMode = None;
Gui::Selection().rmvSelectionGate();
@@ -356,7 +376,10 @@ void FillingEdgePanel::onListUnboundItemDoubleClicked(QListWidgetItem* item)
TopTools_IndexedMapOfShape faces;
TopExp::MapShapes(shape.getShape(), TopAbs_FACE, faces);
TopTools_IndexedDataMapOfShapeListOfShape edge2Face;
TopExp::MapShapesAndAncestors(shape.getShape(), TopAbs_EDGE, TopAbs_FACE, edge2Face);
TopExp::MapShapesAndAncestors(shape.getShape(),
TopAbs_EDGE,
TopAbs_FACE,
edge2Face);
const TopTools_ListOfShape& adj_faces = edge2Face.FindFromKey(edge);
if (adj_faces.Extent() > 0) {
int n = adj_faces.Extent();
@@ -365,9 +388,12 @@ void FillingEdgePanel::onListUnboundItemDoubleClicked(QListWidgetItem* item)
// fill up the combo boxes
modifyBoundary(true);
ui->comboBoxUnboundFaces->addItem(tr("None"), QByteArray(""));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("C0"), static_cast<int>(GeomAbs_C0));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G1"), static_cast<int>(GeomAbs_G1));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G2"), static_cast<int>(GeomAbs_G2));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("C0"),
static_cast<int>(GeomAbs_C0));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G1"),
static_cast<int>(GeomAbs_G1));
ui->comboBoxUnboundCont->addItem(QString::fromLatin1("G2"),
static_cast<int>(GeomAbs_G2));
TopTools_ListIteratorOfListOfShape it(adj_faces);
for (; it.More(); it.Next()) {
const TopoDS_Shape& F = it.Value();
@@ -400,8 +426,9 @@ void FillingEdgePanel::onListUnboundItemDoubleClicked(QListWidgetItem* item)
void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (selectionMode == None)
if (selectionMode == None) {
return;
}
if (msg.Type == Gui::SelectionChanges::AddSelection) {
checkOpenCommand();
@@ -410,9 +437,9 @@ void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listUnbound->addItem(item);
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
item->setText(text);
QList<QVariant> data;
@@ -443,7 +470,8 @@ void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), true);
editedObject->UnboundEdges.getSubListValues(),
true);
}
else if (selectionMode == RemoveEdge) {
Gui::SelectionObject sel(msg);
@@ -453,10 +481,10 @@ void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pSubName);
// only the three first elements must match
for (int i=0; i<ui->listUnbound->count(); i++) {
for (int i = 0; i < ui->listUnbound->count(); i++) {
QListWidgetItem* item = ui->listUnbound->item(i);
QList<QVariant> userdata = item->data(Qt::UserRole).toList();
if (userdata.mid(0,3) == data) {
if (userdata.mid(0, 3) == data) {
ui->listUnbound->takeItem(i);
delete item;
break;
@@ -464,7 +492,8 @@ void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), false);
editedObject->UnboundEdges.getSubListValues(),
false);
App::DocumentObject* obj = sel.getObject();
std::string sub = msg.pSubName;
auto objects = editedObject->UnboundEdges.getValues();
@@ -497,7 +526,8 @@ void FillingEdgePanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), true);
editedObject->UnboundEdges.getSubListValues(),
true);
}
editedObject->recomputeFeature();
@@ -524,7 +554,8 @@ void FillingEdgePanel::onDeleteUnboundEdge()
auto it = objects.begin();
auto jt = element.begin();
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), false);
editedObject->UnboundEdges.getSubListValues(),
false);
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
if (*it == obj && *jt == sub) {
std::size_t index = std::distance(objects.begin(), it);
@@ -550,7 +581,8 @@ void FillingEdgePanel::onDeleteUnboundEdge()
}
}
this->vp->highlightReferences(ViewProviderFilling::Edge,
editedObject->UnboundEdges.getSubListValues(), true);
editedObject->UnboundEdges.getSubListValues(),
true);
editedObject->recomputeFeature();
}
@@ -563,7 +595,8 @@ void FillingEdgePanel::onButtonUnboundAcceptClicked()
QList<QVariant> data;
data = item->data(Qt::UserRole).toList();
QVariant face = ui->comboBoxUnboundFaces->itemData(ui->comboBoxUnboundFaces->currentIndex());
QVariant face =
ui->comboBoxUnboundFaces->itemData(ui->comboBoxUnboundFaces->currentIndex());
QVariant cont = ui->comboBoxUnboundCont->itemData(ui->comboBoxUnboundCont->currentIndex());
if (data.size() == 5) {
data[3] = face;
@@ -620,7 +653,7 @@ void FillingEdgePanel::modifyBoundary(bool on)
ui->buttonUnboundAccept->setEnabled(on);
ui->buttonUnboundIgnore->setEnabled(on);
}
}
}// namespace SurfaceGui
void FillingEdgePanel::exitSelectionMode()
{

View File

@@ -24,11 +24,11 @@
#ifndef SURFACEGUI_TASKFILLINGEDGE_H
#define SURFACEGUI_TASKFILLINGEDGE_H
#include <QWidget>
#include <Gui/DocumentObserver.h>
#include <Gui/SelectionFilter.h>
#include <Mod/Surface/App/FeatureFilling.h>
#include <Mod/Surface/Gui/SelectionMode.h>
#include <QWidget>
class QListWidgetItem;
@@ -44,15 +44,14 @@ namespace SurfaceGui
class ViewProviderFilling;
class Ui_TaskFillingEdge;
class FillingEdgePanel : public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
class FillingEdgePanel: public QWidget, public Gui::SelectionObserver, public Gui::DocumentObserver
{
Q_OBJECT
protected:
class ShapeSelection;
enum SelectionMode {
enum SelectionMode
{
None = SurfaceGui::SelectionMode::None,
AppendEdge = SurfaceGui::SelectionMode::AppendEdgeConstraint,
RemoveEdge = SurfaceGui::SelectionMode::RemoveEdgeConstraint
@@ -74,10 +73,10 @@ public:
bool accept();
bool reject();
void setEditedObject(Surface::Filling* obj);
void appendButtons(Gui::ButtonGroup *);
void appendButtons(Gui::ButtonGroup*);
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
/** Notifies on undo */
void slotUndoDocument(const Gui::Document& Doc) override;
@@ -101,6 +100,6 @@ private:
void exitSelectionMode();
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_TASKFILLINGEDGE_H
#endif// SURFACEGUI_TASKFILLINGEDGE_H

View File

@@ -22,8 +22,8 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QTimer>
#include <QAction>
#include <QTimer>
#endif
#include <App/Document.h>
@@ -34,49 +34,52 @@
#include <Gui/Widgets.h>
#include <Mod/Part/Gui/ViewProvider.h>
#include "TaskFilling.h"
#include "TaskFillingVertex.h"
#include "ui_TaskFillingVertex.h"
#include "TaskFilling.h"
using namespace SurfaceGui;
namespace SurfaceGui {
namespace SurfaceGui
{
class FillingVertexPanel::VertexSelection : public Gui::SelectionFilterGate
class FillingVertexPanel::VertexSelection: public Gui::SelectionFilterGate
{
public:
VertexSelection(FillingVertexPanel::SelectionMode& mode, Surface::Filling* editedObject)
: Gui::SelectionFilterGate(nullPointer())
, mode(mode)
, editedObject(editedObject)
{
}
{}
~VertexSelection() override
{
mode = FillingVertexPanel::None;
}
/**
* Allow the user to pick only edges.
*/
* Allow the user to pick only edges.
*/
bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
{
// don't allow references to itself
if (pObj == editedObject)
if (pObj == editedObject) {
return false;
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
}
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
return false;
}
if (!sSubName || sSubName[0] == '\0')
if (!sSubName || sSubName[0] == '\0') {
return false;
}
switch (mode) {
case FillingVertexPanel::AppendVertex:
return allowVertex(true, pObj, sSubName);
case FillingVertexPanel::RemoveVertex:
return allowVertex(false, pObj, sSubName);
default:
return false;
case FillingVertexPanel::AppendVertex:
return allowVertex(true, pObj, sSubName);
case FillingVertexPanel::RemoveVertex:
return allowVertex(false, pObj, sSubName);
default:
return false;
}
}
@@ -84,15 +87,17 @@ private:
bool allowVertex(bool appendVertex, App::DocumentObject* pObj, const char* sSubName)
{
std::string element(sSubName);
if (element.substr(0,6) != "Vertex")
if (element.substr(0, 6) != "Vertex") {
return false;
}
auto links = editedObject->Points.getSubListValues();
for (const auto& it : links) {
if (it.first == pObj) {
for (const auto& jt : it.second) {
if (jt == sSubName)
if (jt == sSubName) {
return !appendVertex;
}
}
}
}
@@ -139,11 +144,14 @@ FillingVertexPanel::~FillingVertexPanel()
void FillingVertexPanel::setupConnections()
{
connect(ui->buttonVertexAdd, &QToolButton::toggled,
this, &FillingVertexPanel::onButtonVertexAddToggled);
connect(ui->buttonVertexRemove, &QToolButton::toggled,
this, &FillingVertexPanel::onButtonVertexRemoveToggled);
connect(ui->buttonVertexAdd,
&QToolButton::toggled,
this,
&FillingVertexPanel::onButtonVertexAddToggled);
connect(ui->buttonVertexRemove,
&QToolButton::toggled,
this,
&FillingVertexPanel::onButtonVertexRemoveToggled);
}
void FillingVertexPanel::appendButtons(Gui::ButtonGroup* buttonGroup)
@@ -167,9 +175,8 @@ void FillingVertexPanel::setEditedObject(Surface::Filling* obj)
QListWidgetItem* item = new QListWidgetItem(ui->listFreeVertex);
ui->listFreeVertex->addItem(item);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8((*it)->Label.getValue()),
QString::fromStdString(*jt));
QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8((*it)->Label.getValue()),
QString::fromStdString(*jt));
item->setText(text);
QList<QVariant> data;
@@ -181,7 +188,7 @@ void FillingVertexPanel::setEditedObject(Surface::Filling* obj)
attachDocument(Gui::Application::Instance->getDocument(doc));
}
void FillingVertexPanel::changeEvent(QEvent *e)
void FillingVertexPanel::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -195,14 +202,16 @@ void FillingVertexPanel::open()
{
checkOpenCommand();
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), true);
editedObject->Points.getSubListValues(),
true);
Gui::Selection().clearSelection();
}
void FillingVertexPanel::reject()
{
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), false);
editedObject->Points.getSubListValues(),
false);
}
void FillingVertexPanel::clearSelection()
@@ -236,7 +245,8 @@ void FillingVertexPanel::slotDeletedObject(const Gui::ViewProviderDocumentObject
// referenced part objects. The dialog will be deleted later.
if (this->vp == &Obj) {
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), false);
editedObject->Points.getSubListValues(),
false);
}
}
@@ -266,8 +276,9 @@ void FillingVertexPanel::onButtonVertexRemoveToggled(bool checked)
void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (selectionMode == None)
if (selectionMode == None) {
return;
}
if (msg.Type == Gui::SelectionChanges::AddSelection) {
checkOpenCommand();
@@ -276,9 +287,9 @@ void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listFreeVertex->addItem(item);
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
item->setText(text);
QList<QVariant> data;
@@ -293,7 +304,8 @@ void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
element.emplace_back(msg.pSubName);
editedObject->Points.setValues(objects, element);
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), true);
editedObject->Points.getSubListValues(),
true);
}
else if (selectionMode == RemoveVertex) {
Gui::SelectionObject sel(msg);
@@ -301,7 +313,7 @@ void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pDocName);
data << QByteArray(msg.pObjectName);
data << QByteArray(msg.pSubName);
for (int i=0; i<ui->listFreeVertex->count(); i++) {
for (int i = 0; i < ui->listFreeVertex->count(); i++) {
QListWidgetItem* item = ui->listFreeVertex->item(i);
if (item && item->data(Qt::UserRole) == data) {
ui->listFreeVertex->takeItem(i);
@@ -310,7 +322,8 @@ void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), false);
editedObject->Points.getSubListValues(),
false);
App::DocumentObject* obj = sel.getObject();
std::string sub = msg.pSubName;
auto objects = editedObject->Points.getValues();
@@ -326,7 +339,8 @@ void FillingVertexPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
}
}
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), true);
editedObject->Points.getSubListValues(),
true);
}
editedObject->recomputeFeature();
@@ -353,7 +367,8 @@ void FillingVertexPanel::onDeleteVertex()
auto it = objects.begin();
auto jt = element.begin();
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), false);
editedObject->Points.getSubListValues(),
false);
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
if (*it == obj && *jt == sub) {
@@ -366,7 +381,8 @@ void FillingVertexPanel::onDeleteVertex()
}
this->vp->highlightReferences(ViewProviderFilling::Vertex,
editedObject->Points.getSubListValues(), true);
editedObject->Points.getSubListValues(),
true);
}
}
@@ -377,6 +393,6 @@ void FillingVertexPanel::exitSelectionMode()
Gui::Selection().rmvSelectionGate();
}
}
}// namespace SurfaceGui
#include "moc_TaskFillingVertex.cpp"

View File

@@ -23,11 +23,11 @@
#ifndef SURFACEGUI_TASKFILLINGVERTEX_H
#define SURFACEGUI_TASKFILLINGVERTEX_H
#include <QWidget>
#include <Gui/DocumentObserver.h>
#include <Gui/SelectionFilter.h>
#include <Mod/Surface/App/FeatureFilling.h>
#include <Mod/Surface/Gui/SelectionMode.h>
#include <QWidget>
class QListWidgetItem;
@@ -43,15 +43,16 @@ namespace SurfaceGui
class ViewProviderFilling;
class Ui_TaskFillingVertex;
class FillingVertexPanel : public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
class FillingVertexPanel: public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
{
Q_OBJECT
protected:
class VertexSelection;
enum SelectionMode {
enum SelectionMode
{
None = SurfaceGui::SelectionMode::None,
AppendVertex = SurfaceGui::SelectionMode::AppendVertexConstraint,
RemoveVertex = SurfaceGui::SelectionMode::RemoveVertexConstraint
@@ -72,10 +73,10 @@ public:
void reject();
void checkOpenCommand();
void setEditedObject(Surface::Filling* obj);
void appendButtons(Gui::ButtonGroup *);
void appendButtons(Gui::ButtonGroup*);
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
/** Notifies on undo */
void slotUndoDocument(const Gui::Document& Doc) override;
@@ -95,6 +96,6 @@ private:
void exitSelectionMode();
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_TASKFILLINGVERTEX_H
#endif// SURFACEGUI_TASKFILLINGVERTEX_H

View File

@@ -23,13 +23,12 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QMenu>
# include <QMessageBox>
# include <QTimer>
# include <TopExp.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <QTimer>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#endif
#include <App/Document.h>
@@ -51,9 +50,12 @@ using namespace SurfaceGui;
PROPERTY_SOURCE(SurfaceGui::ViewProviderGeomFillSurface, PartGui::ViewProviderSpline)
namespace SurfaceGui {
namespace SurfaceGui
{
void ViewProviderGeomFillSurface::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
void ViewProviderGeomFillSurface::setupContextMenu(QMenu* menu,
QObject* receiver,
const char* member)
{
QAction* act;
act = menu->addAction(QObject::tr("Edit filling"), receiver, member);
@@ -63,20 +65,21 @@ void ViewProviderGeomFillSurface::setupContextMenu(QMenu* menu, QObject* receive
bool ViewProviderGeomFillSurface::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
if (ModNum == ViewProvider::Default) {
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Surface::GeomFillSurface* obj = static_cast<Surface::GeomFillSurface*>(this->getObject());
Surface::GeomFillSurface* obj = static_cast<Surface::GeomFillSurface*>(this->getObject());
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
// start the edit dialog
if (dlg) {
TaskGeomFillSurface* tDlg = qobject_cast<TaskGeomFillSurface*>(dlg);
if (tDlg)
if (tDlg) {
tDlg->setEditedObject(obj);
}
Gui::Control().showDialog(dlg);
}
else {
@@ -113,7 +116,7 @@ void ViewProviderGeomFillSurface::highlightReferences(bool on)
Part::Feature* base = dynamic_cast<Part::Feature*>(it.first);
if (base) {
PartGui::ViewProviderPartExt* svp = dynamic_cast<PartGui::ViewProviderPartExt*>(
Gui::Application::Instance->getViewProvider(base));
Gui::Application::Instance->getViewProvider(base));
if (svp) {
if (on) {
std::vector<App::Color> colors;
@@ -123,8 +126,8 @@ void ViewProviderGeomFillSurface::highlightReferences(bool on)
for (const auto& jt : it.second) {
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
assert (idx < colors.size());
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
assert(idx < colors.size());
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
svp->setHighlightedEdges(colors);
@@ -139,18 +142,17 @@ void ViewProviderGeomFillSurface::highlightReferences(bool on)
// ----------------------------------------------------------------------------
class GeomFillSurface::EdgeSelection : public Gui::SelectionFilterGate
class GeomFillSurface::EdgeSelection: public Gui::SelectionFilterGate
{
public:
EdgeSelection(bool appendEdges, Surface::GeomFillSurface* editedObject)
: Gui::SelectionFilterGate(nullPointer())
, appendEdges(appendEdges)
, editedObject(editedObject)
{
}
{}
/**
* Allow the user to pick only edges.
*/
* Allow the user to pick only edges.
*/
bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName) override;
private:
@@ -158,27 +160,34 @@ private:
Surface::GeomFillSurface* editedObject;
};
bool GeomFillSurface::EdgeSelection::allow(App::Document* , App::DocumentObject* pObj, const char* sSubName)
bool GeomFillSurface::EdgeSelection::allow(App::Document*,
App::DocumentObject* pObj,
const char* sSubName)
{
// don't allow references to itself
if (pObj == editedObject)
if (pObj == editedObject) {
return false;
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
}
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
return false;
}
if (!sSubName || sSubName[0] == '\0')
if (!sSubName || sSubName[0] == '\0') {
return false;
}
std::string element(sSubName);
if (element.substr(0,4) != "Edge")
if (element.substr(0, 4) != "Edge") {
return false;
}
auto links = editedObject->BoundaryList.getSubListValues();
for (const auto& it : links) {
if (it.first == pObj) {
for (const auto& jt : it.second) {
if (jt == sSubName)
if (jt == sSubName) {
return !appendEdges;
}
}
}
}
@@ -229,38 +238,50 @@ GeomFillSurface::~GeomFillSurface()
void GeomFillSurface::setupConnections()
{
connect(ui->fillType_stretch, &QRadioButton::clicked,
this, &GeomFillSurface::onFillTypeStretchClicked);
connect(ui->fillType_coons, &QRadioButton::clicked,
this, &GeomFillSurface::onFillTypeCoonsClicked);
connect(ui->fillType_curved, &QRadioButton::clicked,
this, &GeomFillSurface::onFillTypeCurvedClicked);
connect(ui->buttonEdgeAdd, &QToolButton::toggled,
this, &GeomFillSurface::onButtonEdgeAddToggled);
connect(ui->buttonEdgeRemove, &QToolButton::toggled,
this, &GeomFillSurface::onButtonEdgeRemoveToggled);
connect(ui->listWidget, &QListWidget::itemDoubleClicked,
this, &GeomFillSurface::onListWidgetItemDoubleClicked);
connect(ui->fillType_stretch,
&QRadioButton::clicked,
this,
&GeomFillSurface::onFillTypeStretchClicked);
connect(ui->fillType_coons,
&QRadioButton::clicked,
this,
&GeomFillSurface::onFillTypeCoonsClicked);
connect(ui->fillType_curved,
&QRadioButton::clicked,
this,
&GeomFillSurface::onFillTypeCurvedClicked);
connect(ui->buttonEdgeAdd,
&QToolButton::toggled,
this,
&GeomFillSurface::onButtonEdgeAddToggled);
connect(ui->buttonEdgeRemove,
&QToolButton::toggled,
this,
&GeomFillSurface::onButtonEdgeRemoveToggled);
connect(ui->listWidget,
&QListWidget::itemDoubleClicked,
this,
&GeomFillSurface::onListWidgetItemDoubleClicked);
}
// stores object pointer, its old fill type and adjusts radio buttons according to it.
void GeomFillSurface::setEditedObject(Surface::GeomFillSurface* obj)
{
editedObject = obj;
GeomFill_FillingStyle curtype = static_cast<GeomFill_FillingStyle>(editedObject->FillType.getValue());
switch(curtype)
{
case GeomFill_StretchStyle:
ui->fillType_stretch->setChecked(true);
break;
case GeomFill_CoonsStyle:
ui->fillType_coons->setChecked(true);
break;
case GeomFill_CurvedStyle:
ui->fillType_curved->setChecked(true);
break;
default:
break;
GeomFill_FillingStyle curtype =
static_cast<GeomFill_FillingStyle>(editedObject->FillType.getValue());
switch (curtype) {
case GeomFill_StretchStyle:
ui->fillType_stretch->setChecked(true);
break;
case GeomFill_CoonsStyle:
ui->fillType_coons->setChecked(true);
break;
case GeomFill_CurvedStyle:
ui->fillType_curved->setChecked(true);
break;
default:
break;
}
auto objects = editedObject->BoundaryList.getValues();
@@ -277,16 +298,17 @@ void GeomFillSurface::setEditedObject(Surface::GeomFillSurface* obj)
for (; it != objects.end() && jt != element.end(); ++it, ++jt, ++index) {
QListWidgetItem* item = new QListWidgetItem(ui->listWidget);
if (index < boolean.size()) {
if (boolean[index])
if (boolean[index]) {
item->setIcon(rotateLeft);
else
}
else {
item->setIcon(rotateRight);
}
}
ui->listWidget->addItem(item);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8((*it)->Label.getValue()),
QString::fromStdString(*jt));
QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8((*it)->Label.getValue()),
QString::fromStdString(*jt));
item->setText(text);
QList<QVariant> data;
@@ -299,7 +321,7 @@ void GeomFillSurface::setEditedObject(Surface::GeomFillSurface* obj)
attachDocument(Gui::Application::Instance->getDocument(doc));
}
void GeomFillSurface::changeEvent(QEvent *e)
void GeomFillSurface::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -358,29 +380,31 @@ bool GeomFillSurface::accept()
int count = ui->listWidget->count();
if (count > 4) {
QMessageBox::warning(this,
tr("Too many edges"),
tr("The tool requires two, three or four edges"));
tr("Too many edges"),
tr("The tool requires two, three or four edges"));
return false;
}
else if (count < 2) {
QMessageBox::warning(this,
tr("Too less edges"),
tr("The tool requires two, three or four edges"));
tr("Too less edges"),
tr("The tool requires two, three or four edges"));
return false;
}
if (editedObject->mustExecute())
if (editedObject->mustExecute()) {
editedObject->recomputeFeature();
}
if (!editedObject->isValid()) {
QMessageBox::warning(this, tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
QMessageBox::warning(this,
tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
return false;
}
this->vp->highlightReferences(false);
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
return true;
}
@@ -392,7 +416,7 @@ bool GeomFillSurface::reject()
Gui::Selection().rmvSelectionGate();
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
return true;
}
@@ -414,7 +438,8 @@ void GeomFillSurface::onFillTypeCurvedClicked()
void GeomFillSurface::changeFillType(GeomFill_FillingStyle fillType)
{
GeomFill_FillingStyle curtype = static_cast<GeomFill_FillingStyle>(editedObject->FillType.getValue());
GeomFill_FillingStyle curtype =
static_cast<GeomFill_FillingStyle>(editedObject->FillType.getValue());
if (curtype != fillType) {
checkOpenCommand();
editedObject->FillType.setValue(static_cast<long>(fillType));
@@ -449,8 +474,9 @@ void GeomFillSurface::onButtonEdgeRemoveToggled(bool checked)
void GeomFillSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (selectionMode == None)
if (selectionMode == None) {
return;
}
if (msg.Type == Gui::SelectionChanges::AddSelection) {
checkOpenCommand();
@@ -460,9 +486,9 @@ void GeomFillSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listWidget->addItem(item);
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
item->setText(text);
QList<QVariant> data;
@@ -488,7 +514,7 @@ void GeomFillSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pDocName);
data << QByteArray(msg.pObjectName);
data << QByteArray(msg.pSubName);
for (int i=0; i<ui->listWidget->count(); i++) {
for (int i = 0; i < ui->listWidget->count(); i++) {
QListWidgetItem* item = ui->listWidget->item(i);
if (item && item->data(Qt::UserRole) == data) {
row = i;
@@ -508,12 +534,13 @@ void GeomFillSurface::onSelectionChanged(const Gui::SelectionChanges& msg)
// remove the element of the bitset at position 'row'
const boost::dynamic_bitset<>& old_booleans = editedObject->ReversedList.getValues();
boost::dynamic_bitset<> new_booleans = old_booleans >> 1;
new_booleans.resize(objects.size()-1);
new_booleans.resize(objects.size() - 1);
// double-check in case 'old_booleans' is out of sync
if (new_booleans.size() < old_booleans.size()) {
for (int i=0; i<row; i++)
for (int i = 0; i < row; i++) {
new_booleans[i] = old_booleans[i];
}
}
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
@@ -556,12 +583,13 @@ void GeomFillSurface::onDeleteEdge()
// remove the element of the bitset at position 'row'
const boost::dynamic_bitset<>& old_booleans = editedObject->ReversedList.getValues();
boost::dynamic_bitset<> new_booleans = old_booleans >> 1;
new_booleans.resize(objects.size()-1);
new_booleans.resize(objects.size() - 1);
// double-check in case 'old_booleans' is out of sync
if (new_booleans.size() < old_booleans.size()) {
for (int i=0; i<row; i++)
for (int i = 0; i < row; i++) {
new_booleans[i] = old_booleans[i];
}
}
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
@@ -625,13 +653,15 @@ void GeomFillSurface::exitSelectionMode()
// ----------------------------------------------------------------------------
TaskGeomFillSurface::TaskGeomFillSurface(ViewProviderGeomFillSurface* vp, Surface::GeomFillSurface* obj)
TaskGeomFillSurface::TaskGeomFillSurface(ViewProviderGeomFillSurface* vp,
Surface::GeomFillSurface* obj)
{
widget = new GeomFillSurface(vp, obj);
widget->setWindowTitle(QObject::tr("Surface"));
taskbox = new Gui::TaskView::TaskBox(
Gui::BitmapFactory().pixmap("Surface_BSplineSurface"),
widget->windowTitle(), true, nullptr);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Surface_BSplineSurface"),
widget->windowTitle(),
true,
nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
@@ -656,6 +686,6 @@ bool TaskGeomFillSurface::reject()
return widget->reject();
}
}
}// namespace SurfaceGui
#include "moc_TaskGeomFillSurface.cpp"

View File

@@ -44,9 +44,10 @@ namespace SurfaceGui
class Ui_GeomFillSurface;
class ViewProviderGeomFillSurface : public PartGui::ViewProviderSpline
class ViewProviderGeomFillSurface: public PartGui::ViewProviderSpline
{
PROPERTY_HEADER_WITH_OVERRIDE(SurfaceGui::ViewProviderGeomFillSurface);
public:
void setupContextMenu(QMenu*, QObject*, const char*) override;
bool setEdit(int ModNum) override;
@@ -55,15 +56,18 @@ public:
void highlightReferences(bool on);
};
class GeomFillSurface : public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
class GeomFillSurface: public QWidget, public Gui::SelectionObserver, public Gui::DocumentObserver
{
Q_OBJECT
protected:
class EdgeSelection;
enum SelectionMode { None, Append, Remove };
enum SelectionMode
{
None,
Append,
Remove
};
SelectionMode selectionMode;
Surface::GeomFillSurface* editedObject;
bool checkCommand;
@@ -71,7 +75,7 @@ protected:
private:
Ui_GeomFillSurface* ui;
ViewProviderGeomFillSurface* vp;
Gui::ButtonGroup *buttonGroup;
Gui::ButtonGroup* buttonGroup;
public:
GeomFillSurface(ViewProviderGeomFillSurface* vp, Surface::GeomFillSurface* obj);
@@ -84,7 +88,7 @@ public:
void setEditedObject(Surface::GeomFillSurface* obj);
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
/** Notifies on undo */
void slotUndoDocument(const Gui::Document& Doc) override;
@@ -111,7 +115,7 @@ private:
void exitSelectionMode();
};
class TaskGeomFillSurface : public Gui::TaskView::TaskDialog
class TaskGeomFillSurface: public Gui::TaskView::TaskDialog
{
Q_OBJECT
@@ -125,13 +129,15 @@ public:
bool reject() override;
QDialogButtonBox::StandardButtons getStandardButtons() const override
{ return QDialogButtonBox::Ok | QDialogButtonBox::Cancel; }
{
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
}
private:
GeomFillSurface* widget;
Gui::TaskView::TaskBox* taskbox;
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_TASKGEOMFILLSURFACE_H
#endif// SURFACEGUI_TASKGEOMFILLSURFACE_H

View File

@@ -22,13 +22,13 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
# include <QMenu>
# include <QMessageBox>
# include <QTimer>
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <QTimer>
# include <TopExp.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#endif
#include <App/Document.h>
@@ -48,7 +48,8 @@ using namespace SurfaceGui;
PROPERTY_SOURCE(SurfaceGui::ViewProviderSections, PartGui::ViewProviderSpline)
namespace SurfaceGui {
namespace SurfaceGui
{
void ViewProviderSections::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
@@ -60,20 +61,21 @@ void ViewProviderSections::setupContextMenu(QMenu* menu, QObject* receiver, cons
bool ViewProviderSections::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
if (ModNum == ViewProvider::Default) {
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Surface::Sections* obj = static_cast<Surface::Sections*>(this->getObject());
Surface::Sections* obj = static_cast<Surface::Sections*>(this->getObject());
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
// start the edit dialog
if (dlg) {
TaskSections* tDlg = qobject_cast<TaskSections*>(dlg);
if (tDlg)
if (tDlg) {
tDlg->setEditedObject(obj);
}
Gui::Control().showDialog(dlg);
}
else {
@@ -108,72 +110,78 @@ void ViewProviderSections::highlightReferences(ShapeType type, const References&
Part::Feature* base = dynamic_cast<Part::Feature*>(it.first);
if (base) {
PartGui::ViewProviderPartExt* svp = dynamic_cast<PartGui::ViewProviderPartExt*>(
Gui::Application::Instance->getViewProvider(base));
Gui::Application::Instance->getViewProvider(base));
if (svp) {
switch (type) {
case ViewProviderSections::Vertex:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_VERTEX, vMap);
colors.resize(vMap.Extent(), svp->PointColor.getValue());
case ViewProviderSections::Vertex:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_VERTEX, vMap);
colors.resize(vMap.Extent(), svp->PointColor.getValue());
for (const auto& jt : it.second) {
// check again that the index is in range because it's possible that the
// sub-names are invalid
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(6)) - 1);
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
for (const auto& jt : it.second) {
// check again that the index is in range because it's possible that
// the sub-names are invalid
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(6)) - 1);
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
svp->setHighlightedPoints(colors);
}
svp->setHighlightedPoints(colors);
}
else {
svp->unsetHighlightedPoints();
}
break;
case ViewProviderSections::Edge:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape eMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
colors.resize(eMap.Extent(), svp->LineColor.getValue());
for (const auto& jt : it.second) {
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that the
// sub-names are invalid
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
else {
svp->unsetHighlightedPoints();
}
break;
case ViewProviderSections::Edge:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape eMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
colors.resize(eMap.Extent(), svp->LineColor.getValue());
svp->setHighlightedEdges(colors);
}
else {
svp->unsetHighlightedEdges();
}
break;
case ViewProviderSections::Face:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape fMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
colors.resize(fMap.Extent(), svp->ShapeColor.getValue());
for (const auto& jt : it.second) {
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that
// the sub-names are invalid
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
for (const auto& jt : it.second) {
std::size_t idx = static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that the
// sub-names are invalid
if (idx < colors.size())
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
svp->setHighlightedEdges(colors);
}
else {
svp->unsetHighlightedEdges();
}
break;
case ViewProviderSections::Face:
if (on) {
std::vector<App::Color> colors;
TopTools_IndexedMapOfShape fMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_FACE, fMap);
colors.resize(fMap.Extent(), svp->ShapeColor.getValue());
svp->setHighlightedFaces(colors);
}
else {
svp->unsetHighlightedFaces();
}
break;
for (const auto& jt : it.second) {
std::size_t idx =
static_cast<std::size_t>(std::stoi(jt.substr(4)) - 1);
// check again that the index is in range because it's possible that
// the sub-names are invalid
if (idx < colors.size()) {
colors[idx] = App::Color(1.0, 0.0, 1.0);// magenta
}
}
svp->setHighlightedFaces(colors);
}
else {
svp->unsetHighlightedFaces();
}
break;
}
}
}
@@ -182,40 +190,42 @@ void ViewProviderSections::highlightReferences(ShapeType type, const References&
// ----------------------------------------------------------------------------
class SectionsPanel::ShapeSelection : public Gui::SelectionFilterGate
class SectionsPanel::ShapeSelection: public Gui::SelectionFilterGate
{
public:
ShapeSelection(SectionsPanel::SelectionMode& mode, Surface::Sections* editedObject)
: Gui::SelectionFilterGate(nullPointer())
, mode(mode)
, editedObject(editedObject)
{
}
{}
~ShapeSelection() override
{
mode = SectionsPanel::None;
}
/**
* Allow the user to pick only edges.
*/
* Allow the user to pick only edges.
*/
bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override
{
// don't allow references to itself
if (pObj == editedObject)
if (pObj == editedObject) {
return false;
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
}
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId())) {
return false;
}
if (!sSubName || sSubName[0] == '\0')
if (!sSubName || sSubName[0] == '\0') {
return false;
}
switch (mode) {
case SectionsPanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case SectionsPanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
case SectionsPanel::AppendEdge:
return allowEdge(true, pObj, sSubName);
case SectionsPanel::RemoveEdge:
return allowEdge(false, pObj, sSubName);
default:
return false;
}
}
@@ -223,15 +233,17 @@ private:
bool allowEdge(bool appendEdges, App::DocumentObject* pObj, const char* sSubName)
{
std::string element(sSubName);
if (element.substr(0,4) != "Edge")
if (element.substr(0, 4) != "Edge") {
return false;
}
auto links = editedObject->NSections.getSubListValues();
for (const auto& it : links) {
if (it.first == pObj) {
for (const auto& jt : it.second) {
if (jt == sSubName)
if (jt == sSubName) {
return !appendEdges;
}
}
}
}
@@ -246,7 +258,8 @@ private:
// ----------------------------------------------------------------------------
SectionsPanel::SectionsPanel(ViewProviderSections* vp, Surface::Sections* obj) : ui(new Ui_Sections())
SectionsPanel::SectionsPanel(ViewProviderSections* vp, Surface::Sections* obj)
: ui(new Ui_Sections())
{
ui->setupUi(this);
setupConnections();
@@ -270,7 +283,10 @@ SectionsPanel::SectionsPanel(ViewProviderSections* vp, Surface::Sections* obj) :
connect(action, &QAction::triggered, this, &SectionsPanel::onDeleteEdge);
ui->listSections->setContextMenuPolicy(Qt::ActionsContextMenu);
connect(ui->listSections->model(), &QAbstractItemModel::rowsMoved, this, &SectionsPanel::onIndexesMoved);
connect(ui->listSections->model(),
&QAbstractItemModel::rowsMoved,
this,
&SectionsPanel::onIndexesMoved);
}
/*
@@ -280,11 +296,11 @@ SectionsPanel::~SectionsPanel() = default;
void SectionsPanel::setupConnections()
{
connect(ui->buttonEdgeAdd, &QToolButton::toggled,
this, &SectionsPanel::onButtonEdgeAddToggled);
connect(ui->buttonEdgeRemove, &QToolButton::toggled,
this, &SectionsPanel::onButtonEdgeRemoveToggled);
connect(ui->buttonEdgeAdd, &QToolButton::toggled, this, &SectionsPanel::onButtonEdgeAddToggled);
connect(ui->buttonEdgeRemove,
&QToolButton::toggled,
this,
&SectionsPanel::onButtonEdgeRemoveToggled);
}
// stores object pointer, its old fill type and adjusts radio buttons according to it.
@@ -298,16 +314,15 @@ void SectionsPanel::setEditedObject(Surface::Sections* fea)
auto count = objects.size();
App::Document* doc = editedObject->getDocument();
for (std::size_t i=0; i<count; i++) {
for (std::size_t i = 0; i < count; i++) {
App::DocumentObject* obj = objects[i];
std::string edge = edges[i];
QListWidgetItem* item = new QListWidgetItem(ui->listSections);
ui->listSections->addItem(item);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
QString text = QString::fromLatin1("%1.%2").arg(QString::fromUtf8(obj->Label.getValue()),
QString::fromStdString(edge));
item->setText(text);
// The user data field of a list widget item
@@ -326,7 +341,7 @@ void SectionsPanel::setEditedObject(Surface::Sections* fea)
attachDocument(Gui::Application::Instance->getDocument(doc));
}
void SectionsPanel::changeEvent(QEvent *e)
void SectionsPanel::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -342,7 +357,8 @@ void SectionsPanel::open()
// highlight the boundary edges
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), true);
editedObject->NSections.getSubListValues(),
true);
Gui::Selection().clearSelection();
}
@@ -378,7 +394,8 @@ void SectionsPanel::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj
// referenced part objects. The dialog will be deleted later.
if (this->vp == &Obj) {
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), false);
editedObject->NSections.getSubListValues(),
false);
}
}
@@ -387,16 +404,19 @@ bool SectionsPanel::accept()
selectionMode = None;
Gui::Selection().rmvSelectionGate();
if (editedObject->mustExecute())
if (editedObject->mustExecute()) {
editedObject->recomputeFeature();
}
if (!editedObject->isValid()) {
QMessageBox::warning(this, tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
QMessageBox::warning(this,
tr("Invalid object"),
QString::fromLatin1(editedObject->getStatusString()));
return false;
}
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), false);
editedObject->NSections.getSubListValues(),
false);
return true;
}
@@ -404,7 +424,8 @@ bool SectionsPanel::accept()
bool SectionsPanel::reject()
{
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), false);
editedObject->NSections.getSubListValues(),
false);
selectionMode = None;
Gui::Selection().rmvSelectionGate();
@@ -438,8 +459,9 @@ void SectionsPanel::onButtonEdgeRemoveToggled(bool checked)
void SectionsPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (selectionMode == None)
if (selectionMode == None) {
return;
}
if (msg.Type == Gui::SelectionChanges::AddSelection) {
checkOpenCommand();
@@ -448,9 +470,9 @@ void SectionsPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listSections->addItem(item);
Gui::SelectionObject sel(msg);
QString text = QString::fromLatin1("%1.%2")
.arg(QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
QString text = QString::fromLatin1("%1.%2").arg(
QString::fromUtf8(sel.getObject()->Label.getValue()),
QString::fromLatin1(msg.pSubName));
item->setText(text);
QList<QVariant> data;
@@ -469,10 +491,10 @@ void SectionsPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pSubName);
// only the three first elements must match
for (int i=0; i<ui->listSections->count(); i++) {
for (int i = 0; i < ui->listSections->count(); i++) {
QListWidgetItem* item = ui->listSections->item(i);
QList<QVariant> userdata = item->data(Qt::UserRole).toList();
if (userdata.mid(0,3) == data) {
if (userdata.mid(0, 3) == data) {
ui->listSections->takeItem(i);
delete item;
break;
@@ -509,8 +531,9 @@ void SectionsPanel::onDeleteEdge()
void SectionsPanel::onIndexesMoved()
{
QAbstractItemModel* model = qobject_cast<QAbstractItemModel*>(sender());
if (!model)
if (!model) {
return;
}
std::vector<App::DocumentObject*> objects;
std::vector<std::string> element;
@@ -542,13 +565,15 @@ void SectionsPanel::appendCurve(App::DocumentObject* obj, const std::string& sub
editedObject->NSections.setValues(objects, element);
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), true);
editedObject->NSections.getSubListValues(),
true);
}
void SectionsPanel::removeCurve(App::DocumentObject* obj, const std::string& subname)
{
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), false);
editedObject->NSections.getSubListValues(),
false);
auto objects = editedObject->NSections.getValues();
auto element = editedObject->NSections.getSubValues();
@@ -564,8 +589,8 @@ void SectionsPanel::removeCurve(App::DocumentObject* obj, const std::string& sub
}
}
this->vp->highlightReferences(ViewProviderSections::Edge,
editedObject->NSections.getSubListValues(), true);
editedObject->NSections.getSubListValues(),
true);
}
void SectionsPanel::exitSelectionMode()
@@ -581,9 +606,11 @@ TaskSections::TaskSections(ViewProviderSections* vp, Surface::Sections* obj)
{
// first task box
widget1 = new SectionsPanel(vp, obj);
Gui::TaskView::TaskBox* taskbox1 = new Gui::TaskView::TaskBox(
Gui::BitmapFactory().pixmap("Surface_Sections"),
widget1->windowTitle(), true, nullptr);
Gui::TaskView::TaskBox* taskbox1 =
new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Surface_Sections"),
widget1->windowTitle(),
true,
nullptr);
taskbox1->groupLayout()->addWidget(widget1);
Content.push_back(taskbox1);
}
@@ -603,7 +630,7 @@ bool TaskSections::accept()
bool ok = widget1->accept();
if (ok) {
Gui::Command::commitCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
}
@@ -615,13 +642,13 @@ bool TaskSections::reject()
bool ok = widget1->reject();
if (ok) {
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
Gui::Command::updateActive();
}
return ok;
}
}
}// namespace SurfaceGui
#include "moc_TaskSections.cpp"

View File

@@ -44,13 +44,18 @@ namespace SurfaceGui
class Ui_Sections;
class ViewProviderSections : public PartGui::ViewProviderSpline
class ViewProviderSections: public PartGui::ViewProviderSpline
{
PROPERTY_HEADER_WITH_OVERRIDE(SurfaceGui::ViewProviderSections);
using References = std::vector<App::PropertyLinkSubList::SubSet>;
public:
enum ShapeType {Vertex, Edge, Face};
enum ShapeType
{
Vertex,
Edge,
Face
};
void setupContextMenu(QMenu*, QObject*, const char*) override;
bool setEdit(int ModNum) override;
void unsetEdit(int ModNum) override;
@@ -58,15 +63,18 @@ public:
void highlightReferences(ShapeType type, const References& refs, bool on);
};
class SectionsPanel : public QWidget,
public Gui::SelectionObserver,
public Gui::DocumentObserver
class SectionsPanel: public QWidget, public Gui::SelectionObserver, public Gui::DocumentObserver
{
Q_OBJECT
protected:
class ShapeSelection;
enum SelectionMode { None, AppendEdge, RemoveEdge };
enum SelectionMode
{
None,
AppendEdge,
RemoveEdge
};
SelectionMode selectionMode;
Surface::Sections* editedObject;
bool checkCommand;
@@ -74,7 +82,7 @@ protected:
private:
std::unique_ptr<Ui_Sections> ui;
ViewProviderSections* vp;
Gui::ButtonGroup *buttonGroup;
Gui::ButtonGroup* buttonGroup;
public:
SectionsPanel(ViewProviderSections* vp, Surface::Sections* obj);
@@ -87,7 +95,7 @@ public:
void setEditedObject(Surface::Sections* obj);
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
/** Notifies on undo */
void slotUndoDocument(const Gui::Document& Doc) override;
@@ -110,7 +118,7 @@ private:
void exitSelectionMode();
};
class TaskSections : public Gui::TaskView::TaskDialog
class TaskSections: public Gui::TaskView::TaskDialog
{
Q_OBJECT
@@ -124,12 +132,14 @@ public:
bool reject() override;
QDialogButtonBox::StandardButtons getStandardButtons() const override
{ return QDialogButtonBox::Ok | QDialogButtonBox::Cancel; }
{
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
}
private:
SectionsPanel* widget1;
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_TASKSECTIONS_H
#endif// SURFACEGUI_TASKSECTIONS_H

View File

@@ -31,11 +31,12 @@ using namespace SurfaceGui;
PROPERTY_SOURCE(SurfaceGui::ViewProviderExtend, PartGui::ViewProviderSpline)
namespace SurfaceGui {
namespace SurfaceGui
{
QIcon ViewProviderExtend::getIcon() const
{
return Gui::BitmapFactory().pixmap("Surface_ExtendFace");
}
} //namespace SurfaceGui
}// namespace SurfaceGui

View File

@@ -29,7 +29,7 @@
namespace SurfaceGui
{
class ViewProviderExtend : public PartGui::ViewProviderSpline
class ViewProviderExtend: public PartGui::ViewProviderSpline
{
PROPERTY_HEADER_WITH_OVERRIDE(SurfaceGui::ViewProviderExtend);
@@ -37,6 +37,6 @@ public:
QIcon getIcon() const override;
};
} //namespace SurfaceGui
}// namespace SurfaceGui
#endif // SURFACEGUI_VIEWPROVIDEREXTEND_H
#endif// SURFACEGUI_VIEWPROVIDEREXTEND_H

View File

@@ -38,12 +38,12 @@ Workbench::Workbench() = default;
Workbench::~Workbench() = default;
Gui::MenuItem *Workbench::setupMenuBar() const
Gui::MenuItem* Workbench::setupMenuBar() const
{
Gui::MenuItem *root = StdWorkbench::setupMenuBar();
Gui::MenuItem *item = root->findItem("&Windows");
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
Gui::MenuItem* item = root->findItem("&Windows");
Gui::MenuItem *surface = new Gui::MenuItem;
Gui::MenuItem* surface = new Gui::MenuItem;
root->insertItem(item, surface);
surface->setCommand("Surface");
*surface << "Surface_Filling"
@@ -53,17 +53,17 @@ Gui::MenuItem *Workbench::setupMenuBar() const
<< "Surface_CurveOnMesh"
<< "Surface_BlendCurve";
/*
*surface << "Surface_Cut";
*/
*surface << "Surface_Cut";
*/
return root;
}
Gui::ToolBarItem *Workbench::setupToolBars() const
Gui::ToolBarItem* Workbench::setupToolBars() const
{
Gui::ToolBarItem *root = StdWorkbench::setupToolBars();
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
Gui::ToolBarItem *surface = new Gui::ToolBarItem(root);
Gui::ToolBarItem* surface = new Gui::ToolBarItem(root);
surface->setCommand("Surface");
*surface << "Surface_Filling"
<< "Surface_GeomFillSurface"
@@ -72,8 +72,8 @@ Gui::ToolBarItem *Workbench::setupToolBars() const
<< "Surface_CurveOnMesh"
<< "Surface_BlendCurve";
/*
*surface << "Surface_Cut";
*/
*surface << "Surface_Cut";
*/
return root;
}

View File

@@ -26,9 +26,10 @@
#include <Gui/Workbench.h>
namespace SurfaceGui {
namespace SurfaceGui
{
class Workbench : public Gui::StdWorkbench
class Workbench: public Gui::StdWorkbench
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
@@ -41,7 +42,7 @@ protected:
Gui::ToolBarItem* setupToolBars() const override;
};
} // namespace SurfaceGui
}// namespace SurfaceGui
#endif // Surface_WORKBENCH_H
#endif// Surface_WORKBENCH_H

View File

@@ -32,9 +32,9 @@ import FreeCADGui as Gui
class SurfaceWorkbench(Gui.Workbench):
"""Surface workbench object."""
Icon = os.path.join(App.getResourceDir(),
"Mod", "Surface",
"Resources", "icons", "Surface_Workbench.svg")
Icon = os.path.join(
App.getResourceDir(), "Mod", "Surface", "Resources", "icons", "Surface_Workbench.svg"
)
MenuText = "Surface"
ToolTip = "Surface workbench: Create and edit complex surfaces"

View File

@@ -29,19 +29,19 @@
// Surface
#ifndef SurfaceExport
#ifdef Surface_EXPORTS
# define SurfaceExport FREECAD_DECL_EXPORT
#define SurfaceExport FREECAD_DECL_EXPORT
#else
# define SurfaceExport FREECAD_DECL_IMPORT
#define SurfaceExport FREECAD_DECL_IMPORT
#endif
#endif
// SurfaceGui
#ifndef SurfaceGuiExport
#ifdef SurfaceGui_EXPORTS
# define SurfaceGuiExport FREECAD_DECL_EXPORT
#define SurfaceGuiExport FREECAD_DECL_EXPORT
#else
# define SurfaceGuiExport FREECAD_DECL_IMPORT
#define SurfaceGuiExport FREECAD_DECL_IMPORT
#endif
#endif
#endif //SURFACE_GLOBAL_H
#endif// SURFACE_GLOBAL_H

View File

@@ -51,7 +51,7 @@ class TestBlendCurve(unittest.TestCase):
# Create C0 BlendPoint at origin
b1 = Surface.BlendPoint()
# Create G1 BlendPoint
b2 = Surface.BlendPoint([vec(10,3,6), vec(2,5,6)])
b2 = Surface.BlendPoint([vec(10, 3, 6), vec(2, 5, 6)])
# BlendCurve between the two BlendPoints
bc = Surface.BlendCurve(b1, b2)
# Compute the interpolating BezierCurve
@@ -60,7 +60,7 @@ class TestBlendCurve(unittest.TestCase):
# Create G2 BlendPoint at the end of previous BlendCurve
b1 = Surface.BlendPoint(curve1.toShape(), 1, 2)
# Create G1 BlendPoint
b2 = Surface.BlendPoint([vec(5,6,2), vec(2,5,6)])
b2 = Surface.BlendPoint([vec(5, 6, 2), vec(2, 5, 6)])
bc = Surface.BlendCurve(b1, b2)
# Compute the interpolating BezierCurve