diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6513b1773..8e7c5d8c9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -170,6 +170,7 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X)
# -------------------------------- Python --------------------------------
+ set(Python_ADDITIONAL_VERSIONS "2.3" "2.4" "2.5" "2.6" "2.7" "2.8" "2.9")
find_package(PythonLibs REQUIRED)
find_package(PythonInterp REQUIRED)
diff --git a/configure.ac b/configure.ac
index 4f94456af..dfdbf8524 100644
--- a/configure.ac
+++ b/configure.ac
@@ -193,7 +193,7 @@ fc_py_ac_save_ldflags=$LDFLAGS
fc_py_ac_save_libs=$LIBS
CPPFLAGS="$CPPFLAGS -I$fc_py_incs"
LDFLAGS="$LDFLAGS -L$fc_py_libs"
-LIBS="-lpython$PYTHON_VERSION"
+LIBS="-lpython$PYTHON_VERSION -lpthread -ldl -lutil -lm"
dnl Small test program that only works with Python 2.5 and higher
fc_cv_lib_py_avail=no
diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp
index c0ac0f154..a48fac413 100644
--- a/src/App/DocumentObject.cpp
+++ b/src/App/DocumentObject.cpp
@@ -109,11 +109,11 @@ const char* DocumentObject::getStatusString(void) const
const char *DocumentObject::getNameInDocument(void) const
{
- // Note: It can happen that we query the internal name of an object even if it is not
- // part of a document (anymore). This is the case e.g. if we have a reference in Python
- // to an object that has been removed from the document. In this case we should rather
+ // Note: It can happen that we query the internal name of an object even if it is not
+ // part of a document (anymore). This is the case e.g. if we have a reference in Python
+ // to an object that has been removed from the document. In this case we should rather
// return 0.
- //assert(pcNameInDocument);
+ //assert(pcNameInDocument);
if (!pcNameInDocument) return 0;
return pcNameInDocument->c_str();
}
@@ -171,6 +171,7 @@ App::Document *DocumentObject::getDocument(void) const
void DocumentObject::setDocument(App::Document* doc)
{
_pDoc=doc;
+ onSettingDocument();
}
void DocumentObject::onBeforeChange(const Property* prop)
diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h
index 70a91ffe1..78616408c 100644
--- a/src/App/DocumentObject.h
+++ b/src/App/DocumentObject.h
@@ -102,7 +102,7 @@ public:
/// returns true if this objects is currently restoring from file
bool isRestoring() const {return StatusBits.test(4);}
/// recompute only this object
- App::DocumentObjectExecReturn *recompute(void);
+ virtual App::DocumentObjectExecReturn *recompute(void);
/// return the status bits
unsigned long getStatus() const {return StatusBits.to_ulong();}
//@}
@@ -183,6 +183,8 @@ protected:
virtual void onDocumentRestored() {}
/// get called after duplicating an object
virtual void onFinishDuplicating() {}
+ /// get called after setting the document
+ virtual void onSettingDocument() {}
/// python object of this class and all descendend
protected: // attributes
diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h
index b6aa5349d..36444c667 100644
--- a/src/Base/Matrix.h
+++ b/src/Base/Matrix.h
@@ -134,9 +134,11 @@ public:
/// transform (move,scale,rotate) around a point
void transform (const Vector3f& rclVct, const Matrix4D& rclMtrx);
void transform (const Vector3d& rclVct, const Matrix4D& rclMtrx);
+ /// Matrix is expected to have a 3x3 rotation submatrix.
void inverse (void);
- /// if matrix is orthogonal a special way of getting the inverse is used
+ /// Matrix is expected to have a 3x3 rotation submatrix.
void inverseOrthogonal(void);
+ /// Arbitrary, non-singular matrix
void inverseGauss (void);
void transpose (void);
//@}
diff --git a/src/Base/MatrixPyImp.cpp b/src/Base/MatrixPyImp.cpp
index b7d594f54..5c7eda29c 100644
--- a/src/Base/MatrixPyImp.cpp
+++ b/src/Base/MatrixPyImp.cpp
@@ -342,7 +342,7 @@ PyObject* MatrixPy::invert(PyObject * args)
PY_TRY {
if (getMatrixPtr()->determinant() > DBL_EPSILON)
- getMatrixPtr()->inverse();
+ getMatrixPtr()->inverseGauss();
else {
PyErr_SetString(PyExc_Exception, "Cannot invert singular matrix");
return 0;
@@ -361,7 +361,7 @@ PyObject* MatrixPy::inverse(PyObject * args)
PY_TRY {
if (getMatrixPtr()->determinant() > DBL_EPSILON) {
Base::Matrix4D m = *getMatrixPtr();
- m.inverse();
+ m.inverseGauss();
return new MatrixPy(m);
}
else {
diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp
index b969ffb98..53dec5681 100644
--- a/src/Gui/Application.cpp
+++ b/src/Gui/Application.cpp
@@ -1403,7 +1403,6 @@ static void init_resources()
void Application::initApplication(void)
{
try {
- Base::Interpreter().replaceStdOutput();
initTypes();
new Base::ScriptProducer( "FreeCADGuiInit", FreeCADGuiInit );
init_resources();
diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp
index 288bc3df2..03407c52d 100644
--- a/src/Main/MainGui.cpp
+++ b/src/Main/MainGui.cpp
@@ -225,6 +225,7 @@ int main( int argc, char ** argv )
// Inits the Application
App::Application::init(argc,argv);
Gui::Application::initApplication();
+ Base::Interpreter().replaceStdOutput();
}
catch (const Base::UnknownProgramOption& e) {
QApplication app(argc,argv);
diff --git a/src/Mod/Part/App/ParabolaPy.xml b/src/Mod/Part/App/ParabolaPy.xml
index 068a227f9..d08b5274e 100644
--- a/src/Mod/Part/App/ParabolaPy.xml
+++ b/src/Mod/Part/App/ParabolaPy.xml
@@ -14,6 +14,14 @@
Describes a parabola in 3D space
+
+
+
+ compute(p1,p2,p3)
+ The three points must lie on a plane parallel to xy plane and must not be collinear
+
+
+
Returns 1. (which is the eccentricity of any parabola).
diff --git a/src/Mod/Part/App/ParabolaPyImp.cpp b/src/Mod/Part/App/ParabolaPyImp.cpp
index 7782c4254..191df05f4 100644
--- a/src/Mod/Part/App/ParabolaPyImp.cpp
+++ b/src/Mod/Part/App/ParabolaPyImp.cpp
@@ -60,6 +60,51 @@ int ParabolaPy::PyInit(PyObject* args, PyObject* /*kwd*/)
return -1;
}
+PyObject* ParabolaPy::compute(PyObject *args)
+{
+ PyObject *p1, *p2, *p3;
+ if (!PyArg_ParseTuple(args, "O!O!O!",
+ &Base::VectorPy::Type,&p1,
+ &Base::VectorPy::Type,&p2,
+ &Base::VectorPy::Type,&p3))
+ return 0;
+ Base::Vector3d v1 = Py::Vector(p1,false).toVector();
+ Base::Vector3d v2 = Py::Vector(p2,false).toVector();
+ Base::Vector3d v3 = Py::Vector(p3,false).toVector();
+ Base::Vector3d c = (v1-v2) % (v3-v2);
+ double zValue = v1.z;
+ if (fabs(c.Length()) < 0.0001) {
+ PyErr_SetString(PyExc_Exception, "Points are collinear");
+ return 0;
+ }
+
+ Base::Matrix4D m;
+ Base::Vector3f v;
+ m[0][0] = v1.y * v1.y;
+ m[0][1] = v1.y;
+ m[0][2] = 1;
+ m[1][0] = v2.y * v2.y;
+ m[1][1] = v2.y;
+ m[1][2] = 1;
+ m[2][0] = v3.y * v3.y;
+ m[2][1] = v3.y;
+ m[2][2] = 1.0;
+ v.x = v1.x;
+ v.y = v2.x;
+ v.z = v3.x;
+ m.inverseGauss();
+ v = m * v;
+ double a22 = v.x;
+ double a10 = -0.5;
+ double a20 = v.y/2.0;
+ double a00 = v.z;
+ Handle_Geom_Parabola curve = Handle_Geom_Parabola::DownCast(getGeometryPtr()->handle());
+ curve->SetFocal(0.5*fabs(a10/a22));
+ curve->SetLocation(gp_Pnt((a20*a20-a22*a00)/(2*a22*a10), -a20/a22, zValue));
+
+ Py_Return;
+}
+
Py::Float ParabolaPy::getEccentricity(void) const
{
Handle_Geom_Parabola curve = Handle_Geom_Parabola::DownCast(getGeometryPtr()->handle());
diff --git a/src/Mod/Part/App/Part2DObject.cpp b/src/Mod/Part/App/Part2DObject.cpp
index d9280bc46..bb59cde2a 100644
--- a/src/Mod/Part/App/Part2DObject.cpp
+++ b/src/Mod/Part/App/Part2DObject.cpp
@@ -193,6 +193,12 @@ int Part2DObject::getAxisCount(void) const
Base::Axis Part2DObject::getAxis(int axId) const
{
+ if (axId == H_Axis) {
+ return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
+ }
+ else if (axId == V_Axis) {
+ return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
+ }
return Base::Axis();
}
diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp
index 45e0076e9..660146282 100644
--- a/src/Mod/Part/App/PartFeature.cpp
+++ b/src/Mod/Part/App/PartFeature.cpp
@@ -27,13 +27,16 @@
# include
# include
# include
+# include
# include
# include
# include
-// includes for findAllFacesCutBy()
+# include
# include
# include
# include // for Precision::Confusion()
+# include
+# include
#endif
@@ -71,6 +74,19 @@ short Feature::mustExecute(void) const
return GeoFeature::mustExecute();
}
+App::DocumentObjectExecReturn *Feature::recompute(void)
+{
+ try {
+ return App::GeoFeature::recompute();
+ }
+ catch (Standard_Failure) {
+ Handle_Standard_Failure e = Standard_Failure::Caught();
+ App::DocumentObjectExecReturn* ret = new App::DocumentObjectExecReturn(e->GetMessageString());
+ if (ret->Why.empty()) ret->Why = "Unknown OCC exception";
+ return ret;
+ }
+}
+
App::DocumentObjectExecReturn *Feature::execute(void)
{
return App::DocumentObject::StdReturn;
@@ -319,3 +335,34 @@ std::vector Part::findAllFacesCutBy(
return result;
}
+
+const bool Part::checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick) {
+ Bnd_Box first_bb, second_bb;
+ BRepBndLib::Add(first, first_bb);
+ first_bb.SetGap(0);
+ BRepBndLib::Add(second, second_bb);
+ second_bb.SetGap(0);
+
+ // Note: Both tests fail if the objects are touching one another at zero distance!
+ if (first_bb.IsOut(second_bb))
+ return false; // no intersection
+ //if (first_bb.Distance(second_bb) > Precision::Confusion())
+ // return false;
+ if (quick)
+ return true; // assumed intersection
+
+ // Try harder
+ BRepAlgoAPI_Common mkCommon(first, second);
+ // FIXME: Error in boolean operation, return true by default
+ if (!mkCommon.IsDone())
+ return true;
+ if (mkCommon.Shape().IsNull())
+ return true;
+
+ TopExp_Explorer xp;
+ xp.Init(mkCommon.Shape(),TopAbs_SOLID);
+ if (xp.More())
+ return true;
+
+ return false;
+}
diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h
index 5c08151bc..d44272b65 100644
--- a/src/Mod/Part/App/PartFeature.h
+++ b/src/Mod/Part/App/PartFeature.h
@@ -60,6 +60,8 @@ public:
/** @name methods override feature */
//@{
/// recalculate the feature
+ /// recompute only this object
+ virtual App::DocumentObjectExecReturn *recompute(void);
virtual App::DocumentObjectExecReturn *execute(void);
virtual short mustExecute(void) const;
//@}
@@ -133,6 +135,16 @@ PartExport
std::vector findAllFacesCutBy(const TopoDS_Shape& shape,
const TopoDS_Shape& face, const gp_Dir& dir);
+/**
+ * Check for intersection between the two shapes. Only solids are guaranteed to work properly
+ * There are two modes:
+ * 1. Bounding box check only - quick but inaccurate
+ * 2. Bounding box check plus (if necessary) boolean operation - costly but accurate
+ * Return true if the shapes intersect, false if they don't
+ */
+PartExport
+const bool checkIntersection(const TopoDS_Shape& first, const TopoDS_Shape& second, const bool quick = true);
+
} //namespace Part
diff --git a/src/Mod/Part/App/PartFeatures.h b/src/Mod/Part/App/PartFeatures.h
index ddaae9627..e891cee59 100644
--- a/src/Mod/Part/App/PartFeatures.h
+++ b/src/Mod/Part/App/PartFeatures.h
@@ -67,6 +67,9 @@ public:
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
+ const char* getViewProviderName(void) const {
+ return "PartGui::ViewProviderLoft";
+ }
//@}
protected:
@@ -91,6 +94,9 @@ public:
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
+ const char* getViewProviderName(void) const {
+ return "PartGui::ViewProviderSweep";
+ }
//@}
protected:
diff --git a/src/Mod/Part/Gui/AppPartGui.cpp b/src/Mod/Part/Gui/AppPartGui.cpp
index fadff8744..48f979675 100644
--- a/src/Mod/Part/Gui/AppPartGui.cpp
+++ b/src/Mod/Part/Gui/AppPartGui.cpp
@@ -103,6 +103,8 @@ void PartGuiExport initPartGui()
PartGui::ViewProviderFillet ::init();
PartGui::ViewProviderChamfer ::init();
PartGui::ViewProviderRevolution ::init();
+ PartGui::ViewProviderLoft ::init();
+ PartGui::ViewProviderSweep ::init();
PartGui::ViewProviderCustom ::init();
PartGui::ViewProviderCustomPython ::init();
PartGui::ViewProviderBoolean ::init();
diff --git a/src/Mod/Part/Gui/ViewProviderMirror.cpp b/src/Mod/Part/Gui/ViewProviderMirror.cpp
index 841fb402b..b3c6d705a 100644
--- a/src/Mod/Part/Gui/ViewProviderMirror.cpp
+++ b/src/Mod/Part/Gui/ViewProviderMirror.cpp
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -348,3 +349,49 @@ bool ViewProviderRevolution::onDelete(const std::vector &)
return true;
}
+
+// ---------------------------------------
+
+PROPERTY_SOURCE(PartGui::ViewProviderLoft, PartGui::ViewProviderPart)
+
+ViewProviderLoft::ViewProviderLoft()
+{
+ sPixmap = "Part_Loft";
+}
+
+ViewProviderLoft::~ViewProviderLoft()
+{
+}
+
+std::vector ViewProviderLoft::claimChildren() const
+{
+ return static_cast(getObject())->Sections.getValues();
+}
+
+bool ViewProviderLoft::onDelete(const std::vector &)
+{
+ return true;
+}
+
+// ---------------------------------------
+
+PROPERTY_SOURCE(PartGui::ViewProviderSweep, PartGui::ViewProviderPart)
+
+ViewProviderSweep::ViewProviderSweep()
+{
+ sPixmap = "Part_Sweep";
+}
+
+ViewProviderSweep::~ViewProviderSweep()
+{
+}
+
+std::vector ViewProviderSweep::claimChildren() const
+{
+ return static_cast(getObject())->Sections.getValues();
+}
+
+bool ViewProviderSweep::onDelete(const std::vector &)
+{
+ return true;
+}
diff --git a/src/Mod/Part/Gui/ViewProviderMirror.h b/src/Mod/Part/Gui/ViewProviderMirror.h
index 7e282b01a..aae6a79aa 100644
--- a/src/Mod/Part/Gui/ViewProviderMirror.h
+++ b/src/Mod/Part/Gui/ViewProviderMirror.h
@@ -108,6 +108,36 @@ public:
bool onDelete(const std::vector &);
};
+class ViewProviderLoft : public ViewProviderPart
+{
+ PROPERTY_HEADER(PartGui::ViewProviderLoft);
+
+public:
+ /// constructor
+ ViewProviderLoft();
+ /// destructor
+ virtual ~ViewProviderLoft();
+
+ /// grouping handling
+ std::vector claimChildren(void)const;
+ bool onDelete(const std::vector &);
+};
+
+class ViewProviderSweep : public ViewProviderPart
+{
+ PROPERTY_HEADER(PartGui::ViewProviderSweep);
+
+public:
+ /// constructor
+ ViewProviderSweep();
+ /// destructor
+ virtual ~ViewProviderSweep();
+
+ /// grouping handling
+ std::vector claimChildren(void)const;
+ bool onDelete(const std::vector &);
+};
+
} // namespace PartGui
diff --git a/src/Mod/PartDesign/App/FeatureGroove.cpp b/src/Mod/PartDesign/App/FeatureGroove.cpp
index baa60683e..40309d496 100644
--- a/src/Mod/PartDesign/App/FeatureGroove.cpp
+++ b/src/Mod/PartDesign/App/FeatureGroove.cpp
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2010 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * 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"
@@ -56,8 +56,6 @@ Groove::Groove()
ADD_PROPERTY_TYPE(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)),"Groove", App::Prop_ReadOnly, "Axis");
ADD_PROPERTY_TYPE(Angle,(360.0),"Groove", App::Prop_None, "Angle");
ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Groove",(App::PropertyType)(App::Prop_None),"Reference axis of Groove");
- ADD_PROPERTY_TYPE(Midplane,(0),"Groove", App::Prop_None, "Mid plane");
- ADD_PROPERTY_TYPE(Reversed, (0),"Groove", App::Prop_None, "Reversed");
}
short Groove::mustExecute() const
@@ -66,9 +64,7 @@ short Groove::mustExecute() const
ReferenceAxis.isTouched() ||
Axis.isTouched() ||
Base.isTouched() ||
- Angle.isTouched() ||
- Midplane.isTouched() ||
- Reversed.isTouched())
+ Angle.isTouched())
return 1;
return Subtractive::mustExecute();
}
diff --git a/src/Mod/PartDesign/App/FeatureGroove.h b/src/Mod/PartDesign/App/FeatureGroove.h
index ec13362d3..7e637e607 100644
--- a/src/Mod/PartDesign/App/FeatureGroove.h
+++ b/src/Mod/PartDesign/App/FeatureGroove.h
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2010 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * 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 PARTDESIGN_Groove_H
@@ -40,8 +40,6 @@ public:
App::PropertyVector Base;
App::PropertyVector Axis;
App::PropertyAngle Angle;
- App::PropertyBool Midplane;
- App::PropertyBool Reversed;
/** if this property is set to a valid link, both Axis and Base properties
* are calculated according to the linked line
@@ -50,7 +48,13 @@ public:
/** @name methods override feature */
//@{
- /// recalculate the feature
+ /** Recalculate the feature
+ * Revolves the Sketch around the given Axis (with basepoint Base)
+ * The angle of the revolution is given by Angle.
+ * If Midplane is true, then the revolution will extend for half of Angle on both sides of the sketch plane.
+ * If Reversed is true then the direction of revolution will be reversed.
+ * The created material will be cut out of the sketch support
+ */
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp
index cc7f18ebe..ae037197b 100644
--- a/src/Mod/PartDesign/App/FeaturePad.cpp
+++ b/src/Mod/PartDesign/App/FeaturePad.cpp
@@ -59,8 +59,6 @@ Pad::Pad()
ADD_PROPERTY(Type,((long)0));
Type.setEnums(TypeEnums);
ADD_PROPERTY(Length,(100.0));
- ADD_PROPERTY(Reversed,(0));
- ADD_PROPERTY(Midplane,(0));
ADD_PROPERTY(Length2,(100.0));
ADD_PROPERTY(FaceName,(""));
}
@@ -69,8 +67,6 @@ short Pad::mustExecute() const
{
if (Placement.isTouched() ||
Length.isTouched() ||
- Midplane.isTouched() ||
- Reversed.isTouched() ||
Length2.isTouched() ||
FaceName.isTouched())
return 1;
diff --git a/src/Mod/PartDesign/App/FeaturePad.h b/src/Mod/PartDesign/App/FeaturePad.h
index 8c9787685..f70803df7 100644
--- a/src/Mod/PartDesign/App/FeaturePad.h
+++ b/src/Mod/PartDesign/App/FeaturePad.h
@@ -40,15 +40,24 @@ public:
App::PropertyEnumeration Type;
App::PropertyLength Length;
- //App::PropertyEnumeration Side;
- App::PropertyBool Reversed;
- App::PropertyBool Midplane;
App::PropertyLength Length2;
App::PropertyString FaceName;
/** @name methods override feature */
//@{
- /// recalculate the feature
+ /** Recalculate the feature
+ * Extrudes the Sketch in the direction of the sketch face normal
+ * If Type is "Length" then Length gives the extrusion length, the direction will be away from the support
+ * If Type is "UpToLast" then the extrusion will stop at the last face of the support
+ * that is cut by a line through the centre of gravite of the sketch
+ * If Type is "UpToFirst" then extrusion will stop at the first face of the support
+ * If Type is "UpToFace" then the extrusion will stop at FaceName in the support
+ * If Type is "TwoLengths" then the extrusion will extend Length in the direction away from the support
+ * and Length2 in the opposite direction
+ * If Midplane is true, then the extrusion will extend for half of the length on both sides of the sketch plane
+ * If Reversed is true then the direction of revolution will be reversed.
+ * The created material will be fused with the sketch support (if there is one)
+ */
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
diff --git a/src/Mod/PartDesign/App/FeaturePocket.h b/src/Mod/PartDesign/App/FeaturePocket.h
index cab10b16a..f3c65bf12 100644
--- a/src/Mod/PartDesign/App/FeaturePocket.h
+++ b/src/Mod/PartDesign/App/FeaturePocket.h
@@ -43,7 +43,16 @@ public:
/** @name methods override feature */
//@{
- /// recalculate the feature
+ /** Recalculate the feature
+ * Extrudes the Sketch in the direction of the sketch face normal
+ * If Type is "Length" then Length gives the extrusion length, the direction will be into the support
+ * If Type is "ThroughAll" then the extrusion length will be infinite
+ * If Type is "UpToFirst" then extrusion will stop at the first face of the support that is cut
+ * by a line through the centre of gravite of the sketch
+ * If Type is "UpToFace" then the extrusion will stop at FaceName in the support
+ * If Midplane is true, then the extrusion will extend for half of the length on both sides of the sketch plane
+ * The created material will be cut out of the sketch support
+ */
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
diff --git a/src/Mod/PartDesign/App/FeatureRevolution.cpp b/src/Mod/PartDesign/App/FeatureRevolution.cpp
index 32acdb705..30501df24 100644
--- a/src/Mod/PartDesign/App/FeatureRevolution.cpp
+++ b/src/Mod/PartDesign/App/FeatureRevolution.cpp
@@ -56,8 +56,6 @@ Revolution::Revolution()
ADD_PROPERTY_TYPE(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)),"Revolution", App::Prop_ReadOnly, "Axis");
ADD_PROPERTY_TYPE(Angle,(360.0),"Revolution", App::Prop_None, "Angle");
ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Revolution",(App::Prop_None),"Reference axis of revolution");
- ADD_PROPERTY_TYPE(Midplane,(0),"Revolution", App::Prop_None, "Mid plane");
- ADD_PROPERTY_TYPE(Reversed, (0),"Revolution", App::Prop_None, "Reversed");
}
short Revolution::mustExecute() const
@@ -66,9 +64,7 @@ short Revolution::mustExecute() const
ReferenceAxis.isTouched() ||
Axis.isTouched() ||
Base.isTouched() ||
- Angle.isTouched() ||
- Midplane.isTouched() ||
- Reversed.isTouched())
+ Angle.isTouched())
return 1;
return Additive::mustExecute();
}
diff --git a/src/Mod/PartDesign/App/FeatureRevolution.h b/src/Mod/PartDesign/App/FeatureRevolution.h
index 976f473d2..485c851f6 100644
--- a/src/Mod/PartDesign/App/FeatureRevolution.h
+++ b/src/Mod/PartDesign/App/FeatureRevolution.h
@@ -40,8 +40,6 @@ public:
App::PropertyVector Base;
App::PropertyVector Axis;
App::PropertyAngle Angle;
- App::PropertyBool Midplane;
- App::PropertyBool Reversed;
/** if this property is set to a valid link, both Axis and Base properties
* are calculated according to the linked line
@@ -50,7 +48,13 @@ public:
/** @name methods override feature */
//@{
- /// recalculate the feature
+ /** Recalculate the feature
+ * Revolves the Sketch around the given Axis (with basepoint Base)
+ * The angle of the revolution is given by Angle.
+ * If Midplane is true, then the revolution will extend for half of Angle on both sides of the sketch plane.
+ * If Reversed is true then the direction of revolution will be reversed.
+ * The created material will be fused with the sketch support (if there is one)
+ */
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp
index 3d1bcd092..1cb4ef1a4 100644
--- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp
+++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp
@@ -75,11 +75,15 @@ PROPERTY_SOURCE(PartDesign::SketchBased, PartDesign::Feature)
SketchBased::SketchBased()
{
ADD_PROPERTY(Sketch,(0));
+ ADD_PROPERTY_TYPE(Midplane,(0),"SketchBased", App::Prop_None, "Extrude symmetric to sketch face");
+ ADD_PROPERTY_TYPE(Reversed, (0),"SketchBased", App::Prop_None, "Reverse extrusion direction");
}
short SketchBased::mustExecute() const
{
- if (Sketch.isTouched())
+ if (Sketch.isTouched() ||
+ Midplane.isTouched() ||
+ Reversed.isTouched())
return 1;
return 0; // PartDesign::Feature::mustExecute();
}
diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h
index b99d6a15a..8c75d9724 100644
--- a/src/Mod/PartDesign/App/FeatureSketchBased.h
+++ b/src/Mod/PartDesign/App/FeatureSketchBased.h
@@ -40,7 +40,12 @@ class PartDesignExport SketchBased : public PartDesign::Feature
public:
SketchBased();
+ /// Common properties for all sketch based features
App::PropertyLink Sketch;
+ /// Reverse extrusion direction
+ App::PropertyBool Reversed;
+ /// Make extrusion symmetric to sketch plane
+ App::PropertyBool Midplane;
short mustExecute() const;
diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp
index f871f89a0..bf005ac00 100644
--- a/src/Mod/PartDesign/App/FeatureTransformed.cpp
+++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp
@@ -30,8 +30,6 @@
# include
# include
# include
-# include
-# include
# include
# include
#endif
@@ -114,10 +112,6 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
supportShape.setTransform(Base::Matrix4D());
TopoDS_Shape support = supportShape._Shape;
- // Prepare a bounding box for intersection tests
- Bnd_Box support_bb;
- BRepBndLib::Add(support, support_bb);
-
// NOTE: It would be possible to build a compound from all original addShapes/subShapes and then
// transform the compounds as a whole. But we choose to apply the transformations to each
// Original separately. This way it is easier to discover what feature causes a fuse/cut
@@ -144,7 +138,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
BRep_Builder builder;
TopoDS_Compound transformedShapes;
builder.MakeCompound(transformedShapes);
- std::vector v_transformedShapes; // collect all the transformed shapes for history building
+ std::vector v_transformedShapes; // collect all the transformed shapes for intersection testing
std::list::const_iterator t = transformations.begin();
t++; // Skip first transformation, which is always the identity transformation
@@ -162,12 +156,9 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
return new App::DocumentObjectExecReturn("Transformation failed", (*o));
// Check for intersection with support
- Bnd_Box transformed_bb;
- BRepBndLib::Add(mkTrf.Shape(), transformed_bb);
- if (support_bb.Distance(transformed_bb) > Precision::Confusion()) {
+ if (!Part::checkIntersection(support, mkTrf.Shape(), false)) {
Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
- // Note: The removal happens in getSolid() after the fuse. If we remove here,
- // the histories get messed up and we get a crash
+ // Note: The removal happens in getSolid() after the fuse
rejected.push_back(*t);
}
builder.Add(transformedShapes, mkTrf.Shape());
@@ -183,21 +174,14 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
BRepBndLib::Add(trfShape, transformed_bb);
if (support_bb.Distance(transformed_bb) > Precision::Confusion()) {
Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument());
- // Note: The removal happens in getSolid() after the fuse. If we remove here,
- // the histories get messed up and we get a crash
+ // Note: The removal happens in getSolid() after the fuse
}
builder.Add(transformedShapes, trfShape);
v_transformedShapes.push_back(trfShape);
-
*/
}
// Check for intersection of the original and the transformed shape
- // Note: For performance reasons, we only check for intersection of bounding boxes
- Bnd_Box original_bb;
- BRepBndLib::Add(shape, original_bb);
- original_bb.SetGap(0);
-
for (std::vector::const_iterator s = v_transformedShapes.begin(); s != v_transformedShapes.end(); s++)
{
// If there is only one transformed feature, this check is not necessary (though it might seem
@@ -205,12 +189,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
if (v_transformedShapes.size() == 1)
break;
- Bnd_Box transformed_bb;
- BRepBndLib::Add(*s, transformed_bb);
- transformed_bb.SetGap(0);
- if (!original_bb.IsOut(transformed_bb))
- // if (original_bb.Distance(transformed_bb) < Precision::Confusion())
- // FIXME: Both tests fail if the objects are touching one another at zero distance
+ if (Part::checkIntersection(shape, *s, false))
return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
// Note: This limitation could be overcome by fusing the transformed features instead of
// compounding them, probably at the expense of quite a bit of performance and complexity
@@ -220,6 +199,14 @@ App::DocumentObjectExecReturn *Transformed::execute(void)
// features might overlap, even if the original and the first shape don't overlap!
if (this->getTypeId() != PartDesign::MultiTransform::getClassTypeId())
break;
+ else {
+ // Check intersection with all other transformed shapes as well
+ std::vector::const_iterator s2 = s;
+ s2++;
+ for (; s2 != v_transformedShapes.end(); s2++)
+ if (Part::checkIntersection(*s, *s2, false))
+ return new App::DocumentObjectExecReturn("Transformed objects are overlapping, try using a higher length or reducing the number of occurrences", (*o));
+ }
}
// Fuse/Cut the compounded transformed shapes with the support
diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp
index cd584a3f0..1145dd8e6 100644
--- a/src/Mod/PartDesign/Gui/Command.cpp
+++ b/src/Mod/PartDesign/Gui/Command.cpp
@@ -54,6 +54,63 @@ using namespace std;
#include "FeaturePickDialog.h"
+namespace Gui {
+//===========================================================================
+// Common utility functions
+//===========================================================================
+
+// Take a list of Part2DObjects and erase those which are not eligible for creating a
+// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define
+// a Subtractive feature
+void validateSketches(std::vector& sketches, const bool supportRequired)
+{
+ std::vector::iterator s = sketches.begin();
+
+ while (s != sketches.end()) {
+ // Check whether this sketch is already being used by another feature
+ if ((*s)->getInList().size() != 0) {
+ // TODO: Display some information message that this sketch was removed?
+ s = sketches.erase(s);
+ continue;
+ }
+
+ // Check whether the sketch shape is valid
+ Part::Part2DObject* sketch = static_cast(*s);
+ const TopoDS_Shape& shape = sketch->Shape.getValue();
+ if (shape.IsNull()) {
+ s = sketches.erase(s);
+ continue;
+ // TODO: Display some information message that this sketch was removed?
+ }
+
+ // count free wires
+ int ctWires=0;
+ TopExp_Explorer ex;
+ for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
+ ctWires++;
+ }
+ if (ctWires == 0) {
+ s = sketches.erase(s);
+ continue;
+ // TODO: Display some information message that this sketch was removed?
+ }
+
+ // Check for support
+ if (supportRequired) {
+ App::DocumentObject* support = sketch->Support.getValue();
+ if (support == NULL) {
+ s = sketches.erase(s);
+ continue;
+ // TODO: Display some information message that this sketch was removed?
+ }
+ }
+
+ // All checks passed - go on to next candidate
+ s++;
+ }
+}
+} // namespace Gui
+
//===========================================================================
// Part_Pad
//===========================================================================
@@ -118,37 +175,30 @@ CmdPartDesignPad::CmdPartDesignPad()
void CmdPartDesignPad::activated(int iMsg)
{
- unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId());
- if (n != 1) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("Select a sketch or 2D object."));
- return;
- }
-
- std::string FeatName = getUniqueObjectName("Pad");
-
- std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
- Part::Part2DObject* sketch = static_cast(Sel.front());
- const TopoDS_Shape& shape = sketch->Shape.getValue();
- if (shape.IsNull()) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is empty."));
- return;
- }
-
- // count free wires
- int ctWires=0;
- TopExp_Explorer ex;
- for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
- ctWires++;
- }
- if (ctWires == 0) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is not a wire."));
- return;
+ // Get a valid sketch from the user
+ // First check selections
+ std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, false);
+ // Next let the user choose from a list of all eligible objects
+ if (sketches.size() == 0) {
+ sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, false);
+ if (sketches.size() == 0) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"),
+ QObject::tr("Please create a sketch or 2D object first"));
+ return;
+ }
+ }
+ // If there is more than one selection/possibility, show dialog and let user pick sketch
+ if (sketches.size() > 1) {
+ PartDesignGui::FeaturePickDialog Dlg(sketches);
+ if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty())
+ return; // Cancelled or nothing selected
}
+ Part::Part2DObject* sketch = static_cast(sketches.front());
App::DocumentObject* support = sketch->Support.getValue();
+ std::string FeatName = getUniqueObjectName("Pad");
openCommand("Make Pad");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pad\",\"%s\")",FeatName.c_str());
@@ -196,41 +246,30 @@ CmdPartDesignPocket::CmdPartDesignPocket()
void CmdPartDesignPocket::activated(int iMsg)
{
- unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId());
- if (n != 1) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("Select a sketch or 2D object."));
- return;
+ // Get a valid sketch from the user
+ // First check selections
+ std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, true);
+ // Next let the user choose from a list of all eligible objects
+ if (sketches.size() == 0) {
+ sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, true);
+ if (sketches.size() == 0) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"),
+ QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid"));
+ return;
+ }
+ }
+ // If there is more than one selection/possibility, show dialog and let user pick sketch
+ if (sketches.size() > 1) {
+ PartDesignGui::FeaturePickDialog Dlg(sketches);
+ if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty())
+ return; // Cancelled or nothing selected
}
- std::string FeatName = getUniqueObjectName("Pocket");
-
- std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
- Part::Part2DObject* sketch = static_cast(Sel.front());
- const TopoDS_Shape& shape = sketch->Shape.getValue();
- if (shape.IsNull()) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is empty."));
- return;
- }
-
- // count free wires
- int ctWires=0;
- TopExp_Explorer ex;
- for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
- ctWires++;
- }
- if (ctWires == 0) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is not a wire."));
- return;
- }
+ Part::Part2DObject* sketch = static_cast(sketches.front());
App::DocumentObject* support = sketch->Support.getValue();
- if (support == 0) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No Support"),
- QObject::tr("The sketch has to have a support for the pocket feature.\nCreate the sketch on a face."));
- return;
- }
+ std::string FeatName = getUniqueObjectName("Pocket");
openCommand("Make Pocket");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pocket\",\"%s\")",FeatName.c_str());
@@ -272,37 +311,30 @@ CmdPartDesignRevolution::CmdPartDesignRevolution()
void CmdPartDesignRevolution::activated(int iMsg)
{
- unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId());
- if (n != 1) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("Select a sketch or 2D object."));
- return;
- }
-
- std::string FeatName = getUniqueObjectName("Revolution");
-
- std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
- Part::Part2DObject* sketch = static_cast(Sel.front());
- const TopoDS_Shape& shape = sketch->Shape.getValue();
- if (shape.IsNull()) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is empty."));
- return;
- }
-
- // count free wires
- int ctWires=0;
- TopExp_Explorer ex;
- for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
- ctWires++;
- }
- if (ctWires == 0) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is not a wire."));
- return;
+ // Get a valid sketch from the user
+ // First check selections
+ std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, false);
+ // Next let the user choose from a list of all eligible objects
+ if (sketches.size() == 0) {
+ sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, false);
+ if (sketches.size() == 0) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"),
+ QObject::tr("Please create a sketch or 2D object first"));
+ return;
+ }
+ }
+ // If there is more than one selection/possibility, show dialog and let user pick sketch
+ if (sketches.size() > 1) {
+ PartDesignGui::FeaturePickDialog Dlg(sketches);
+ if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty())
+ return; // Cancelled or nothing selected
}
+ Part::Part2DObject* sketch = static_cast(sketches.front());
App::DocumentObject* support = sketch->Support.getValue();
+ std::string FeatName = getUniqueObjectName("Revolution");
openCommand("Make Revolution");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Revolution\",\"%s\")",FeatName.c_str());
@@ -349,37 +381,30 @@ CmdPartDesignGroove::CmdPartDesignGroove()
void CmdPartDesignGroove::activated(int iMsg)
{
- unsigned int n = getSelection().countObjectsOfType(Part::Part2DObject::getClassTypeId());
- if (n != 1) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("Select a sketch or 2D object."));
- return;
- }
-
- std::string FeatName = getUniqueObjectName("Groove");
-
- std::vector Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
- Part::Part2DObject* sketch = static_cast(Sel.front());
- const TopoDS_Shape& shape = sketch->Shape.getValue();
- if (shape.IsNull()) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is empty."));
- return;
- }
-
- // count free wires
- int ctWires=0;
- TopExp_Explorer ex;
- for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) {
- ctWires++;
- }
- if (ctWires == 0) {
- QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
- QObject::tr("The shape of the selected object is not a wire."));
- return;
+ // Get a valid sketch from the user
+ // First check selections
+ std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, true);
+ // Next let the user choose from a list of all eligible objects
+ if (sketches.size() == 0) {
+ sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId());
+ Gui::validateSketches(sketches, true);
+ if (sketches.size() == 0) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"),
+ QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid"));
+ return;
+ }
+ }
+ // If there is more than one selection/possibility, show dialog and let user pick sketch
+ if (sketches.size() > 1) {
+ PartDesignGui::FeaturePickDialog Dlg(sketches);
+ if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty())
+ return; // Cancelled or nothing selected
}
+ Part::Part2DObject* sketch = static_cast(sketches.front());
App::DocumentObject* support = sketch->Support.getValue();
+ std::string FeatName = getUniqueObjectName("Groove");
openCommand("Make Groove");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Groove\",\"%s\")",FeatName.c_str());
diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp
index 79b0278fe..974e1e288 100644
--- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp
+++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.cpp
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2011 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * 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"
diff --git a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h
index 8b82f0187..1c19bb6b6 100644
--- a/src/Mod/PartDesign/Gui/TaskGrooveParameters.h
+++ b/src/Mod/PartDesign/Gui/TaskGrooveParameters.h
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2011 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * 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 GUI_TASKVIEW_TaskGrooveParameters_H
diff --git a/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp b/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp
index 7b46d7681..981801c3f 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp
+++ b/src/Mod/PartDesign/Gui/ViewProviderGroove.cpp
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2011 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * 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"
diff --git a/src/Mod/PartDesign/Gui/ViewProviderGroove.h b/src/Mod/PartDesign/Gui/ViewProviderGroove.h
index 51b1adca4..6f02326e3 100644
--- a/src/Mod/PartDesign/Gui/ViewProviderGroove.h
+++ b/src/Mod/PartDesign/Gui/ViewProviderGroove.h
@@ -1,24 +1,24 @@
-/***************************************************************************
- * Copyright (c) 2011 Juergen Riegel *
- * *
- * 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 *
- * *
- ***************************************************************************/
+/******************************************************************************
+ * Copyright (c)2012 Jan Rheinlaender *
+ * *
+ * This file is part of the FreeCAD CAx development system. *
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Library General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Library General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this library; see the file COPYING.LIB. If not, *
+ * write to the Free Software Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307, USA *
+ * *
+ ******************************************************************************/
#ifndef PARTGUI_ViewProviderGroove_H
diff --git a/src/Mod/Start/Gui/CMakeLists.txt b/src/Mod/Start/Gui/CMakeLists.txt
index 339c9ad50..b3f9a9836 100644
--- a/src/Mod/Start/Gui/CMakeLists.txt
+++ b/src/Mod/Start/Gui/CMakeLists.txt
@@ -56,6 +56,9 @@ SET(StartPage_Resources
StartPage/web.png
StartPage/blank.png
StartPage/complete.jpg
+ StartPage/Ship.py
+ StartPage/Ship.png
+ StartPage/ShipExample.png
)
add_library(StartGui SHARED ${StartGui_SRCS})
diff --git a/src/Mod/Start/StartPage/CMakeLists.txt b/src/Mod/Start/StartPage/CMakeLists.txt
index 7a798c98e..b4233676a 100644
--- a/src/Mod/Start/StartPage/CMakeLists.txt
+++ b/src/Mod/Start/StartPage/CMakeLists.txt
@@ -26,6 +26,9 @@ SET(StartPage_DATA
web.png
blank.png
complete.jpg
+ Ship.py
+ Ship.png
+ ShipExample.png
)
INSTALL(FILES ${StartPage_SRCS}
diff --git a/src/Mod/Start/StartPage/Makefile.am b/src/Mod/Start/StartPage/Makefile.am
index 57ffd74ee..c23b289a9 100644
--- a/src/Mod/Start/StartPage/Makefile.am
+++ b/src/Mod/Start/StartPage/Makefile.am
@@ -30,7 +30,10 @@ data_DATA = \
ArchExample.png \
web.png \
blank.png \
- complete.jpg
+ complete.jpg \
+ Ship.py \
+ Ship.png \
+ ShipExample.png
EXTRA_DIST = \
$(data_DATA) $(python_DATA)
diff --git a/src/Mod/Start/StartPage/Ship.png b/src/Mod/Start/StartPage/Ship.png
new file mode 100644
index 000000000..533b3fcc5
Binary files /dev/null and b/src/Mod/Start/StartPage/Ship.png differ
diff --git a/src/Mod/Start/StartPage/Ship.py b/src/Mod/Start/StartPage/Ship.py
new file mode 100644
index 000000000..371ca2d69
--- /dev/null
+++ b/src/Mod/Start/StartPage/Ship.py
@@ -0,0 +1,3 @@
+import FreeCADGui
+FreeCADGui.activateWorkbench("ShipWorkbench")
+App.newDocument()
diff --git a/src/Mod/Start/StartPage/ShipExample.png b/src/Mod/Start/StartPage/ShipExample.png
new file mode 100644
index 000000000..be89b2f74
Binary files /dev/null and b/src/Mod/Start/StartPage/ShipExample.png differ
diff --git a/src/Mod/Start/StartPage/StartPage.py b/src/Mod/Start/StartPage/StartPage.py
index 03b445860..015aeda6a 100644
--- a/src/Mod/Start/StartPage/StartPage.py
+++ b/src/Mod/Start/StartPage/StartPage.py
@@ -73,6 +73,9 @@ text48 = translate("StartPage","A blog dedicated to teaching FreeCAD, maintained
text49 = translate("StartPage","Getting started")
text50 = translate("StartPage","The FreeCAD interface is divided in workbenches, which are sets of tools suited for a specific task. You can start with one of the workbenches in this list, or with the complete workbench, which presents you with some of the most used tools gathered from other workbenches. Click to read more about workbenches on the FreeCAD website.")
text51 = translate("StartPage","http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=Workbench_Concept")
+text52 = translate("StartPage","Ship Design")
+text53 = translate("StartPage","Designing and calculating ships")
+text54 = translate("StartPage","The Ship Design module offers several tools to help ship designers to view, model and calculate profiles and other specific properties of ship hulls.")
# here is the html page skeleton
@@ -366,6 +369,13 @@ def getWorkbenches():
onMouseout="show('')"
href="ArchDesign.py">""" + text25 + """
+
+ \
+ """ + text54 + """
""" + text21 + """ \
+ :
')"
+ onMouseout="show('')"
+ href="Ship.py">""" + text52 + """
+
\
""" + text27 + """
""" + text28 + """
')"
diff --git a/src/Mod/Surfaces/surfUtils/Geometry.py b/src/Mod/Surfaces/surfUtils/Geometry.py
index 687fe3cdd..eac10f5ed 100644
--- a/src/Mod/Surfaces/surfUtils/Geometry.py
+++ b/src/Mod/Surfaces/surfUtils/Geometry.py
@@ -25,7 +25,8 @@ import math
# FreeCAD
import FreeCAD, FreeCADGui
from FreeCAD import Base
-from FreeCAD import Part
+#from FreeCAD import Part
+import Part
# FreeCAD ship
from surfUtils import Math
diff --git a/src/Mod/Test/BaseTests.py b/src/Mod/Test/BaseTests.py
index c6442ce05..97ceb4f6a 100644
--- a/src/Mod/Test/BaseTests.py
+++ b/src/Mod/Test/BaseTests.py
@@ -149,6 +149,11 @@ class ParameterTestCase(unittest.TestCase):
self.TestPar.RemString("44")
self.failUnless(self.TestPar.GetString("44","hallo") == "hallo","Deletion error at String")
+ def testMatrix(self):
+ m=FreeCAD.Matrix(4,2,1,0,1,1,1,0,0,0,1,0,0,0,0,1)
+ u=m.multiply(m.inverse())
+ self.failUnless(u==FreeCAD.Matrix(),"Invalid inverse of matrix")
+
def testNesting(self):
# Parameter testing
#FreeCAD.Console.PrintLog("Base::ParameterTestCase::testNesting\n")
diff --git a/src/WindowsInstaller/FreeCAD.wxs b/src/WindowsInstaller/FreeCAD.wxs
index 05a5d19fd..8a3a8833c 100644
--- a/src/WindowsInstaller/FreeCAD.wxs
+++ b/src/WindowsInstaller/FreeCAD.wxs
@@ -161,6 +161,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WindowsInstaller/FreeCADData.wxs b/src/WindowsInstaller/FreeCADData.wxs
index 5244bf9a2..2f52bf207 100644
--- a/src/WindowsInstaller/FreeCADData.wxs
+++ b/src/WindowsInstaller/FreeCADData.wxs
@@ -92,6 +92,9 @@
+
+
+
diff --git a/src/WindowsInstaller/ModShip.wxi b/src/WindowsInstaller/ModShip.wxi
index 274c0fc78..029fe06c3 100644
--- a/src/WindowsInstaller/ModShip.wxi
+++ b/src/WindowsInstaller/ModShip.wxi
@@ -38,7 +38,7 @@
-
+
@@ -80,7 +80,7 @@
-
+
@@ -137,11 +137,11 @@
-
+
-
-
-
+
+
+