diff --git a/src/Mod/Surface/App/AppSurface.cpp b/src/Mod/Surface/App/AppSurface.cpp
index 0c03fc086e..d9e094487c 100644
--- a/src/Mod/Surface/App/AppSurface.cpp
+++ b/src/Mod/Surface/App/AppSurface.cpp
@@ -32,6 +32,7 @@
#include "FeatureSewing.h"
#include "FeatureCut.h"
#include "FeatureGeomFillSurface.h"
+#include "FeatureExtend.h"
#include
#include
@@ -78,6 +79,7 @@ PyMOD_INIT_FUNC(Surface)
Surface::Sewing ::init();
Surface::Cut ::init();
Surface::GeomFillSurface ::init();
+ Surface::Extend ::init();
PyMOD_Return(mod);
}
diff --git a/src/Mod/Surface/App/CMakeLists.txt b/src/Mod/Surface/App/CMakeLists.txt
index dbe80b3b64..2d7371d99c 100644
--- a/src/Mod/Surface/App/CMakeLists.txt
+++ b/src/Mod/Surface/App/CMakeLists.txt
@@ -21,6 +21,8 @@ SET(Surface_SRCS
AppSurface.cpp
PreCompiled.cpp
PreCompiled.h
+ FeatureExtend.cpp
+ FeatureExtend.h
FeatureGeomFillSurface.cpp
FeatureGeomFillSurface.h
FeatureFilling.cpp
diff --git a/src/Mod/Surface/App/FeatureExtend.cpp b/src/Mod/Surface/App/FeatureExtend.cpp
new file mode 100644
index 0000000000..e20d46c3ab
--- /dev/null
+++ b/src/Mod/Surface/App/FeatureExtend.cpp
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * Copyright (c) 2017 Werner Mayer *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+#include "PreCompiled.h"
+#ifndef _PreComp_
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#include "FeatureExtend.h"
+#include
+#include
+
+using namespace Surface;
+
+const App::PropertyIntegerConstraint::Constraints SampleRange = {2,INT_MAX,1};
+const App::PropertyFloatConstraint::Constraints ToleranceRange = {0.0,10.0,0.01};
+const App::PropertyFloatConstraint::Constraints ExtendRange = {-0.5,10.0,0.01};
+PROPERTY_SOURCE(Surface::Extend, Part::Spline)
+
+Extend::Extend()
+{
+ ADD_PROPERTY(Face,(0));
+ Face.setScope(App::LinkScope::Global);
+ ADD_PROPERTY(Tolerance, (0.1));
+ Tolerance.setConstraints(&ToleranceRange);
+ ADD_PROPERTY(ExtendU, (0.05));
+ ExtendU.setConstraints(&ExtendRange);
+ ADD_PROPERTY(ExtendV, (0.05));
+ ExtendV.setConstraints(&ExtendRange);
+ ADD_PROPERTY(SampleU, (32));
+ SampleU.setConstraints(&SampleRange);
+ ADD_PROPERTY(SampleV, (32));
+ SampleV.setConstraints(&SampleRange);
+}
+
+Extend::~Extend()
+{
+}
+
+short Extend::mustExecute() const
+{
+ if (Face.isTouched())
+ return 1;
+ if (ExtendU.isTouched())
+ return 1;
+ if (ExtendV.isTouched())
+ return 1;
+ return 0;
+}
+
+App::DocumentObjectExecReturn *Extend::execute(void)
+{
+ App::DocumentObject* part = Face.getValue();
+ if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
+ return new App::DocumentObjectExecReturn("No shape linked.");
+ const auto& faces = Face.getSubValues();
+ if (faces.size() != 1)
+ return new App::DocumentObjectExecReturn("Not exactly one sub-shape linked.");
+
+ TopoDS_Shape shape = static_cast(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);
+ double u1 = adapt.FirstUParameter();
+ double u2 = adapt.LastUParameter();
+ double v1 = adapt.FirstVParameter();
+ double v2 = adapt.LastVParameter();
+
+ double ur = u2 - u1;
+ double vr = v2 - v1;
+ double eu1 = u1 - ur*ExtendU.getValue();
+ double eu2 = u2 + ur*ExtendU.getValue();
+ double ev1 = v1 - vr*ExtendV.getValue();
+ double ev2 = v2 + vr*ExtendV.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= 0x060502
+ , Precision::Confusion()
+#endif
+ );
+
+ Shape.setValue(mkFace.Face());
+
+ return StdReturn;
+}
diff --git a/src/Mod/Surface/App/FeatureExtend.h b/src/Mod/Surface/App/FeatureExtend.h
new file mode 100644
index 0000000000..ab46a739d4
--- /dev/null
+++ b/src/Mod/Surface/App/FeatureExtend.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (c) 2017 Werner Mayer *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ***************************************************************************/
+
+#ifndef SURFACE_FEATUREEXTEND_H
+#define SURFACE_FEATUREEXTEND_H
+
+#include
+#include
+#include
+#include
+
+namespace Surface
+{
+
+class SurfaceExport Extend : public Part::Spline
+{
+ PROPERTY_HEADER(Surface::Extend);
+
+public:
+ Extend();
+ ~Extend();
+
+ App::PropertyLinkSub Face;
+ App::PropertyFloatConstraint Tolerance;
+ App::PropertyFloatConstraint ExtendU;
+ App::PropertyFloatConstraint ExtendV;
+ App::PropertyIntegerConstraint SampleU;
+ App::PropertyIntegerConstraint SampleV;
+
+ // recalculate the feature
+ App::DocumentObjectExecReturn *execute(void);
+ short mustExecute() const;
+};
+
+}//Namespace Surface
+
+#endif
diff --git a/src/Mod/Surface/Gui/Command.cpp b/src/Mod/Surface/Gui/Command.cpp
index 49119142b2..28740cebb0 100644
--- a/src/Mod/Surface/Gui/Command.cpp
+++ b/src/Mod/Surface/Gui/Command.cpp
@@ -52,6 +52,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -219,6 +220,48 @@ bool CmdSurfaceCurveOnMesh::isActive(void)
return false;
}
+DEF_STD_CMD_A(CmdSurfaceExtendFace)
+
+CmdSurfaceExtendFace::CmdSurfaceExtendFace()
+ : Command("Surface_ExtendFace")
+{
+ sAppModule = "Surface";
+ sGroup = QT_TR_NOOP("Surface");
+ sMenuText = QT_TR_NOOP("Extend face");
+ sToolTipText = QT_TR_NOOP("Extend face");
+ sWhatsThis = "Surface_ExtendFace";
+ sStatusTip = sToolTipText;
+}
+
+void CmdSurfaceExtendFace::activated(int)
+{
+ Gui::SelectionFilter faceFilter("SELECT Part::Feature SUBELEMENT Face COUNT 1");
+ if (faceFilter.match()) {
+ App::DocumentObject* obj;
+ obj = faceFilter.Result[0][0].getObject();
+ const std::vector &sub = faceFilter.Result[0][0].getSubNames();
+ if (sub.size() == 1) {
+ openCommand("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());
+ updateActive();
+ commitCommand();
+ }
+ }
+ else {
+ QMessageBox::warning(Gui::getMainWindow(),
+ qApp->translate("Surface_ExtendFace", "Wrong selection"),
+ qApp->translate("Surface_ExtendFace", "Select a single face"));
+ }
+}
+
+bool CmdSurfaceExtendFace::isActive(void)
+{
+ return Gui::Selection().countObjectsOfType(Part::Feature::getClassTypeId()) == 1;
+}
+
void CreateSurfaceCommands(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
@@ -227,4 +270,5 @@ void CreateSurfaceCommands(void)
rcCmdMgr.addCommand(new CmdSurfaceFilling());
rcCmdMgr.addCommand(new CmdSurfaceGeomFillSurface());
rcCmdMgr.addCommand(new CmdSurfaceCurveOnMesh());
+ rcCmdMgr.addCommand(new CmdSurfaceExtendFace());
}
diff --git a/src/Mod/Surface/Gui/Workbench.cpp b/src/Mod/Surface/Gui/Workbench.cpp
index 1e20e8be09..85db1ea5e9 100644
--- a/src/Mod/Surface/Gui/Workbench.cpp
+++ b/src/Mod/Surface/Gui/Workbench.cpp
@@ -53,6 +53,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
root->insertItem( item, surface );
surface->setCommand("Surface");
*surface << "Surface_CurveOnMesh"
+ << "Surface_ExtendFace"
<< "Surface_Filling"
<< "Surface_GeomFillSurface";
/* *surface << "Surface_Filling";