Merge branch 'master' into logari81/PartDesign

This commit is contained in:
logari81 2012-09-09 10:11:20 +02:00
commit 9f452bd6ca
29 changed files with 789 additions and 701 deletions

View File

@ -1056,6 +1056,7 @@ src/Mod/Sandbox/App/Makefile
src/Mod/Sandbox/Gui/Makefile
src/Mod/Surfaces/Makefile
src/Mod/Ship/Makefile
src/Mod/OpenSCAD/Makefile
src/Tools/Makefile
src/Tools/_TEMPLATE_/Makefile
src/Tools/_TEMPLATE_/App/Makefile

View File

@ -16,14 +16,11 @@ if(FREECAD_BUILD_TEMPLATE)
add_subdirectory(Tools/_TEMPLATE_)
endif(FREECAD_BUILD_TEMPLATE)
if(FREECAD_MAINTAINERS_BUILD)
add_subdirectory(Doc)
endif(FREECAD_MAINTAINERS_BUILD)
if(FREECAD_MAINTAINERS_BUILD AND WIN32)
#add_subdirectory(WindowsInstaller)
endif(FREECAD_MAINTAINERS_BUILD AND WIN32)
INSTALL(FILES Doc/Start_Page.html Doc/freecad.qhc Doc/freecad.qch
DESTINATION ${CMAKE_INSTALL_DOCDIR}
)

View File

@ -49,7 +49,7 @@ if(DOXYGEN_FOUND)
STRING(REGEX REPLACE ";" " " DOXYGEN_EXCLUDE_LIST "${DOXYGEN_EXCLUDE_DIR}")
SET(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/Doc/SourceDocu)
SET(DOXYGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/doc/SourceDocu)
SET(DOXYGEN_IMAGE_PATH ${CMAKE_SOURCE_DIR}/src/Gui/Icons)
SET(DOXYGEN_LAYOUT_FILE ${CMAKE_SOURCE_DIR}/src/Doc/FreecadDoxygenLayout.xml)
@ -66,8 +66,8 @@ if(DOXYGEN_FOUND)
if( FREECAD_MAINTAINERS_BUILD )
ADD_CUSTOM_TARGET(SourceDocu
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/BuildDevDoc.cfg
COMMAND ${QT_HELPCOMPILER_EXECUTABLE} "\"${CMAKE_BINARY_DIR}/Doc/SourceDocu/html/index.qhp\""
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/Doc/SourceDocu/html/index.qch ${CMAKE_BINARY_DIR}/Doc/FreeCADSource.qch
COMMAND ${QT_HELPCOMPILER_EXECUTABLE} "\"${CMAKE_BINARY_DIR}/doc/SourceDocu/html/index.qhp\""
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/doc/SourceDocu/html/index.qch ${CMAKE_BINARY_DIR}/doc/FreeCADSource.qch
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/BuildDevDoc.cfg
)
@ -77,7 +77,7 @@ if(DOXYGEN_FOUND)
${CMAKE_SOURCE_DIR}/src/Tools/wiki2qhelp.py
-c ${QT_HELPCOMPILER_EXECUTABLE}
-g ${QT_COLLECTIOMGENERATOR_EXECUTABLE}
-o ${CMAKE_BINARY_DIR}/Doc
-o ${CMAKE_BINARY_DIR}/doc
)
else( FREECAD_MAINTAINERS_BUILD )

View File

@ -69,6 +69,12 @@ EXTRA_DIST = \
accessories-text-editor.svg \
help-browser.svg \
spaceball_button.svg \
SpNav-PanLR.png \
SpNav-PanUD.png \
SpNav-Roll.png \
SpNav-Spin.png \
SpNav-Tilt.png \
SpNav-Zoom.png \
view-unselectable.svg \
view-refresh.svg \
view-measurement.svg \

View File

@ -13,6 +13,7 @@ BUILT_SOURCES=\
moc_DlgCommandsImp.cpp \
moc_DlgCustomizeImp.cpp \
moc_DlgCustomizeSpaceball.cpp \
moc_DlgCustomizeSpNavSettings.cpp \
moc_DlgDisplayPropertiesImp.cpp \
moc_DlgEditorImp.cpp \
moc_DlgGeneralImp.cpp \
@ -84,6 +85,7 @@ BUILT_SOURCES=\
ui_DlgAuthorization.h \
ui_DlgChooseIcon.h \
ui_DlgCommands.h \
ui_DlgCustomizeSpNavSettings.h \
ui_DlgDisplayProperties.h \
ui_DlgEditor.h \
ui_DlgInputDialog.h \
@ -133,6 +135,7 @@ libFreeCADGui_la_UI=\
DlgAuthorization.ui \
DlgChooseIcon.ui \
DlgCommands.ui \
DlgCustomizeSpNavSettings.ui \
DlgDisplayProperties.ui \
DlgEditor.ui \
DlgGeneral.ui \
@ -208,6 +211,8 @@ libFreeCADGui_la_SOURCES=\
DlgCustomizeImp.h \
DlgCustomizeSpaceball.cpp \
DlgCustomizeSpaceball.h \
DlgCustomizeSpNavSettings.cpp \
DlgCustomizeSpNavSettings.h \
DlgDisplayPropertiesImp.cpp \
DlgDisplayPropertiesImp.h \
DlgEditorImp.cpp \

View File

@ -59,7 +59,29 @@ using namespace Gui;
namespace Gui
{
static size_t promptLength = 4; //< length of prompt string: ">>> " or "... ", in either case 4 characters
static const QChar promptEnd( QLatin1Char(' ') ); //< char for detecting prompt end
inline int promptLength( const QString &lineStr )
{ return lineStr.indexOf( promptEnd ) + 1; }
inline QString stripPromptFrom( const QString &lineStr )
{ return lineStr.mid( promptLength(lineStr) ); }
/**
* cursorBeyond checks if cursor is at a valid position to accept keyEvents.
* @param cursor - cursor to check
* @param limit - cursor that marks the begin of the input region
* @param shift - offset for shifting the limit for non-selection cursors [default: 0]
* @return true if a keyEvent is ok at cursor's position, false otherwise
*/
inline bool cursorBeyond( const QTextCursor &cursor, const QTextCursor &limit, int shift = 0 )
{
int pos = limit.position();
if (cursor.hasSelection())
return (cursor.selectionStart() >= pos && cursor.selectionEnd() >= pos);
else
return cursor.position() >= (pos + shift);
}
struct PythonConsoleP
{
@ -341,7 +363,7 @@ void InteractiveInterpreter::clearBuffer()
* Constructs a PythonConsole which is a child of 'parent'.
*/
PythonConsole::PythonConsole(QWidget *parent)
: TextEdit(parent), WindowParameter( "Editor" )
: TextEdit(parent), WindowParameter( "Editor" ), _sourceDrain(NULL)
{
d = new PythonConsoleP();
d->interactive = false;
@ -445,7 +467,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
QTextCursor cursor = this->textCursor();
QTextCursor inputLineBegin = this->inputBegin();
if (cursor < inputLineBegin)
if (!cursorBeyond( cursor, inputLineBegin ))
{
/**
* The cursor is placed not on the input line (or within the prompt string)
@ -460,6 +482,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
case Qt::Key_Return:
case Qt::Key_Enter:
case Qt::Key_Escape:
case Qt::Key_Backspace:
this->moveCursor( QTextCursor::End );
break;
@ -488,17 +511,18 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
* - show call tips on period
*/
QTextBlock inputBlock = inputLineBegin.block(); //< get the last paragraph's text
QString inputLine = inputBlock.text().mid(promptLength); //< and skip prompt characters
QString inputLine = inputBlock.text();
QString inputStrg = stripPromptFrom( inputLine );
switch (e->key())
{
case Qt::Key_Escape:
{
// disable current input line - i.e. put it to history but don't execute it.
if (!inputLine.isEmpty())
// disable current input string - i.e. put it to history but don't execute it.
if (!inputStrg.isEmpty())
{
d->history.append( QLatin1String("# ") + inputLine ); //< put line to history ...
inputLineBegin.insertText( QString::fromAscii("# ") ); //< but comment it on console
d->history.append( QLatin1String("# ") + inputStrg ); //< put commented string to history ...
inputLineBegin.insertText( QString::fromAscii("# ") ); //< and comment it on console
setTextCursor( inputLineBegin );
printPrompt(d->interpreter->hasPendingInput() //< print adequate prompt
? PythonConsole::Incomplete
@ -509,8 +533,8 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
case Qt::Key_Return:
case Qt::Key_Enter:
{
runSource( inputLine ); //< commit input line
d->history.append( inputLine ); //< put statement to history
d->history.append( inputStrg ); //< put statement to history
runSource( inputStrg ); //< commit input string
} break;
case Qt::Key_Period:
@ -518,14 +542,14 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
// analyse context and show available call tips
int contextLength = cursor.position() - inputLineBegin.position();
TextEdit::keyPressEvent(e);
d->callTipsList->showTips( inputLine.left( contextLength ) );
d->callTipsList->showTips( inputStrg.left( contextLength ) );
} break;
case Qt::Key_Home:
{
QTextCursor::MoveMode mode = (e->modifiers() & Qt::ShiftModifier)? QTextCursor::KeepAnchor
/* else */ : QTextCursor::MoveAnchor;
cursor.setPosition( inputBlock.position() + promptLength, mode );
cursor.setPosition( inputLineBegin.position(), mode );
setTextCursor( cursor );
ensureCursorVisible();
} break;
@ -533,7 +557,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
case Qt::Key_Up:
{
// if possible, move back in history
if (d->history.prev( inputLine ))
if (d->history.prev( inputStrg ))
{ overrideCursor( d->history.value() ); }
restartHistory = false;
} break;
@ -561,7 +585,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
case Qt::Key_Backspace:
{
if (cursor > inputLineBegin)
if (cursorBeyond( cursor, inputLineBegin, +1 ))
{ TextEdit::keyPressEvent(e); }
} break;
@ -576,7 +600,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
{ d->callTipsList->validateCursor(); }
// disable history restart if input line changed
restartHistory &= (inputLine != inputBlock.text().mid(promptLength));
restartHistory &= (inputLine != inputBlock.text());
}
// any cursor move resets the history to its latest item.
if (restartHistory)
@ -623,6 +647,8 @@ void PythonConsole::printPrompt(PythonConsole::Prompt mode)
d->error = QString::null;
}
if (mode != PythonConsole::Special)
{
// Append the prompt string
QTextCursor cursor = textCursor();
cursor.beginEditBlock();
@ -655,6 +681,7 @@ void PythonConsole::printPrompt(PythonConsole::Prompt mode)
cursor.movePosition(QTextCursor::End);
setTextCursor(cursor);
}
}
/**
* Appends \a output to the console and set \a state as user state to
@ -683,6 +710,17 @@ void PythonConsole::appendOutput(const QString& output, int state)
*/
void PythonConsole::runSource(const QString& line)
{
/**
* Check if there's a "source drain", which want's to consume the source in another way then just executing it.
* If so, put the source to the drain and emit a signal to notify the consumer, whoever this may be.
*/
if (this->_sourceDrain)
{
*this->_sourceDrain = line;
Q_EMIT pendingSource();
return;
}
bool incomplete = false;
Base::PyGILStateLocker lock;
PyObject* default_stdout = PySys_GetObject("stdout");
@ -692,8 +730,11 @@ void PythonConsole::runSource(const QString& line)
d->interactive = true;
try {
d->history.markScratch(); //< mark current history position ...
// launch the command now
incomplete = d->interpreter->push(line.toUtf8());
if (!incomplete)
{ d->history.doScratch(); } //< ... and scratch history entries that might have been added by executing the line.
setFocus(); // if focus was lost
}
catch (const Base::SystemExitException&) {
@ -923,7 +964,8 @@ QTextCursor PythonConsole::inputBegin( void ) const
QTextCursor inputLineBegin( this->textCursor() );
inputLineBegin.movePosition( QTextCursor::End );
inputLineBegin.movePosition( QTextCursor::StartOfLine );
inputLineBegin.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, promptLength );
// ... and move cursor right beyond the prompt.
inputLineBegin.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, promptLength( inputLineBegin.block().text() ) );
return inputLineBegin;
}
@ -948,10 +990,7 @@ QMimeData * PythonConsole::createMimeDataFromSelection () const
int pos = b.position();
if ( pos >= s && pos <= e ) {
if (b.userState() > -1 && b.userState() < pythonSyntax->maximumUserState()) {
QString line = b.text();
// and skip the prompt characters consisting of either ">>> " or "... "
line = line.mid(promptLength);
lines << line;
lines << stripPromptFrom( b.text() );
}
}
}
@ -1020,8 +1059,7 @@ void PythonConsole::runSourceFromMimeData(const QString& source)
QString select = cursor.selectedText();
cursor.removeSelectedText();
last = last + select;
line = cursor.block().text();
line = line.mid(promptLength);
line = stripPromptFrom( cursor.block().text() );
}
// put statement to the history
@ -1073,12 +1111,10 @@ void PythonConsole::runSourceFromMimeData(const QString& source)
void PythonConsole::overrideCursor(const QString& txt)
{
// Go to the last line and the fourth position, right after the prompt
QTextCursor cursor = textCursor();
QTextBlock block = cursor.block();
cursor.movePosition(QTextCursor::End);
cursor.movePosition(QTextCursor::StartOfLine);
cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, promptLength);
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, block.text().length());
QTextCursor cursor = this->inputBegin();
int blockLength = this->textCursor().block().text().length();
cursor.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor, blockLength ); //<< select text to override
cursor.removeSelectedText();
cursor.insertText(txt);
// move cursor to the end
@ -1090,12 +1126,7 @@ void PythonConsole::contextMenuEvent ( QContextMenuEvent * e )
{
QMenu menu(this);
QAction *a;
// construct reference cursor at begin of input line ...
QTextCursor cursor = this->textCursor();
QTextCursor inputLineBegin = cursor;
inputLineBegin.movePosition(QTextCursor::End);
inputLineBegin.movePosition(QTextCursor::StartOfLine);
inputLineBegin.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, promptLength);
bool mayPasteHere = cursorBeyond( this->textCursor(), this->inputBegin() );
a = menu.addAction(tr("&Copy"), this, SLOT(copy()), Qt::CTRL+Qt::Key_C);
a->setEnabled(textCursor().hasSelection());
@ -1113,7 +1144,7 @@ void PythonConsole::contextMenuEvent ( QContextMenuEvent * e )
a = menu.addAction(tr("&Paste"), this, SLOT(paste()), Qt::CTRL+Qt::Key_V);
const QMimeData *md = QApplication::clipboard()->mimeData();
a->setEnabled(cursor >= inputLineBegin && md && canInsertFromMimeData(md));
a->setEnabled( mayPasteHere && md && canInsertFromMimeData(md));
a = menu.addAction(tr("Select All"), this, SLOT(selectAll()), Qt::CTRL+Qt::Key_A);
a->setEnabled(!document()->isEmpty());
@ -1195,6 +1226,20 @@ void PythonConsole::onCopyCommand()
d->type = PythonConsoleP::Normal;
}
QString PythonConsole::readline( void )
{
QEventLoop loop;
QString inputBuffer;
printPrompt( PythonConsole::Special );
this->_sourceDrain = &inputBuffer; //< enable source drain ...
// ... and wait until we get notified about pendingSource
QObject::connect( this, SIGNAL(pendingSource()), &loop, SLOT(quit()) );
loop.exec();
this->_sourceDrain = NULL; //< disable source drain
return inputBuffer.append(QChar::fromAscii('\n')); //< pass a newline here, since the readline-caller may need it!
}
// ---------------------------------------------------------------------
PythonConsoleHighlighter::PythonConsoleHighlighter(QObject* parent)
@ -1245,6 +1290,7 @@ void PythonConsoleHighlighter::colorChanged(const QString& type, const QColor& c
// ---------------------------------------------------------------------
ConsoleHistory::ConsoleHistory()
: _scratchBegin(0)
{
_it = _history.end();
}
@ -1345,6 +1391,28 @@ void ConsoleHistory::restart( void )
_it = _history.end();
}
/**
* markScratch stores the current end index of the history list.
* Note: with simply remembering a start index, it does not work to nest scratch regions.
* However, just replace the index keeping by a stack - in case this is be a concern.
*/
void ConsoleHistory::markScratch( void )
{
_scratchBegin = _history.length();
}
/**
* doScratch removes the tail of the history list, starting from the index marked lately.
*/
void ConsoleHistory::doScratch( void )
{
if (_scratchBegin < _history.length())
{
_history.erase( _history.begin() + _scratchBegin, _history.end() );
this->restart();
}
}
// -----------------------------------------------------
/* TRANSLATOR Gui::PythonInputField */

View File

@ -79,10 +79,13 @@ public:
void append(const QString &inputLine);
const QStringList& values() const;
void restart();
void markScratch( void );
void doScratch( void );
private:
QStringList _history;
QStringList::ConstIterator _it;
int _scratchBegin;
QString _prefix;
};
@ -99,7 +102,8 @@ public:
enum Prompt {
Complete = 0,
Incomplete = 1,
Flush = 2
Flush = 2,
Special = 3
};
PythonConsole(QWidget *parent = 0);
@ -107,6 +111,7 @@ public:
void OnChange( Base::Subject<const char*> &rCaller,const char* rcReason );
void printStatement( const QString& cmd );
QString readline( void );
public Q_SLOTS:
void onSaveHistoryAs();
@ -146,6 +151,9 @@ private:
void runSourceFromMimeData(const QString&);
void appendOutput(const QString&, int);
Q_SIGNALS:
void pendingSource( void );
private:
struct PythonConsoleP* d;
@ -154,6 +162,7 @@ private:
private:
PythonConsoleHighlighter* pythonSyntax;
QString *_sourceDrain;
};
/**

View File

@ -317,16 +317,5 @@ Py::Object PythonStdin::repr()
Py::Object PythonStdin::readline(const Py::Tuple& args)
{
if (console)
console->onFlush();
timer->stop();
QEventLoop loop;
QObject::connect(editField, SIGNAL(textEntered()), &loop, SLOT(quit()));
editField->clear();
editField->show();
editField->setFocus();
loop.exec();
QString txt = editField->getText();
timer->start();
return Py::String((const char*)txt.toAscii());
return Py::String( (const char *)console->readline().toAscii() );
}

View File

@ -1,5 +1,5 @@
#SUBDIRS=Part Mesh Points Raytracing Image Drawing Complete Draft Test TemplatePyMod
SUBDIRS=Points Complete Draft Test TemplatePyMod Web Start Idf Arch Surfaces Ship OpenSCAD
SUBDIRS=Points Complete Draft Test TemplatePyMod Web Start Idf
#if HAVE_OPENCV
SUBDIRS += Image
@ -10,7 +10,7 @@ SUBDIRS += Mesh
#endif
if HAVE_OPENCASCADE
SUBDIRS += Part Import PartDesign Raytracing Drawing
SUBDIRS += Part Import PartDesign Raytracing Drawing Arch Surfaces Ship OpenSCAD
endif
if HAVE_EIGEN3

View File

@ -52,11 +52,9 @@ Chamfer::Chamfer()
short Chamfer::mustExecute() const
{
if (Placement.isTouched() || Base.isTouched() || Size.isTouched())
if (Placement.isTouched() || Size.isTouched())
return 1;
if (Base.getValue() && Base.getValue()->isTouched())
return 1;
return 0;
return DressUp::mustExecute();
}
App::DocumentObjectExecReturn *Chamfer::execute(void)

View File

@ -41,6 +41,14 @@ DressUp::DressUp()
ADD_PROPERTY(Base,(0));
}
short DressUp::mustExecute() const
{
if (Base.getValue() && Base.getValue()->isTouched())
return 1;
return PartDesign::Feature::mustExecute();
}
void DressUp::positionByBase(void)
{
Part::Feature *base = static_cast<Part::Feature*>(Base.getValue());

View File

@ -39,6 +39,7 @@ public:
App::PropertyLinkSub Base;
short mustExecute() const;
/// updates the Placement property from the Placement of Base
void positionByBase(void);

View File

@ -62,7 +62,7 @@ short Face::mustExecute() const
{
if (Sources.isTouched())
return 1;
return 0;
return Part::Part2DObject::mustExecute();
}
App::DocumentObjectExecReturn *Face::execute(void)

View File

@ -49,11 +49,9 @@ Fillet::Fillet()
short Fillet::mustExecute() const
{
if (Placement.isTouched() || Base.isTouched() || Radius.isTouched())
if (Placement.isTouched() || Radius.isTouched())
return 1;
if (Base.getValue() && Base.getValue()->isTouched())
return 1;
return 0;
return DressUp::mustExecute();
}
App::DocumentObjectExecReturn *Fillet::execute(void)

View File

@ -48,7 +48,7 @@ using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Groove, PartDesign::SketchBased)
PROPERTY_SOURCE(PartDesign::Groove, PartDesign::Subtractive)
Groove::Groove()
{
@ -63,7 +63,6 @@ Groove::Groove()
short Groove::mustExecute() const
{
if (Placement.isTouched() ||
Sketch.isTouched() ||
ReferenceAxis.isTouched() ||
Axis.isTouched() ||
Base.isTouched() ||
@ -71,7 +70,7 @@ short Groove::mustExecute() const
Midplane.isTouched() ||
Reversed.isTouched())
return 1;
return 0;
return Subtractive::mustExecute();
}
App::DocumentObjectExecReturn *Groove::execute(void)

View File

@ -25,12 +25,12 @@
#define PARTDESIGN_Groove_H
#include <App/PropertyUnits.h>
#include "FeatureSketchBased.h"
#include "FeatureSubtractive.h"
namespace PartDesign
{
class PartDesignExport Groove : public SketchBased
class PartDesignExport Groove : public Subtractive
{
PROPERTY_HEADER(PartDesign::Groove);

View File

@ -53,7 +53,7 @@ const char* Hole::TypeEnums[] = {"Dimension","UpToLast","UpToFirst",NULL};
const char* Hole::HoleTypeEnums[]= {"Simple","Counterbore","Countersunk",NULL};
const char* Hole::ThreadEnums[] = {"None","Metric","MetricFine",NULL};
PROPERTY_SOURCE(PartDesign::Hole, PartDesign::SketchBased)
PROPERTY_SOURCE(PartDesign::Hole, PartDesign::Subtractive)
Hole::Hole()
{
@ -72,7 +72,7 @@ Hole::Hole()
// if (Sketch.isTouched() ||
// Length.isTouched())
// return 1;
// return 0;
// return Subtractive::mustExecute();
//}
App::DocumentObjectExecReturn *Hole::execute(void)
@ -134,6 +134,8 @@ App::DocumentObjectExecReturn *Hole::execute(void)
//if (PrismMaker.IsDone()) {
// // if the sketch has a support fuse them to get one result object (PAD!)
// if (SupportObject) {
// // Set the subtractive shape property for later usage in e.g. pattern
// this->SubShape.setValue(PrismMaker.Shape());
// const TopoDS_Shape& support = SupportObject->Shape.getValue();
// if (support.IsNull())
// return new App::DocumentObjectExecReturn("Support shape is invalid");

View File

@ -68,14 +68,13 @@ Pad::Pad()
short Pad::mustExecute() const
{
if (Placement.isTouched() ||
Sketch.isTouched() ||
Length.isTouched() ||
Midplane.isTouched() ||
Reversed.isTouched() ||
Length2.isTouched() ||
FaceName.isTouched())
return 1;
return 0;
return Additive::mustExecute();
}
App::DocumentObjectExecReturn *Pad::execute(void)

View File

@ -56,7 +56,7 @@ using namespace PartDesign;
const char* Pocket::TypeEnums[]= {"Length","UpToLast","UpToFirst","ThroughAll","UpToFace",NULL};
PROPERTY_SOURCE(PartDesign::Pocket, PartDesign::SketchBased)
PROPERTY_SOURCE(PartDesign::Pocket, PartDesign::Subtractive)
Pocket::Pocket()
{
@ -69,11 +69,10 @@ Pocket::Pocket()
short Pocket::mustExecute() const
{
if (Placement.isTouched() ||
Sketch.isTouched() ||
Length.isTouched() ||
FaceName.isTouched())
return 1;
return 0;
return Subtractive::mustExecute();
}
App::DocumentObjectExecReturn *Pocket::execute(void)
@ -255,8 +254,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void)
return new App::DocumentObjectExecReturn("Internal error: Unknown type for Pocket feature");
}
// TODO: Set the subtractive shape property for later usage in e.g. pattern
//this->SubShape.setValue(prism); // This crashes with "Illegal storage access". Why?
this->SubShape.setValue(prism);
// Cut out the pocket
BRepAlgoAPI_Cut mkCut(support.Moved(invObjLoc), prism);

View File

@ -48,7 +48,7 @@ using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::SketchBased)
PROPERTY_SOURCE(PartDesign::Revolution, PartDesign::Additive)
Revolution::Revolution()
{
@ -63,7 +63,6 @@ Revolution::Revolution()
short Revolution::mustExecute() const
{
if (Placement.isTouched() ||
Sketch.isTouched() ||
ReferenceAxis.isTouched() ||
Axis.isTouched() ||
Base.isTouched() ||
@ -71,7 +70,7 @@ short Revolution::mustExecute() const
Midplane.isTouched() ||
Reversed.isTouched())
return 1;
return 0;
return Additive::mustExecute();
}
App::DocumentObjectExecReturn *Revolution::execute(void)
@ -183,6 +182,8 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
if (SupportObject) {
const TopoDS_Shape& support = SupportObject->Shape.getValue();
if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) {
// set the additive shape property for later usage in e.g. pattern
this->AddShape.setValue(result);
// Let's call algorithm computing a fuse operation:
BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), result);
// Let's check if the fusion has been successful

View File

@ -25,12 +25,12 @@
#define PARTDESIGN_Revolution_H
#include <App/PropertyUnits.h>
#include "FeatureSketchBased.h"
#include "FeatureAdditive.h"
namespace PartDesign
{
class PartDesignExport Revolution : public SketchBased
class PartDesignExport Revolution : public Additive
{
PROPERTY_HEADER(PartDesign::Revolution);

View File

@ -77,6 +77,13 @@ SketchBased::SketchBased()
ADD_PROPERTY(Sketch,(0));
}
short SketchBased::mustExecute() const
{
if (Sketch.isTouched())
return 1;
return 0; // PartDesign::Feature::mustExecute();
}
void SketchBased::positionBySketch(void)
{
Part::Part2DObject *sketch = static_cast<Part::Part2DObject*>(Sketch.getValue());

View File

@ -42,6 +42,8 @@ public:
App::PropertyLink Sketch;
short mustExecute() const;
/** calculates and updates the Placement property based on the Sketch
* or its support if it has one
*/

View File

@ -24,7 +24,8 @@
import os
# FreeCAD modules
import FreeCAD,FreeCADGui
from FreeCAD import Base, Image, ImageGui
from FreeCAD import Base
import Image, ImageGui
# FreeCADShip modules
from shipUtils import Paths, Translator

View File

@ -26,8 +26,7 @@ import math
# FreeCAD modules
import FreeCAD,FreeCADGui
from FreeCAD import Base, Vector
from FreeCAD import Image, ImageGui
import Part
import Part, Image, ImageGui
# FreeCADShip modules
from shipUtils import Paths, Translator
import Tools

View File

@ -51,7 +51,7 @@ def Plot(scale, sections, shape):
x0 = xMid - 0.5*xTot
y0 = 297.0 - yMid - 0.5*yTot # 297 = A3_width
# Get border
edges = self.getEdges([shape])
edges = getEdges([shape])
border = edges[0]
for i in range(0,len(edges)):
border = border.oldFuse(edges[i]) # Only group objects, don't try to build more complex entities
@ -95,7 +95,7 @@ def Plot(scale, sections, shape):
FreeCAD.ActiveDocument.recompute()
return obj
def getEdges(self, objs=None):
def getEdges(objs=None):
""" Returns object edges (list of them)
@param objs Object to get the faces, none if selected
object may used.

View File

@ -24,8 +24,8 @@
import os
# FreeCAD modules
import FreeCAD,FreeCADGui
from FreeCAD import Base, Image, ImageGui
import Part
from FreeCAD import Base
import Part, Image, ImageGui
# FreeCADShip modules
from shipUtils import Paths, Translator