Merge branch 'master' of git://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
jrheinlaender 2012-10-24 09:13:58 +04:30
commit 3f4772b1a6
44 changed files with 607 additions and 313 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);
//@}

View File

@ -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 {

View File

@ -1403,7 +1403,6 @@ static void init_resources()
void Application::initApplication(void)
{
try {
Base::Interpreter().replaceStdOutput();
initTypes();
new Base::ScriptProducer( "FreeCADGuiInit", FreeCADGuiInit );
init_resources();

View File

@ -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);

View File

@ -14,6 +14,14 @@
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
<UserDocu>Describes a parabola in 3D space</UserDocu>
</Documentation>
<Methode Name="compute">
<Documentation>
<UserDocu>
compute(p1,p2,p3)
The three points must lie on a plane parallel to xy plane and must not be collinear
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="Eccentricity" ReadOnly="true">
<Documentation>
<UserDocu>Returns 1. (which is the eccentricity of any parabola).</UserDocu>

View File

@ -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());

View File

@ -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();
}

View File

@ -27,13 +27,16 @@
# include <gp_Trsf.hxx>
# include <gp_Ax1.hxx>
# include <BRepBuilderAPI_MakeShape.hxx>
# include <BRepAlgoAPI_Common.hxx>
# include <TopTools_ListIteratorOfListOfShape.hxx>
# include <TopExp.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
// includes for findAllFacesCutBy()
# include <Standard_Failure.hxx>
# include <TopoDS_Face.hxx>
# include <gp_Dir.hxx>
# include <gp_Pln.hxx> // for Precision::Confusion()
# include <Bnd_Box.hxx>
# include <BRepBndLib.hxx>
#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::cutFaces> 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;
}

View File

@ -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<cutFaces> 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

View File

@ -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:

View File

@ -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();

View File

@ -40,6 +40,7 @@
#include <Mod/Part/App/FeatureFillet.h>
#include <Mod/Part/App/FeatureChamfer.h>
#include <Mod/Part/App/FeatureRevolution.h>
#include <Mod/Part/App/PartFeatures.h>
#include <Gui/Application.h>
#include <Gui/Control.h>
#include <Gui/Document.h>
@ -348,3 +349,49 @@ bool ViewProviderRevolution::onDelete(const std::vector<std::string> &)
return true;
}
// ---------------------------------------
PROPERTY_SOURCE(PartGui::ViewProviderLoft, PartGui::ViewProviderPart)
ViewProviderLoft::ViewProviderLoft()
{
sPixmap = "Part_Loft";
}
ViewProviderLoft::~ViewProviderLoft()
{
}
std::vector<App::DocumentObject*> ViewProviderLoft::claimChildren() const
{
return static_cast<Part::Loft*>(getObject())->Sections.getValues();
}
bool ViewProviderLoft::onDelete(const std::vector<std::string> &)
{
return true;
}
// ---------------------------------------
PROPERTY_SOURCE(PartGui::ViewProviderSweep, PartGui::ViewProviderPart)
ViewProviderSweep::ViewProviderSweep()
{
sPixmap = "Part_Sweep";
}
ViewProviderSweep::~ViewProviderSweep()
{
}
std::vector<App::DocumentObject*> ViewProviderSweep::claimChildren() const
{
return static_cast<Part::Sweep*>(getObject())->Sections.getValues();
}
bool ViewProviderSweep::onDelete(const std::vector<std::string> &)
{
return true;
}

View File

@ -108,6 +108,36 @@ public:
bool onDelete(const std::vector<std::string> &);
};
class ViewProviderLoft : public ViewProviderPart
{
PROPERTY_HEADER(PartGui::ViewProviderLoft);
public:
/// constructor
ViewProviderLoft();
/// destructor
virtual ~ViewProviderLoft();
/// grouping handling
std::vector<App::DocumentObject*> claimChildren(void)const;
bool onDelete(const std::vector<std::string> &);
};
class ViewProviderSweep : public ViewProviderPart
{
PROPERTY_HEADER(PartGui::ViewProviderSweep);
public:
/// constructor
ViewProviderSweep();
/// destructor
virtual ~ViewProviderSweep();
/// grouping handling
std::vector<App::DocumentObject*> claimChildren(void)const;
bool onDelete(const std::vector<std::string> &);
};
} // namespace PartGui

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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();
}

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2010 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

@ -30,8 +30,6 @@
# include <TopExp.hxx>
# include <TopExp_Explorer.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <Bnd_Box.hxx>
# include <BRepBndLib.hxx>
# include <Precision.hxx>
# include <BRepBuilderAPI_Copy.hxx>
#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<TopoDS_Shape> v_transformedShapes; // collect all the transformed shapes for history building
std::vector<TopoDS_Shape> v_transformedShapes; // collect all the transformed shapes for intersection testing
std::list<gp_Trsf>::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<TopoDS_Shape>::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<TopoDS_Shape>::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

View File

@ -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<App::DocumentObject*>& sketches, const bool supportRequired)
{
std::vector<App::DocumentObject*>::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<Part::Part2DObject*>(*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<App::DocumentObject*> Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
Part::Part2DObject* sketch = static_cast<Part::Part2DObject*>(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<App::DocumentObject*> 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<Part::Part2DObject*>(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<App::DocumentObject*> 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<App::DocumentObject*> Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
Part::Part2DObject* sketch = static_cast<Part::Part2DObject*>(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<Part::Part2DObject*>(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<App::DocumentObject*> Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
Part::Part2DObject* sketch = static_cast<Part::Part2DObject*>(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<App::DocumentObject*> 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<Part::Part2DObject*>(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<App::DocumentObject*> Sel = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId());
Part::Part2DObject* sketch = static_cast<Part::Part2DObject*>(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<App::DocumentObject*> 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<Part::Part2DObject*>(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());

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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"

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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"

View File

@ -1,24 +1,24 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* 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 <jrheinlaender@users.sourceforge.net> *
* *
* 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

View File

@ -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})

View File

@ -26,6 +26,9 @@ SET(StartPage_DATA
web.png
blank.png
complete.jpg
Ship.py
Ship.png
ShipExample.png
)
INSTALL(FILES ${StartPage_SRCS}

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

View File

@ -0,0 +1,3 @@
import FreeCADGui
FreeCADGui.activateWorkbench("ShipWorkbench")
App.newDocument()

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -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 <b>Ship Design</b> 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 + """</a>
</li>
<li><img src="Ship.png">&nbsp;
<a onMouseover="show('<h3>""" + text53 + """</h3> \
<p>""" + text54 + """</p><p><small>""" + text21 + """ \
:</small></p><img src=ShipExample.png>')"
onMouseout="show('')"
href="Ship.py">""" + text52 + """</a>
</li>
<li><img src="Mesh.png">&nbsp;
<a onMouseover="show('<h3>""" + text26 + """</h3> \
<p>""" + text27 + """</p><p>""" + text28 + """</p>')"

View File

@ -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

View File

@ -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")

View File

@ -161,6 +161,25 @@
<ComponentRef Id="CompModWeb" />
<ComponentRef Id="CompModOpenSCAD" />
<ComponentRef Id="CompModOpenSCADPly" />
<!-- Ship module -->
<ComponentRef Id="CompModShip" />
<ComponentRef Id="CompModShipExamples" />
<ComponentRef Id="CompModShipIcons" />
<ComponentRef Id="CompModshipAreasCurve" />
<ComponentRef Id="CompModshipCreateShip" />
<ComponentRef Id="CompModshipHydrostatics" />
<ComponentRef Id="CompModshipLoadExample" />
<ComponentRef Id="CompModshipOutlineDraw" />
<ComponentRef Id="CompModshipUtils" />
<ComponentRef Id="CompModsimCreate" />
<ComponentRef Id="CompModsimPost" />
<ComponentRef Id="CompModsimRun" />
<ComponentRef Id="CompModsimRunCL" />
<ComponentRef Id="CompModsimRunNoCL" />
<ComponentRef Id="CompModtankCreateTank" />
<ComponentRef Id="CompModtankGZ" />
<ComponentRef Id="CompModtankWeights" />
<!-- Ship module -->
<ComponentRef Id="CompExampleData" />
<Feature Id="FeatModImage" Title="The Image module" Description="Module to handle pictures" Level="1">

View File

@ -92,6 +92,9 @@
<File Id="StartPage21" Name="LoadMRU1.py" />
<File Id="StartPage22" Name="LoadMRU2.py" />
<File Id="StartPage23" Name="ArchExample.png" />
<File Id="StartPage24" Name="ShipExample.png" />
<File Id="StartPage25" Name="Ship.png" />
<File Id="StartPage26" Name="Ship.py" />
</Component>
</Directory>
</Directory>

View File

@ -38,7 +38,7 @@
<File Id="ShipExampleWigleyKatamaran" Name="wigley_katamaran.fcstd" />
</Component>
</Directory>
<Directory Id="ModShipIcons" Name="ShipIcons" FileSource="../../Mod/Ship/Icons" >
<Directory Id="ModShipIcons" Name="Icons" FileSource="../../Mod/Ship/Icons" >
<Component Id="CompModShipIcons" Guid="ebdaaf8f-b975-4097-9ef8-4ed51ce24adf" Win64='$(var.Win_64)' KeyPath="yes">
<File Id="ShipIcons01" Name="AreaCurveIco.png" />
<File Id="ShipIcons02" Name="DataIco.png" />
@ -80,7 +80,7 @@
<File Id="shipHydrostatics02" Name="Plot.py" />
<File Id="shipHydrostatics03" Name="TaskPanel.py" />
<File Id="shipHydrostatics04" Name="TaskPanel.ui" />
<File Id="shipHydrostatics05" Name="Tools.ui" />
<File Id="shipHydrostatics05" Name="Tools.py" />
</Component>
</Directory>
<Directory Id="ModshipLoadExample" Name="shipLoadExample" FileSource="../../Mod/Ship/shipLoadExample" >
@ -137,11 +137,11 @@
</Directory>
<Directory Id="ModsimRunNoCL" Name="Sim" FileSource="../../Mod/Ship/simRun/Sim" >
<Component Id="CompModsimRunNoCL" Guid="c8655a85-20de-4f30-9924-de34a79ffa2e" Win64='$(var.Win_64)' KeyPath="yes">
<File Id="Sim02" Name="computeSources.py" />
<File Id="Sim01" Name="computeSources.py" />
<File Id="Sim02" Name="fsEvolution.py" />
<File Id="Sim01" Name="__init__.py" />
<File Id="Sim02" Name="initialization.py" />
<File Id="Sim03" Name="matrixGen.py" />
<File Id="Sim03" Name="__init__.py" />
<File Id="Sim04" Name="initialization.py" />
<File Id="Sim05" Name="matrixGen.py" />
</Component>
</Directory>
</Directory>