Merge remote-tracking branch 'origin/master' into logari81/PartDesign
This commit is contained in:
commit
e1727b6c16
|
@ -166,6 +166,9 @@ QStringList BitmapFactoryInst::findIconFiles() const
|
|||
files << it->absoluteFilePath();
|
||||
}
|
||||
|
||||
#if QT_VERSION >= 0x040500
|
||||
files.removeDuplicates();
|
||||
#endif
|
||||
return files;
|
||||
}
|
||||
|
||||
|
|
|
@ -384,7 +384,8 @@ IconDialog::IconDialog(QWidget* parent)
|
|||
QStringList names = BitmapFactory().findIconFiles();
|
||||
for (QStringList::Iterator it = names.begin(); it != names.end(); ++it) {
|
||||
item = new QListWidgetItem(ui->listWidget);
|
||||
item->setIcon(QIcon(*it));
|
||||
//item->setIcon(QIcon(*it));
|
||||
item->setIcon(QIcon(BitmapFactory().pixmap((const char*)it->toUtf8())));
|
||||
item->setText(QFileInfo(*it).baseName());
|
||||
item->setToolTip(*it);
|
||||
}
|
||||
|
|
|
@ -59,29 +59,29 @@ using namespace Gui;
|
|||
namespace Gui
|
||||
{
|
||||
|
||||
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);
|
||||
}
|
||||
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
|
||||
{
|
||||
|
@ -363,7 +363,7 @@ void InteractiveInterpreter::clearBuffer()
|
|||
* Constructs a PythonConsole which is a child of 'parent'.
|
||||
*/
|
||||
PythonConsole::PythonConsole(QWidget *parent)
|
||||
: TextEdit(parent), WindowParameter( "Editor" ), _sourceDrain(NULL)
|
||||
: TextEdit(parent), WindowParameter( "Editor" ), _sourceDrain(NULL)
|
||||
{
|
||||
d = new PythonConsoleP();
|
||||
d->interactive = false;
|
||||
|
@ -464,10 +464,10 @@ void PythonConsole::OnChange( Base::Subject<const char*> &rCaller,const char* sR
|
|||
void PythonConsole::keyPressEvent(QKeyEvent * e)
|
||||
{
|
||||
bool restartHistory = true;
|
||||
QTextCursor cursor = this->textCursor();
|
||||
QTextCursor inputLineBegin = this->inputBegin();
|
||||
QTextCursor cursor = this->textCursor();
|
||||
QTextCursor inputLineBegin = this->inputBegin();
|
||||
|
||||
if (!cursorBeyond( cursor, inputLineBegin ))
|
||||
if (!cursorBeyond( cursor, inputLineBegin ))
|
||||
{
|
||||
/**
|
||||
* The cursor is placed not on the input line (or within the prompt string)
|
||||
|
@ -482,7 +482,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Escape:
|
||||
case Qt::Key_Backspace:
|
||||
case Qt::Key_Backspace:
|
||||
this->moveCursor( QTextCursor::End );
|
||||
break;
|
||||
|
||||
|
@ -511,20 +511,20 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
* - show call tips on period
|
||||
*/
|
||||
QTextBlock inputBlock = inputLineBegin.block(); //< get the last paragraph's text
|
||||
QString inputLine = inputBlock.text();
|
||||
QString inputStrg = stripPromptFrom( inputLine );
|
||||
QString inputLine = inputBlock.text();
|
||||
QString inputStrg = stripPromptFrom( inputLine );
|
||||
|
||||
switch (e->key())
|
||||
{
|
||||
case Qt::Key_Escape:
|
||||
{
|
||||
// disable current input string - i.e. put it to history but don't execute it.
|
||||
if (!inputStrg.isEmpty())
|
||||
// disable current input string - i.e. put it to history but don't execute it.
|
||||
if (!inputStrg.isEmpty())
|
||||
{
|
||||
d->history.append( QLatin1String("# ") + inputStrg ); //< put commented string to history ...
|
||||
inputLineBegin.insertText( QString::fromAscii("# ") ); //< and 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
|
||||
printPrompt(d->interpreter->hasPendingInput() //< print adequate prompt
|
||||
? PythonConsole::Incomplete
|
||||
: PythonConsole::Complete);
|
||||
}
|
||||
|
@ -533,8 +533,8 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
{
|
||||
d->history.append( inputStrg ); //< put statement to history
|
||||
runSource( inputStrg ); //< commit input string
|
||||
d->history.append( inputStrg ); //< put statement to history
|
||||
runSource( inputStrg ); //< commit input string
|
||||
} break;
|
||||
|
||||
case Qt::Key_Period:
|
||||
|
@ -542,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( inputStrg.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( inputLineBegin.position(), mode );
|
||||
cursor.setPosition( inputLineBegin.position(), mode );
|
||||
setTextCursor( cursor );
|
||||
ensureCursorVisible();
|
||||
} break;
|
||||
|
@ -557,7 +557,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
case Qt::Key_Up:
|
||||
{
|
||||
// if possible, move back in history
|
||||
if (d->history.prev( inputStrg ))
|
||||
if (d->history.prev( inputStrg ))
|
||||
{ overrideCursor( d->history.value() ); }
|
||||
restartHistory = false;
|
||||
} break;
|
||||
|
@ -585,7 +585,7 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
|
||||
case Qt::Key_Backspace:
|
||||
{
|
||||
if (cursorBeyond( cursor, inputLineBegin, +1 ))
|
||||
if (cursorBeyond( cursor, inputLineBegin, +1 ))
|
||||
{ TextEdit::keyPressEvent(e); }
|
||||
} break;
|
||||
|
||||
|
@ -598,9 +598,9 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
|||
// the event and afterwards update the list widget
|
||||
if (d->callTipsList->isVisible())
|
||||
{ d->callTipsList->validateCursor(); }
|
||||
|
||||
// disable history restart if input line changed
|
||||
restartHistory &= (inputLine != inputBlock.text());
|
||||
|
||||
// disable history restart if input line changed
|
||||
restartHistory &= (inputLine != inputBlock.text());
|
||||
}
|
||||
// any cursor move resets the history to its latest item.
|
||||
if (restartHistory)
|
||||
|
@ -647,40 +647,40 @@ void PythonConsole::printPrompt(PythonConsole::Prompt mode)
|
|||
d->error = QString::null;
|
||||
}
|
||||
|
||||
if (mode != PythonConsole::Special)
|
||||
{
|
||||
// Append the prompt string
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.beginEditBlock();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
QTextBlock block = cursor.block();
|
||||
|
||||
// Python's print command appends a trailing '\n' to the system output.
|
||||
// In this case, however, we should not add a new text block. We force
|
||||
// the current block to be normal text (user state = 0) to be highlighted
|
||||
// correctly and append the '>>> ' or '... ' to this block.
|
||||
if (block.length() > 1)
|
||||
cursor.insertBlock(cursor.blockFormat(), cursor.charFormat());
|
||||
else
|
||||
block.setUserState(0);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PythonConsole::Incomplete:
|
||||
cursor.insertText(QString::fromAscii("... "));
|
||||
break;
|
||||
case PythonConsole::Complete:
|
||||
cursor.insertText(QString::fromAscii(">>> "));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
// Append the prompt string
|
||||
QTextCursor cursor = textCursor();
|
||||
|
||||
// move cursor to the end
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
if (mode != PythonConsole::Special)
|
||||
{
|
||||
cursor.beginEditBlock();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
QTextBlock block = cursor.block();
|
||||
|
||||
// Python's print command appends a trailing '\n' to the system output.
|
||||
// In this case, however, we should not add a new text block. We force
|
||||
// the current block to be normal text (user state = 0) to be highlighted
|
||||
// correctly and append the '>>> ' or '... ' to this block.
|
||||
if (block.length() > 1)
|
||||
cursor.insertBlock(cursor.blockFormat(), cursor.charFormat());
|
||||
else
|
||||
block.setUserState(0);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PythonConsole::Incomplete:
|
||||
cursor.insertText(QString::fromAscii("... "));
|
||||
break;
|
||||
case PythonConsole::Complete:
|
||||
cursor.insertText(QString::fromAscii(">>> "));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
// move cursor to the end
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -710,17 +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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
|
@ -730,11 +730,11 @@ void PythonConsole::runSource(const QString& line)
|
|||
d->interactive = true;
|
||||
|
||||
try {
|
||||
d->history.markScratch(); //< mark current history position ...
|
||||
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.
|
||||
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&) {
|
||||
|
@ -845,21 +845,21 @@ void PythonConsole::changeEvent(QEvent *e)
|
|||
TextEdit::changeEvent(e);
|
||||
}
|
||||
|
||||
void PythonConsole::mouseReleaseEvent( QMouseEvent *e )
|
||||
{
|
||||
TextEdit::mouseReleaseEvent( e );
|
||||
if (e->button() == Qt::LeftButton)
|
||||
{
|
||||
QTextCursor cursor = this->textCursor();
|
||||
if (cursor.hasSelection() == false
|
||||
&& cursor < this->inputBegin())
|
||||
{
|
||||
cursor.movePosition( QTextCursor::End );
|
||||
this->setTextCursor( cursor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PythonConsole::mouseReleaseEvent( QMouseEvent *e )
|
||||
{
|
||||
TextEdit::mouseReleaseEvent( e );
|
||||
if (e->button() == Qt::LeftButton)
|
||||
{
|
||||
QTextCursor cursor = this->textCursor();
|
||||
if (cursor.hasSelection() == false
|
||||
&& cursor < this->inputBegin())
|
||||
{
|
||||
cursor.movePosition( QTextCursor::End );
|
||||
this->setTextCursor( cursor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the event \a e and writes the right Python command.
|
||||
*/
|
||||
|
@ -958,17 +958,17 @@ void PythonConsole::insertFromMimeData (const QMimeData * source)
|
|||
}
|
||||
}
|
||||
|
||||
QTextCursor PythonConsole::inputBegin( void ) const
|
||||
{
|
||||
// construct cursor at begin of input line ...
|
||||
QTextCursor inputLineBegin( this->textCursor() );
|
||||
inputLineBegin.movePosition( QTextCursor::End );
|
||||
inputLineBegin.movePosition( QTextCursor::StartOfLine );
|
||||
// ... and move cursor right beyond the prompt.
|
||||
inputLineBegin.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, promptLength( inputLineBegin.block().text() ) );
|
||||
return inputLineBegin;
|
||||
}
|
||||
|
||||
QTextCursor PythonConsole::inputBegin( void ) const
|
||||
{
|
||||
// construct cursor at begin of input line ...
|
||||
QTextCursor inputLineBegin( this->textCursor() );
|
||||
inputLineBegin.movePosition( QTextCursor::End );
|
||||
inputLineBegin.movePosition( QTextCursor::StartOfLine );
|
||||
// ... and move cursor right beyond the prompt.
|
||||
inputLineBegin.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, promptLength( inputLineBegin.block().text() ) );
|
||||
return inputLineBegin;
|
||||
}
|
||||
|
||||
QMimeData * PythonConsole::createMimeDataFromSelection () const
|
||||
{
|
||||
QMimeData* mime = new QMimeData();
|
||||
|
@ -990,7 +990,7 @@ QMimeData * PythonConsole::createMimeDataFromSelection () const
|
|||
int pos = b.position();
|
||||
if ( pos >= s && pos <= e ) {
|
||||
if (b.userState() > -1 && b.userState() < pythonSyntax->maximumUserState()) {
|
||||
lines << stripPromptFrom( b.text() );
|
||||
lines << stripPromptFrom( b.text() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1059,7 +1059,7 @@ void PythonConsole::runSourceFromMimeData(const QString& source)
|
|||
QString select = cursor.selectedText();
|
||||
cursor.removeSelectedText();
|
||||
last = last + select;
|
||||
line = stripPromptFrom( cursor.block().text() );
|
||||
line = stripPromptFrom( cursor.block().text() );
|
||||
}
|
||||
|
||||
// put statement to the history
|
||||
|
@ -1111,10 +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 = this->inputBegin();
|
||||
int blockLength = this->textCursor().block().text().length();
|
||||
|
||||
cursor.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor, blockLength ); //<< select text to override
|
||||
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
|
||||
|
@ -1126,7 +1126,7 @@ void PythonConsole::contextMenuEvent ( QContextMenuEvent * e )
|
|||
{
|
||||
QMenu menu(this);
|
||||
QAction *a;
|
||||
bool mayPasteHere = cursorBeyond( this->textCursor(), this->inputBegin() );
|
||||
bool mayPasteHere = cursorBeyond( this->textCursor(), this->inputBegin() );
|
||||
|
||||
a = menu.addAction(tr("&Copy"), this, SLOT(copy()), Qt::CTRL+Qt::Key_C);
|
||||
a->setEnabled(textCursor().hasSelection());
|
||||
|
@ -1144,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( mayPasteHere && 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());
|
||||
|
@ -1226,20 +1226,22 @@ 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!
|
||||
}
|
||||
|
||||
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()) );
|
||||
// application is about to quit
|
||||
if (loop.exec() < 0)
|
||||
inputBuffer = QLatin1String("quit()");
|
||||
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)
|
||||
|
@ -1290,7 +1292,7 @@ void PythonConsoleHighlighter::colorChanged(const QString& type, const QColor& c
|
|||
// ---------------------------------------------------------------------
|
||||
|
||||
ConsoleHistory::ConsoleHistory()
|
||||
: _scratchBegin(0)
|
||||
: _scratchBegin(0)
|
||||
{
|
||||
_it = _history.end();
|
||||
}
|
||||
|
@ -1391,28 +1393,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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
|
|
@ -302,7 +302,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
<< "Part_Revolve"
|
||||
<< "Part_Mirror"
|
||||
<< "Part_Fillet"
|
||||
<< "PartDesign_Chamfer";
|
||||
<< "Part_Chamfer";
|
||||
|
||||
|
||||
// Drawing ****************************************************************************************************
|
||||
|
@ -475,7 +475,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
<< "Part_Revolve"
|
||||
<< "Part_Mirror"
|
||||
<< "Part_Fillet"
|
||||
<< "PartDesign_Chamfer"
|
||||
<< "Part_Chamfer"
|
||||
;
|
||||
|
||||
// Sketch based
|
||||
|
|
|
@ -214,6 +214,11 @@ void FaceAdjacencySplitter::recursiveFind(const TopoDS_Face &face, FaceVectorTyp
|
|||
TopTools_ListIteratorOfListOfShape edgeIt;
|
||||
for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next())
|
||||
{
|
||||
//don't try to join across seams.
|
||||
ShapeAnalysis_Edge edgeCheck;
|
||||
if(edgeCheck.IsSeam(TopoDS::Edge(edgeIt.Value()), face))
|
||||
continue;
|
||||
|
||||
const TopTools_ListOfShape &faces = edgeToFaceMap.FindFromKey(edgeIt.Value());
|
||||
TopTools_ListIteratorOfListOfShape faceIt;
|
||||
for (faceIt.Initialize(faces); faceIt.More(); faceIt.Next())
|
||||
|
@ -421,25 +426,14 @@ GeomAbs_SurfaceType FaceTypedCylinder::getType() const
|
|||
|
||||
TopoDS_Face FaceTypedCylinder::buildFace(const FaceVectorType &faces) const
|
||||
{
|
||||
static TopoDS_Face dummy;
|
||||
std::vector<EdgeVectorType> boundaries;
|
||||
boundarySplit(faces, boundaries);
|
||||
static TopoDS_Face dummy;
|
||||
if (boundaries.size() < 1)
|
||||
return dummy;
|
||||
|
||||
//take one face and remove all the wires.
|
||||
TopoDS_Face workFace = faces.at(0);
|
||||
ShapeBuild_ReShape reshaper;
|
||||
TopExp_Explorer it;
|
||||
for (it.Init(workFace, TopAbs_WIRE); it.More(); it.Next())
|
||||
reshaper.Remove(it.Current());
|
||||
workFace = TopoDS::Face(reshaper.Apply(workFace));
|
||||
if (workFace.IsNull())
|
||||
return TopoDS_Face();
|
||||
|
||||
ShapeFix_Face faceFixer(workFace);
|
||||
|
||||
//makes wires
|
||||
//make wires
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
std::vector<EdgeVectorType>::iterator boundaryIt;
|
||||
for (boundaryIt = boundaries.begin(); boundaryIt != boundaries.end(); ++boundaryIt)
|
||||
{
|
||||
|
@ -448,14 +442,38 @@ TopoDS_Face FaceTypedCylinder::buildFace(const FaceVectorType &faces) const
|
|||
for (it = (*boundaryIt).begin(); it != (*boundaryIt).end(); ++it)
|
||||
wireMaker.Add(*it);
|
||||
if (wireMaker.Error() != BRepLib_WireDone)
|
||||
continue;
|
||||
faceFixer.Add(wireMaker.Wire());
|
||||
return dummy;
|
||||
wires.push_back(wireMaker.Wire());
|
||||
}
|
||||
if (wires.size() < 1)
|
||||
return dummy;
|
||||
std::sort(wires.begin(), wires.end(), ModelRefine::WireSort());
|
||||
|
||||
//make face from surface and outer wire.
|
||||
Handle(Geom_CylindricalSurface) surface = Handle(Geom_CylindricalSurface)::DownCast(BRep_Tool::Surface(faces.at(0)));
|
||||
std::vector<TopoDS_Wire>::iterator wireIt;
|
||||
wireIt = wires.begin();
|
||||
BRepBuilderAPI_MakeFace faceMaker(surface, *wireIt);
|
||||
if (!faceMaker.IsDone())
|
||||
return dummy;
|
||||
|
||||
//add additional boundaries.
|
||||
for (wireIt++; wireIt != wires.end(); ++wireIt)
|
||||
{
|
||||
faceMaker.Add(*wireIt);
|
||||
if (!faceMaker.IsDone())
|
||||
return dummy;
|
||||
}
|
||||
|
||||
//fix newly constructed face. Orientation doesn't seem to get fixed the first call.
|
||||
ShapeFix_Face faceFixer(faceMaker.Face());
|
||||
faceFixer.SetContext(new ShapeBuild_ReShape());
|
||||
if (faceFixer.Perform() > ShapeExtend_DONE5)
|
||||
return TopoDS_Face();
|
||||
return dummy;
|
||||
faceFixer.FixOrientation();
|
||||
if (faceFixer.Perform() > ShapeExtend_DONE5)
|
||||
return TopoDS_Face();
|
||||
return dummy;
|
||||
|
||||
return faceFixer.Face();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ set(PartGui_MOC_HDRS
|
|||
TaskShapeBuilder.h
|
||||
TaskLoft.h
|
||||
TaskSweep.h
|
||||
TaskCheckGeometry.h
|
||||
)
|
||||
fc_wrap_cpp(PartGui_MOC_SRCS ${PartGui_MOC_HDRS})
|
||||
SOURCE_GROUP("Moc" FILES ${PartGui_MOC_SRCS})
|
||||
|
@ -160,6 +161,8 @@ SET(PartGui_SRCS
|
|||
TaskSweep.cpp
|
||||
TaskSweep.h
|
||||
TaskSweep.ui
|
||||
TaskCheckGeometry.cpp
|
||||
TaskCheckGeometry.h
|
||||
)
|
||||
|
||||
SET(PartGui_Scripts
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "TaskShapeBuilder.h"
|
||||
#include "TaskLoft.h"
|
||||
#include "TaskSweep.h"
|
||||
#include "TaskCheckGeometry.h"
|
||||
|
||||
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
@ -1199,6 +1200,39 @@ bool CmdPartRuledSurface::isActive(void)
|
|||
return getActiveGuiDocument();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Part_CheckGeometry
|
||||
//===========================================================================
|
||||
|
||||
DEF_STD_CMD_A(CmdCheckGeometry);
|
||||
|
||||
CmdCheckGeometry::CmdCheckGeometry()
|
||||
: Command("Part_CheckGeometry")
|
||||
{
|
||||
sAppModule = "Part";
|
||||
sGroup = QT_TR_NOOP("Part");
|
||||
sMenuText = QT_TR_NOOP("Check Geometry");
|
||||
sToolTipText = QT_TR_NOOP("Analyzes Geometry For Errors");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Part_CheckGeometry";
|
||||
}
|
||||
|
||||
void CmdCheckGeometry::activated(int iMsg)
|
||||
{
|
||||
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
|
||||
if (!dlg)
|
||||
dlg = new PartGui::TaskCheckGeometryDialog();
|
||||
Gui::Control().showDialog(dlg);
|
||||
}
|
||||
|
||||
bool CmdCheckGeometry::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid) > 0;
|
||||
return (hasActiveDocument() && !Gui::Control().activeDialog() && objectsSelected);
|
||||
}
|
||||
|
||||
|
||||
void CreatePartCommands(void)
|
||||
{
|
||||
|
@ -1230,5 +1264,5 @@ void CreatePartCommands(void)
|
|||
rcCmdMgr.addCommand(new CmdPartBuilder());
|
||||
rcCmdMgr.addCommand(new CmdPartLoft());
|
||||
rcCmdMgr.addCommand(new CmdPartSweep());
|
||||
rcCmdMgr.addCommand(new CmdCheckGeometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ BUILT_SOURCES=\
|
|||
moc_DlgSettings3DViewPartImp.cpp \
|
||||
moc_DlgSettingsGeneral.cpp \
|
||||
moc_Mirroring.cpp \
|
||||
moc_TaskCheckGeometry.cpp \
|
||||
moc_TaskFaceColors.cpp \
|
||||
moc_TaskShapeBuilder.cpp \
|
||||
moc_TaskLoft.cpp \
|
||||
|
@ -69,6 +70,8 @@ libPartGui_la_SOURCES=\
|
|||
DlgSettingsGeneral.h \
|
||||
Mirroring.cpp \
|
||||
Mirroring.h \
|
||||
TaskCheckGeometry.cpp \
|
||||
TaskCheckGeometry.h \
|
||||
TaskFaceColors.cpp \
|
||||
TaskFaceColors.h \
|
||||
TaskShapeBuilder.cpp \
|
||||
|
@ -194,6 +197,7 @@ EXTRA_DIST = \
|
|||
Resources/icons/Part_Sphere.svg \
|
||||
Resources/icons/Part_Booleans.svg \
|
||||
Resources/icons/Part_Chamfer.svg \
|
||||
Resources/icons/Part_CheckGeometry.svg \
|
||||
Resources/icons/Part_Cut.svg \
|
||||
Resources/icons/Part_Common.svg \
|
||||
Resources/icons/Part_CreatePrimitives.png \
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/PartFeature.svg</file>
|
||||
<file>icons/PartFeature.xpm</file>
|
||||
<file>icons/PartFeatureImport.xpm</file>
|
||||
<file>icons/Part_Booleans.svg</file>
|
||||
<file>icons/Part_Box.svg</file>
|
||||
<file>icons/Part_Chamfer.svg</file>
|
||||
<file>icons/Part_Common.svg</file>
|
||||
<file>icons/Part_Cone.svg</file>
|
||||
<file>icons/Part_Cut.svg</file>
|
||||
<file>icons/Part_CreatePrimitives.png</file>
|
||||
<file>icons/Part_CreatePrimitives.svg</file>
|
||||
<file>icons/Part_Cylinder.svg</file>
|
||||
<file>icons/Part_Extrude.svg</file>
|
||||
<file>icons/Part_Fillet.svg</file>
|
||||
<file>icons/Part_Fuse.svg</file>
|
||||
<file>icons/Part_Import.svg</file>
|
||||
<file>icons/Part_Loft.svg</file>
|
||||
<file>icons/Part_Mirror.svg</file>
|
||||
<file>icons/Part_MirrorPNG.png</file>
|
||||
<file>icons/Part_Revolve.svg</file>
|
||||
<file>icons/Part_RuledSurface.svg</file>
|
||||
<file>icons/Part_Section.svg</file>
|
||||
<file>icons/Part_Shapebuilder.png</file>
|
||||
<file>icons/Part_ShapeInfo.svg</file>
|
||||
<file>icons/Part_Sphere.svg</file>
|
||||
<file>icons/Part_Sweep.svg</file>
|
||||
<file>icons/Part_Torus.svg</file>
|
||||
<file>icons/preferences-part_design.svg</file>
|
||||
<file>icons/Tree_Part.svg</file>
|
||||
<file>translations/Part_af.qm</file>
|
||||
<file>translations/Part_de.qm</file>
|
||||
<file>translations/Part_es.qm</file>
|
||||
<file>translations/Part_fi.qm</file>
|
||||
<file>translations/Part_fr.qm</file>
|
||||
<file>translations/Part_hr.qm</file>
|
||||
<file>translations/Part_it.qm</file>
|
||||
<file>translations/Part_nl.qm</file>
|
||||
<file>translations/Part_no.qm</file>
|
||||
<file>translations/Part_pl.qm</file>
|
||||
<file>translations/Part_pt.qm</file>
|
||||
<file>translations/Part_ru.qm</file>
|
||||
<file>translations/Part_se.qm</file>
|
||||
<file>translations/Part_uk.qm</file>
|
||||
<file>translations/Part_zh.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/PartFeature.svg</file>
|
||||
<file>icons/PartFeature.xpm</file>
|
||||
<file>icons/PartFeatureImport.xpm</file>
|
||||
<file>icons/Part_Booleans.svg</file>
|
||||
<file>icons/Part_Box.svg</file>
|
||||
<file>icons/Part_Chamfer.svg</file>
|
||||
<file>icons/Part_Common.svg</file>
|
||||
<file>icons/Part_Cone.svg</file>
|
||||
<file>icons/Part_Cut.svg</file>
|
||||
<file>icons/Part_CreatePrimitives.png</file>
|
||||
<file>icons/Part_CreatePrimitives.svg</file>
|
||||
<file>icons/Part_Cylinder.svg</file>
|
||||
<file>icons/Part_Extrude.svg</file>
|
||||
<file>icons/Part_Fillet.svg</file>
|
||||
<file>icons/Part_Fuse.svg</file>
|
||||
<file>icons/Part_Import.svg</file>
|
||||
<file>icons/Part_Loft.svg</file>
|
||||
<file>icons/Part_Mirror.svg</file>
|
||||
<file>icons/Part_MirrorPNG.png</file>
|
||||
<file>icons/Part_Revolve.svg</file>
|
||||
<file>icons/Part_RuledSurface.svg</file>
|
||||
<file>icons/Part_Section.svg</file>
|
||||
<file>icons/Part_Shapebuilder.png</file>
|
||||
<file>icons/Part_ShapeInfo.svg</file>
|
||||
<file>icons/Part_Sphere.svg</file>
|
||||
<file>icons/Part_Sweep.svg</file>
|
||||
<file>icons/Part_Torus.svg</file>
|
||||
<file>icons/preferences-part_design.svg</file>
|
||||
<file>icons/Tree_Part.svg</file>
|
||||
<file>icons/Part_CheckGeometry.svg</file>
|
||||
<file>translations/Part_af.qm</file>
|
||||
<file>translations/Part_de.qm</file>
|
||||
<file>translations/Part_es.qm</file>
|
||||
<file>translations/Part_fi.qm</file>
|
||||
<file>translations/Part_fr.qm</file>
|
||||
<file>translations/Part_hr.qm</file>
|
||||
<file>translations/Part_it.qm</file>
|
||||
<file>translations/Part_nl.qm</file>
|
||||
<file>translations/Part_no.qm</file>
|
||||
<file>translations/Part_pl.qm</file>
|
||||
<file>translations/Part_pt.qm</file>
|
||||
<file>translations/Part_ru.qm</file>
|
||||
<file>translations/Part_se.qm</file>
|
||||
<file>translations/Part_uk.qm</file>
|
||||
<file>translations/Part_zh.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
286
src/Mod/Part/Gui/Resources/icons/Part_CheckGeometry.svg
Normal file
286
src/Mod/Part/Gui/Resources/icons/Part_CheckGeometry.svg
Normal file
|
@ -0,0 +1,286 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2943"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="Part_CheckGeometry.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs2945">
|
||||
<linearGradient
|
||||
id="linearGradient4349">
|
||||
<stop
|
||||
style="stop-color:#898709;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4351" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4353" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5241">
|
||||
<stop
|
||||
style="stop-color:#212c45;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5243" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5245" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5227"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5229" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3902">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.58823532;"
|
||||
offset="0"
|
||||
id="stop3904" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.39215687;"
|
||||
offset="1"
|
||||
id="stop3906" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3894">
|
||||
<stop
|
||||
style="stop-color:#45351d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3896" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3898" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3886">
|
||||
<stop
|
||||
style="stop-color:#45351d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3888" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3890" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3792">
|
||||
<stop
|
||||
style="stop-color:#aaaaaa;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3794" />
|
||||
<stop
|
||||
style="stop-color:#d2d2d2;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3796" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3784">
|
||||
<stop
|
||||
style="stop-color:#bebebe;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3786" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.39215687;"
|
||||
offset="1"
|
||||
id="stop3788" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#71b2f8;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#002795;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2951" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3845"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.9271142,0.3747789,-0.74483377,1.8425424,-158.31046,-253.71678)"
|
||||
cx="271.96695"
|
||||
cy="103.54697"
|
||||
fx="271.96695"
|
||||
fy="103.54697"
|
||||
r="19.467436" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3792"
|
||||
id="linearGradient3858"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="16.53011"
|
||||
y1="16.515057"
|
||||
x2="41.610496"
|
||||
y2="16.515057" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3377"
|
||||
id="radialGradient3876"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2248105,0.4951204,-0.9839998,2.4341825,39.005699,-275.81551)"
|
||||
cx="271.96695"
|
||||
cy="103.54697"
|
||||
fx="271.96695"
|
||||
fy="103.54697"
|
||||
r="19.467436" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3886"
|
||||
id="linearGradient3892"
|
||||
x1="17.115427"
|
||||
y1="16.515057"
|
||||
x2="41.025179"
|
||||
y2="16.515057"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3894"
|
||||
id="linearGradient3900"
|
||||
x1="17.115427"
|
||||
y1="16.515057"
|
||||
x2="41.025179"
|
||||
y2="16.515057"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5241"
|
||||
id="linearGradient5247"
|
||||
x1="295.12671"
|
||||
y1="91.464584"
|
||||
x2="314.73236"
|
||||
y2="106.06027"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4349"
|
||||
id="linearGradient4355"
|
||||
x1="6.6594167"
|
||||
y1="3.8183174"
|
||||
x2="61.419407"
|
||||
y2="48.560249"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.3309305"
|
||||
inkscape:cx="59.095911"
|
||||
inkscape:cy="32.00629"
|
||||
inkscape:current-layer="g3629"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="688"
|
||||
inkscape:window-x="-3"
|
||||
inkscape:window-y="-3"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2948">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3629"
|
||||
transform="translate(-256.70919,-66.886588)">
|
||||
<path
|
||||
sodipodi:nodetypes="cscccc"
|
||||
id="path3603"
|
||||
d="m 278.77789,128.54149 c 0,0 17.36408,1.73323 29.84809,-1.25 7.926,-1.89403 8.5863,-5.11389 8.5863,-5.11389 l 1.26269,-6.7554 -30.92477,-0.0359 -8.77231,13.15519 z"
|
||||
style="opacity:0.66523605;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.07586193;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3845);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4355);stroke-width:2.20000004999999987;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="M 20.1875 24.09375 L 5.03125 54.65625 L 5.4375 54.65625 C 5.4114 54.77255 5.40625 54.9132 5.40625 55.03125 C 5.40625 58.19955 14.92499 60.75 26.65625 60.75 C 38.38752 60.75 47.90624 58.19955 47.90625 55.03125 C 47.90625 54.30224 46.982 53.05086 46.46875 52.125 L 33.3125 24.40625 C 31.489287 25.510263 29.330366 26.15625 27 26.15625 C 24.454997 26.15625 22.106905 25.391029 20.1875 24.09375 z "
|
||||
transform="translate(256.70919,66.886588)"
|
||||
id="path3596" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3876);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.306;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
d="m 283.56864,73.508963 -8.96997,18.127594 c 2.45967,1.993759 5.65411,3.190156 9.15763,3.190156 3.2436,0 6.21751,-1.041853 8.59466,-2.777313 l -8.78232,-18.540437 z"
|
||||
id="path3800"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
transform="matrix(1,0,0,0.89212864,254.70604,69.32031)"
|
||||
d="m 40.760496,16.515057 c 0,6.799128 -5.233878,12.310911 -11.690193,12.310911 -6.456315,0 -11.690193,-5.511783 -11.690193,-12.310911 0,-6.7991289 5.233878,-12.3109116 11.690193,-12.3109116 6.456315,0 11.690193,5.5117827 11.690193,12.3109116 z"
|
||||
sodipodi:ry="12.310911"
|
||||
sodipodi:rx="11.690193"
|
||||
sodipodi:cy="16.515057"
|
||||
sodipodi:cx="29.070303"
|
||||
id="path3848"
|
||||
style="fill:#ffffff;fill-opacity:0.58823532000000001;fill-rule:nonzero;stroke:url(#linearGradient3858);stroke-width:3.50016976;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient5247);stroke-width:2.906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 295.07922,91.367461 9.38258,6.945102 10.04523,7.435607"
|
||||
id="path3880"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:url(#linearGradient3900);stroke-width:0.90616274;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3882"
|
||||
sodipodi:cx="29.070303"
|
||||
sodipodi:cy="16.515057"
|
||||
sodipodi:rx="11.690193"
|
||||
sodipodi:ry="12.310911"
|
||||
d="m 40.760496,16.515057 c 0,6.799128 -5.233878,12.310911 -11.690193,12.310911 -6.456315,0 -11.690193,-5.511783 -11.690193,-12.310911 0,-6.7991289 5.233878,-12.3109116 11.690193,-12.3109116 6.456315,0 11.690193,5.5117827 11.690193,12.3109116 z"
|
||||
transform="matrix(1.168369,0,0,1.0423356,249.81151,66.839637)" />
|
||||
<path
|
||||
transform="matrix(0.8906974,0,0,0.79461695,257.88348,70.930724)"
|
||||
d="m 40.760496,16.515057 c 0,6.799128 -5.233878,12.310911 -11.690193,12.310911 -6.456315,0 -11.690193,-5.511783 -11.690193,-12.310911 0,-6.7991289 5.233878,-12.3109116 11.690193,-12.3109116 6.456315,0 11.690193,5.5117827 11.690193,12.3109116 z"
|
||||
sodipodi:ry="12.310911"
|
||||
sodipodi:rx="11.690193"
|
||||
sodipodi:cy="16.515057"
|
||||
sodipodi:cx="29.070303"
|
||||
id="path3884"
|
||||
style="fill:none;stroke:url(#linearGradient3892);stroke-width:1.18865548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
693
src/Mod/Part/Gui/TaskCheckGeometry.cpp
Normal file
693
src/Mod/Part/Gui/TaskCheckGeometry.cpp
Normal file
|
@ -0,0 +1,693 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2012 Thomas Anderson <blobfish[at]gmx.com> *
|
||||
* *
|
||||
* 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"
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepCheck_Result.hxx>
|
||||
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoSwitch.h>
|
||||
#include <Inventor/nodes/SoDrawStyle.h>
|
||||
#include <Inventor/nodes/SoCube.h>
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/nodes/SoTransform.h>
|
||||
#include "../App/PartFeature.h"
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
#include "TaskCheckGeometry.h"
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
QVector<QString> buildShapeEnumVector()
|
||||
{
|
||||
QVector<QString>names;
|
||||
names.push_back(QObject::tr("Compound")); //TopAbs_COMPOUND
|
||||
names.push_back(QObject::tr("Compound Solid")); //TopAbs_COMPSOLID
|
||||
names.push_back(QObject::tr("Solid")); //TopAbs_SOLID
|
||||
names.push_back(QObject::tr("Shell")); //TopAbs_SHELL
|
||||
names.push_back(QObject::tr("Face")); //TopAbs_FACE
|
||||
names.push_back(QObject::tr("Wire")); //TopAbs_WIRE
|
||||
names.push_back(QObject::tr("Edge")); //TopAbs_EDGE
|
||||
names.push_back(QObject::tr("Vertex")); //TopAbs_VERTEX
|
||||
names.push_back(QObject::tr("Shape")); //TopAbs_SHAPE
|
||||
return names;
|
||||
}
|
||||
|
||||
QString shapeEnumToString(const int &index)
|
||||
{
|
||||
static QVector<QString> names = buildShapeEnumVector();
|
||||
if (index < 0 || index > TopAbs_SHAPE)
|
||||
return names.at(8);
|
||||
return names.at(index);
|
||||
}
|
||||
|
||||
QVector<QString> buildCheckStatusStringVector()
|
||||
{
|
||||
QVector<QString>names;
|
||||
names.push_back(QObject::tr("No Error")); // BRepCheck_NoError
|
||||
names.push_back(QObject::tr("Invalid Point On Curve")); // BRepCheck_InvalidPointOnCurve
|
||||
names.push_back(QObject::tr("Invalid Point On Curve On Surface")); // BRepCheck_InvalidPointOnCurveOnSurface
|
||||
names.push_back(QObject::tr("Invalid Point On Surface")); // BRepCheck_InvalidPointOnSurface
|
||||
names.push_back(QObject::tr("No 3D Curve")); // BRepCheck_No3DCurve
|
||||
names.push_back(QObject::tr("Multiple 3D Curve")); // BRepCheck_Multiple3DCurve
|
||||
names.push_back(QObject::tr("Invalid 3D Curve")); // BRepCheck_Invalid3DCurve
|
||||
names.push_back(QObject::tr("No Curve On Surface")); // BRepCheck_NoCurveOnSurface
|
||||
names.push_back(QObject::tr("Invalid Curve On Surface")); // BRepCheck_InvalidCurveOnSurface
|
||||
names.push_back(QObject::tr("Invalid Curve On Closed Surface")); // BRepCheck_InvalidCurveOnClosedSurface
|
||||
names.push_back(QObject::tr("Invalid Same Range Flag")); // BRepCheck_InvalidSameRangeFlag
|
||||
names.push_back(QObject::tr("Invalid Same Parameter Flag")); // BRepCheck_InvalidSameParameterFlag
|
||||
names.push_back(QObject::tr("Invalid Degenerated Flag")); // BRepCheck_InvalidDegeneratedFlag
|
||||
names.push_back(QObject::tr("Free Edge")); // BRepCheck_FreeEdge
|
||||
names.push_back(QObject::tr("Invalid MultiConnexity")); // BRepCheck_InvalidMultiConnexity
|
||||
names.push_back(QObject::tr("Invalid Range")); // BRepCheck_InvalidRange
|
||||
names.push_back(QObject::tr("Empty Wire")); // BRepCheck_EmptyWire
|
||||
names.push_back(QObject::tr("Redundant Edge")); // BRepCheck_RedundantEdge
|
||||
names.push_back(QObject::tr("Self Intersecting Wire")); // BRepCheck_SelfIntersectingWire
|
||||
names.push_back(QObject::tr("No Surface")); // BRepCheck_NoSurface
|
||||
names.push_back(QObject::tr("Invalid Wire")); // BRepCheck_InvalidWire
|
||||
names.push_back(QObject::tr("Redundant Wire")); // BRepCheck_RedundantWire
|
||||
names.push_back(QObject::tr("Intersecting Wires")); // BRepCheck_IntersectingWires
|
||||
names.push_back(QObject::tr("Invalid Imbrication Of Wires")); // BRepCheck_InvalidImbricationOfWires
|
||||
names.push_back(QObject::tr("Empty Shell")); // BRepCheck_EmptyShell
|
||||
names.push_back(QObject::tr("Redundant Face")); // BRepCheck_RedundantFace
|
||||
names.push_back(QObject::tr("Unorientable Shape")); // BRepCheck_UnorientableShape
|
||||
names.push_back(QObject::tr("Not Closed")); // BRepCheck_NotClosed
|
||||
names.push_back(QObject::tr("Not Connected")); // BRepCheck_NotConnected
|
||||
names.push_back(QObject::tr("Sub Shape Not In Shape")); // BRepCheck_SubshapeNotInShape
|
||||
names.push_back(QObject::tr("Bad Orientation")); // BRepCheck_BadOrientation
|
||||
names.push_back(QObject::tr("Bad Orientation Of Sub Shape")); // BRepCheck_BadOrientationOfSubshape
|
||||
names.push_back(QObject::tr("Invalid Tolerance Value")); // BRepCheck_InvalidToleranceValue
|
||||
names.push_back(QObject::tr("Check Failed")); // BRepCheck_CheckFail
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
QString checkStatusToString(const int &index)
|
||||
{
|
||||
static QVector<QString> names = buildCheckStatusStringVector();
|
||||
if (index == -1)
|
||||
{
|
||||
return QString(QObject::tr("No Result"));
|
||||
}
|
||||
if (index > 33 || index < 0)
|
||||
{
|
||||
QString message(QObject::tr("Out Of Enum Range: "));
|
||||
QString number;
|
||||
number.setNum(index);
|
||||
message += number;
|
||||
return message;
|
||||
}
|
||||
return names.at(index);
|
||||
}
|
||||
|
||||
ResultEntry::ResultEntry()
|
||||
{
|
||||
viewProvider = 0;
|
||||
boxSep = 0;
|
||||
boxSwitch = 0;
|
||||
parent = 0;
|
||||
children.clear();
|
||||
selectionStrings.clear();
|
||||
}
|
||||
|
||||
ResultEntry::~ResultEntry()
|
||||
{
|
||||
if (boxSep)
|
||||
viewProvider->getRoot()->removeChild(boxSep);
|
||||
qDeleteAll(children);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ResultModel::ResultModel(QObject *parent) : QAbstractItemModel(parent)
|
||||
{
|
||||
root = 0;
|
||||
}
|
||||
|
||||
ResultModel::~ResultModel()
|
||||
{
|
||||
if (root)
|
||||
delete root;
|
||||
}
|
||||
|
||||
QModelIndex ResultModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!root)
|
||||
return QModelIndex();
|
||||
ResultEntry *parentNode = nodeFromIndex(parent);
|
||||
if (!parentNode)
|
||||
return QModelIndex();
|
||||
return createIndex(row, column, parentNode->children.at(row));
|
||||
}
|
||||
|
||||
QModelIndex ResultModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
ResultEntry *childNode = nodeFromIndex(child);
|
||||
if (!childNode)
|
||||
return QModelIndex();
|
||||
ResultEntry *parentNode = childNode->parent;
|
||||
if (!parentNode)
|
||||
return QModelIndex();
|
||||
ResultEntry *grandParentNode = parentNode->parent;
|
||||
if (!grandParentNode)
|
||||
return QModelIndex();
|
||||
int row = grandParentNode->children.indexOf(parentNode);
|
||||
return createIndex(row, 0, parentNode);
|
||||
}
|
||||
|
||||
int ResultModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
ResultEntry *parentNode = nodeFromIndex(parent);
|
||||
if (!parentNode)
|
||||
return 0;
|
||||
return parentNode->children.size();
|
||||
}
|
||||
|
||||
int ResultModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant ResultModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
ResultEntry *node = nodeFromIndex(index);
|
||||
if (!node)
|
||||
return QVariant();
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return QVariant(node->name);
|
||||
case 1:
|
||||
return QVariant(node->type);
|
||||
case 2:
|
||||
return QVariant(node->error);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant ResultModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return QVariant(QString(tr("Name")));
|
||||
case 1:
|
||||
return QVariant(QString(tr("Type")));
|
||||
case 2:
|
||||
return QVariant(QString(tr("Error")));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ResultModel::setResults(ResultEntry *resultsIn)
|
||||
{
|
||||
#if QT_VERSION >= 0x040600
|
||||
this->beginResetModel();
|
||||
#endif
|
||||
if (root)
|
||||
delete root;
|
||||
root = resultsIn;
|
||||
#if QT_VERSION >= 0x040600
|
||||
this->endResetModel();
|
||||
#else
|
||||
this->reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
ResultEntry* ResultModel::getEntry(const QModelIndex &index)
|
||||
{
|
||||
return nodeFromIndex(index);
|
||||
}
|
||||
|
||||
ResultEntry* ResultModel::nodeFromIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<ResultEntry *>(index.internalPointer());
|
||||
else
|
||||
return root;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TaskCheckGeometryResults::TaskCheckGeometryResults(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
this->setWindowTitle(tr("Check Geometry"));
|
||||
setupInterface();
|
||||
setupFunctionMap();
|
||||
goCheck();
|
||||
}
|
||||
|
||||
TaskCheckGeometryResults::~TaskCheckGeometryResults()
|
||||
{
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::setupInterface()
|
||||
{
|
||||
message = new QLabel(this);
|
||||
model = new ResultModel(this);
|
||||
treeView = new QTreeView(this);
|
||||
treeView->setModel(model);
|
||||
treeView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
connect(treeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
||||
this, SLOT(currentRowChanged(QModelIndex,QModelIndex)));
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->addWidget(message);
|
||||
layout->addWidget(treeView);
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::goCheck()
|
||||
{
|
||||
Gui::WaitCursor wc;
|
||||
int selectedCount(0), checkedCount(0), invalidShapes(0);
|
||||
std::vector<Gui::SelectionSingleton::SelObj> selection = Gui::Selection().getSelection();
|
||||
std::vector<Gui::SelectionSingleton::SelObj>::iterator it;
|
||||
ResultEntry *theRoot = new ResultEntry();
|
||||
for (it = selection.begin(); it != selection.end(); ++it)
|
||||
{
|
||||
selectedCount++;
|
||||
Part::Feature *feature = dynamic_cast<Part::Feature *>((*it).pObject);
|
||||
if (!feature)
|
||||
continue;
|
||||
currentProvider = Gui::Application::Instance->activeDocument()->getViewProvider(feature);
|
||||
if (!currentProvider)
|
||||
continue;
|
||||
TopoDS_Shape shape = feature->Shape.getValue();
|
||||
QString baseName;
|
||||
QTextStream baseStream(&baseName);
|
||||
baseStream << (*it).DocName;
|
||||
baseStream << "." << (*it).FeatName;
|
||||
if (strlen((*it).SubName) > 0)
|
||||
{
|
||||
shape = feature->Shape.getShape().getSubShape((*it).SubName);
|
||||
baseStream << "." << (*it).SubName;
|
||||
}
|
||||
|
||||
if (shape.IsNull())
|
||||
continue;
|
||||
checkedCount++;
|
||||
checkedMap.Clear();
|
||||
|
||||
BRepCheck_Analyzer shapeCheck(shape);
|
||||
if (!shapeCheck.IsValid())
|
||||
{
|
||||
invalidShapes++;
|
||||
ResultEntry *entry = new ResultEntry();
|
||||
entry->parent = theRoot;
|
||||
entry->shape = shape;
|
||||
entry->name = baseName;
|
||||
entry->type = shapeEnumToString(shape.ShapeType());
|
||||
entry->error = QObject::tr("Invalid");
|
||||
entry->viewProvider = currentProvider;
|
||||
getSetupResultBoundingBoxObject().go(entry);
|
||||
theRoot->children.push_back(entry);
|
||||
recursiveCheck(shapeCheck, shape, entry);
|
||||
}
|
||||
}
|
||||
model->setResults(theRoot);
|
||||
treeView->expandAll();
|
||||
treeView->header()->resizeSections(QHeaderView::ResizeToContents);
|
||||
QString aMessage;
|
||||
QTextStream aStream(&aMessage);
|
||||
aStream << checkedCount << " processed out of " << selectedCount << " selected\n";
|
||||
aStream << invalidShapes << " invalid shapes.";
|
||||
message->setText(aMessage);
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::recursiveCheck(const BRepCheck_Analyzer &shapeCheck, const TopoDS_Shape &shape,
|
||||
ResultEntry *parent)
|
||||
{
|
||||
ResultEntry *branchNode = parent;
|
||||
BRepCheck_ListIteratorOfListOfStatus listIt;
|
||||
if (!shapeCheck.Result(shape).IsNull() && !checkedMap.Contains(shape))
|
||||
{
|
||||
listIt.Initialize(shapeCheck.Result(shape)->Status());
|
||||
if (listIt.Value() != BRepCheck_NoError)
|
||||
{
|
||||
ResultEntry *entry = new ResultEntry();
|
||||
entry->parent = parent;
|
||||
entry->shape = shape;
|
||||
entry->type = shapeEnumToString(shape.ShapeType());
|
||||
entry->error = checkStatusToString(listIt.Value());
|
||||
entry->viewProvider = currentProvider;
|
||||
dispatchError(entry, listIt.Value());
|
||||
parent->children.push_back(entry);
|
||||
branchNode = entry;
|
||||
}
|
||||
}
|
||||
checkedMap.Add(shape);
|
||||
|
||||
if (shape.ShapeType() == TopAbs_SOLID)
|
||||
checkSub(shapeCheck, shape, TopAbs_SHELL, branchNode);
|
||||
if (shape.ShapeType() == TopAbs_EDGE)
|
||||
checkSub(shapeCheck, shape, TopAbs_VERTEX, branchNode);
|
||||
if (shape.ShapeType() == TopAbs_FACE)
|
||||
{
|
||||
checkSub(shapeCheck, shape, TopAbs_WIRE, branchNode);
|
||||
checkSub(shapeCheck, shape, TopAbs_EDGE, branchNode);
|
||||
checkSub(shapeCheck, shape, TopAbs_VERTEX, branchNode);
|
||||
}
|
||||
|
||||
for (TopoDS_Iterator it(shape); it.More(); it.Next())
|
||||
recursiveCheck(shapeCheck, it.Value(), branchNode);
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::checkSub(const BRepCheck_Analyzer &shapeCheck, const TopoDS_Shape &shape,
|
||||
const TopAbs_ShapeEnum subType, ResultEntry *parent)
|
||||
{
|
||||
BRepCheck_ListIteratorOfListOfStatus itl;
|
||||
TopExp_Explorer exp;
|
||||
for (exp.Init(shape,subType); exp.More(); exp.Next())
|
||||
{
|
||||
const Handle(BRepCheck_Result)& res = shapeCheck.Result(exp.Current());
|
||||
const TopoDS_Shape& sub = exp.Current();
|
||||
for (res->InitContextIterator(); res->MoreShapeInContext(); res->NextShapeInContext())
|
||||
{
|
||||
if (res->ContextualShape().IsSame(shape))
|
||||
{
|
||||
for (itl.Initialize(res->StatusOnShape()); itl.More(); itl.Next())
|
||||
{
|
||||
if (itl.Value() == BRepCheck_NoError)
|
||||
break;
|
||||
checkedMap.Add(sub);
|
||||
ResultEntry *entry = new ResultEntry();
|
||||
entry->parent = parent;
|
||||
entry->shape = sub;
|
||||
entry->type = shapeEnumToString(sub.ShapeType());
|
||||
entry->error = checkStatusToString(itl.Value());
|
||||
entry->viewProvider = currentProvider;
|
||||
dispatchError(entry, itl.Value());
|
||||
parent->children.push_back(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::dispatchError(ResultEntry *entry, const BRepCheck_Status &stat)
|
||||
{
|
||||
std::vector<FunctionMapType>::iterator mapIt;
|
||||
for (mapIt = functionMap.begin(); mapIt != functionMap.end(); ++mapIt)
|
||||
{
|
||||
if ((*mapIt).get<0>() == entry->shape.ShapeType() && (*mapIt).get<1>() == stat)
|
||||
{
|
||||
((*mapIt).get<2>())->go(entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
getSetupResultBoundingBoxObject().go(entry);
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::setupFunctionMap()
|
||||
{
|
||||
functionMap.push_back(FunctionMapType(TopAbs_SHELL, BRepCheck_NotClosed, &getSetupResultShellNotClosedObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_WIRE, BRepCheck_NotClosed, &getSetupResultWireNotClosedObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_VERTEX, BRepCheck_InvalidPointOnCurve, &getSetupResultInvalidPointCurveObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_FACE, BRepCheck_IntersectingWires, &getSetupResultIntersectingWiresObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_EDGE, BRepCheck_InvalidCurveOnSurface, &getSetupResultInvalidCurveSurfaceObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_EDGE, BRepCheck_InvalidSameParameterFlag, &getSetupResultInvalidSameParameterFlagObject()));
|
||||
functionMap.push_back(FunctionMapType(TopAbs_FACE, BRepCheck_UnorientableShape, &getSetupResultUnorientableShapeFaceObject()));
|
||||
}
|
||||
|
||||
void TaskCheckGeometryResults::currentRowChanged (const QModelIndex ¤t, const QModelIndex &previous)
|
||||
{
|
||||
Gui::Selection().clearSelection();
|
||||
if (previous.isValid())
|
||||
{
|
||||
ResultEntry *entry = model->getEntry(previous);
|
||||
if (entry)
|
||||
{
|
||||
if (entry->boxSwitch)
|
||||
entry->boxSwitch->whichChild.setValue(SO_SWITCH_NONE);
|
||||
}
|
||||
}
|
||||
if (current.isValid())
|
||||
{
|
||||
ResultEntry *entry = model->getEntry(current);
|
||||
if (entry)
|
||||
{
|
||||
if (entry->boxSwitch)
|
||||
entry->boxSwitch->whichChild.setValue(0);
|
||||
QStringList::Iterator stringIt;
|
||||
for (stringIt = entry->selectionStrings.begin(); stringIt != entry->selectionStrings.end(); ++stringIt)
|
||||
{
|
||||
//need unique delimiter.
|
||||
QString doc, object, sub;
|
||||
if (!this->split((*stringIt), doc, object, sub))
|
||||
continue;
|
||||
Gui::Selection().addSelection(doc.toAscii(), object.toAscii(), sub.toAscii());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskCheckGeometryResults::split(QString &input, QString &doc, QString &object, QString &sub)
|
||||
{
|
||||
QStringList strings = input.split(QString::fromAscii("."));
|
||||
if (strings.size() != 3)
|
||||
return false;
|
||||
doc = strings.at(0);
|
||||
object = strings.at(1);
|
||||
sub = strings.at(2);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QString SetupResultBase::selectionName(ResultEntry *entry, const TopoDS_Shape &shape)
|
||||
{
|
||||
ResultEntry *parentEntry = entry;
|
||||
while(parentEntry->name.isEmpty())
|
||||
parentEntry = parentEntry->parent;
|
||||
|
||||
QString stringOut;
|
||||
QTextStream stream(&stringOut);
|
||||
stream << parentEntry->name;
|
||||
stream << '.';
|
||||
TopTools_IndexedMapOfShape shapeMap;
|
||||
int index(-1);
|
||||
|
||||
switch (shape.ShapeType())
|
||||
{
|
||||
case TopAbs_FACE:
|
||||
TopExp::MapShapes(parentEntry->shape, TopAbs_FACE, shapeMap);
|
||||
stream << "Face";
|
||||
break;
|
||||
case TopAbs_EDGE:
|
||||
TopExp::MapShapes(parentEntry->shape, TopAbs_EDGE, shapeMap);
|
||||
stream << "Edge";
|
||||
break;
|
||||
case TopAbs_VERTEX:
|
||||
TopExp::MapShapes(parentEntry->shape, TopAbs_VERTEX, shapeMap);
|
||||
stream << "Vertex";
|
||||
break;
|
||||
}
|
||||
|
||||
index = shapeMap.FindIndex(shape);
|
||||
stream << index;
|
||||
return stringOut;
|
||||
}
|
||||
|
||||
void SetupResultBase::addTypedSelection(ResultEntry *entry, const TopoDS_Shape &shape, TopAbs_ShapeEnum type)
|
||||
{
|
||||
TopExp_Explorer it;
|
||||
for (it.Init(shape, type); it.More(); it.Next())
|
||||
{
|
||||
QString name = selectionName(entry, (it.Current()));
|
||||
if (!name.isEmpty())
|
||||
entry->selectionStrings.append(name);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupResultBoundingBox::go(ResultEntry *entry)
|
||||
{
|
||||
entry->boxSep = new SoSeparator();
|
||||
entry->viewProvider->getRoot()->addChild(entry->boxSep);
|
||||
entry->boxSwitch = new SoSwitch();
|
||||
entry->boxSep->addChild(entry->boxSwitch);
|
||||
SoGroup *group = new SoGroup();
|
||||
entry->boxSwitch->addChild(group);
|
||||
entry->boxSwitch->whichChild.setValue(SO_SWITCH_NONE);
|
||||
SoDrawStyle *dStyle = new SoDrawStyle();
|
||||
dStyle->style.setValue(SoDrawStyle::LINES);
|
||||
dStyle->linePattern.setValue(0xc0c0);
|
||||
group->addChild(dStyle);
|
||||
SoMaterial *material = new SoMaterial();
|
||||
material->diffuseColor.setValue(255.0, 255.0, 255.0);
|
||||
material->ambientColor.setValue(255.0, 255.0, 255.0);
|
||||
group->addChild(material);
|
||||
|
||||
Bnd_Box boundingBox;
|
||||
BRepBndLib::Add(entry->shape, boundingBox);
|
||||
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
boundingBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
|
||||
double xCenter, yCenter, zCenter;
|
||||
xCenter = (xmax - xmin)/2 + xmin;
|
||||
yCenter = (ymax - ymin)/2 + ymin;
|
||||
zCenter = (zmax - zmin)/2 + zmin;
|
||||
|
||||
SbVec3f boundCenter(xCenter, yCenter, zCenter);
|
||||
Standard_Real x, y, z;
|
||||
entry->shape.Location().Transformation().TranslationPart().Coord(x, y, z);
|
||||
boundCenter -= SbVec3f(x, y, z);
|
||||
|
||||
SoTransform *position = new SoTransform();
|
||||
position->translation.setValue(boundCenter);
|
||||
group->addChild(position);
|
||||
|
||||
SoCube *cube = new SoCube();
|
||||
cube->width.setValue(xmax - xmin);
|
||||
cube->height.setValue(ymax - ymin);
|
||||
cube->depth.setValue(zmax - zmin);
|
||||
group->addChild(cube);
|
||||
}
|
||||
|
||||
SetupResultBoundingBox& PartGui::getSetupResultBoundingBoxObject()
|
||||
{
|
||||
static SetupResultBoundingBox object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultShellNotClosed::go(ResultEntry *entry)
|
||||
{
|
||||
ShapeAnalysis_FreeBounds shellCheck(entry->shape);
|
||||
TopoDS_Compound closedWires = shellCheck.GetClosedWires();
|
||||
TopoDS_Compound openWires = shellCheck.GetOpenWires();
|
||||
|
||||
addTypedSelection(entry, closedWires, TopAbs_EDGE);
|
||||
addTypedSelection(entry, openWires, TopAbs_EDGE);
|
||||
}
|
||||
|
||||
SetupResultShellNotClosed& PartGui::getSetupResultShellNotClosedObject()
|
||||
{
|
||||
static SetupResultShellNotClosed object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultWireNotClosed::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_EDGE);
|
||||
}
|
||||
|
||||
SetupResultWireNotClosed& PartGui::getSetupResultWireNotClosedObject()
|
||||
{
|
||||
static SetupResultWireNotClosed object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultInvalidPointCurve::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_VERTEX);
|
||||
}
|
||||
|
||||
SetupResultInvalidPointCurve& PartGui::getSetupResultInvalidPointCurveObject()
|
||||
{
|
||||
static SetupResultInvalidPointCurve object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultIntersectingWires::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_FACE);
|
||||
}
|
||||
|
||||
SetupResultIntersectingWires& PartGui::getSetupResultIntersectingWiresObject()
|
||||
{
|
||||
static SetupResultIntersectingWires object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultInvalidCurveSurface::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_EDGE);
|
||||
}
|
||||
|
||||
SetupResultInvalidCurveSurface& PartGui::getSetupResultInvalidCurveSurfaceObject()
|
||||
{
|
||||
static SetupResultInvalidCurveSurface object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultInvalidSameParameterFlag::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_EDGE);
|
||||
}
|
||||
|
||||
SetupResultInvalidSameParameterFlag& PartGui::getSetupResultInvalidSameParameterFlagObject()
|
||||
{
|
||||
static SetupResultInvalidSameParameterFlag object;
|
||||
return object;
|
||||
}
|
||||
|
||||
void SetupResultUnorientableShapeFace::go(ResultEntry *entry)
|
||||
{
|
||||
addTypedSelection(entry, entry->shape, TopAbs_FACE);
|
||||
getSetupResultBoundingBoxObject().go(entry);
|
||||
}
|
||||
|
||||
SetupResultUnorientableShapeFace& PartGui::getSetupResultUnorientableShapeFaceObject()
|
||||
{
|
||||
static SetupResultUnorientableShapeFace object;
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TaskCheckGeometryDialog::TaskCheckGeometryDialog()
|
||||
{
|
||||
this->setButtonPosition(TaskDialog::South);
|
||||
widget = new TaskCheckGeometryResults();
|
||||
taskbox = new Gui::TaskView::TaskBox(
|
||||
Gui::BitmapFactory().pixmap("Part_CheckGeometry"),
|
||||
widget->windowTitle(), false, 0);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
TaskCheckGeometryDialog::~TaskCheckGeometryDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#include "moc_TaskCheckGeometry.cpp"
|
219
src/Mod/Part/Gui/TaskCheckGeometry.h
Normal file
219
src/Mod/Part/Gui/TaskCheckGeometry.h
Normal file
|
@ -0,0 +1,219 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2012 Thomas Anderson <blobfish[at]gmx.com> *
|
||||
* *
|
||||
* 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 TASKCHECKGEOMETRY_H
|
||||
#define TASKCHECKGEOMETRY_H
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepCheck_Status.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class SoSeparator;
|
||||
class SoSwitch;
|
||||
|
||||
namespace PartGui {
|
||||
|
||||
class ResultEntry
|
||||
{
|
||||
public:
|
||||
ResultEntry();
|
||||
~ResultEntry();
|
||||
|
||||
TopoDS_Shape shape;//invisible
|
||||
QString name;
|
||||
QString type;
|
||||
QString error;
|
||||
Gui::ViewProvider *viewProvider;
|
||||
SoSeparator *boxSep;
|
||||
SoSwitch *boxSwitch;
|
||||
ResultEntry *parent;
|
||||
QList<ResultEntry *> children;
|
||||
QStringList selectionStrings;
|
||||
};
|
||||
|
||||
class SetupResultBase
|
||||
{
|
||||
protected:
|
||||
SetupResultBase(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry) = 0;
|
||||
protected:
|
||||
QString selectionName(ResultEntry *entry, const TopoDS_Shape &shape);
|
||||
void addTypedSelection(ResultEntry *entry, const TopoDS_Shape &shape, TopAbs_ShapeEnum type);
|
||||
};
|
||||
|
||||
class SetupResultBoundingBox : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultBoundingBox(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultBoundingBox& getSetupResultBoundingBoxObject();
|
||||
};
|
||||
SetupResultBoundingBox& getSetupResultBoundingBoxObject();
|
||||
|
||||
class SetupResultShellNotClosed : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultShellNotClosed(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultShellNotClosed& getSetupResultShellNotClosedObject();
|
||||
};
|
||||
SetupResultShellNotClosed& getSetupResultShellNotClosedObject();
|
||||
|
||||
class SetupResultWireNotClosed : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultWireNotClosed(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultWireNotClosed& getSetupResultWireNotClosedObject();
|
||||
};
|
||||
SetupResultWireNotClosed& getSetupResultWireNotClosedObject();
|
||||
|
||||
class SetupResultInvalidPointCurve : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultInvalidPointCurve(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultInvalidPointCurve& getSetupResultInvalidPointCurveObject();
|
||||
};
|
||||
SetupResultInvalidPointCurve& getSetupResultInvalidPointCurveObject();
|
||||
|
||||
class SetupResultIntersectingWires : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultIntersectingWires(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultIntersectingWires& getSetupResultIntersectingWiresObject();
|
||||
};
|
||||
SetupResultIntersectingWires& getSetupResultIntersectingWiresObject();
|
||||
|
||||
class SetupResultInvalidCurveSurface : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultInvalidCurveSurface(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultInvalidCurveSurface& getSetupResultInvalidCurveSurfaceObject();
|
||||
};
|
||||
SetupResultInvalidCurveSurface& getSetupResultInvalidCurveSurfaceObject();
|
||||
|
||||
class SetupResultInvalidSameParameterFlag : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultInvalidSameParameterFlag(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultInvalidSameParameterFlag& getSetupResultInvalidSameParameterFlagObject();
|
||||
};
|
||||
SetupResultInvalidSameParameterFlag& getSetupResultInvalidSameParameterFlagObject();
|
||||
|
||||
class SetupResultUnorientableShapeFace : public SetupResultBase
|
||||
{
|
||||
private:
|
||||
SetupResultUnorientableShapeFace(){}
|
||||
public:
|
||||
virtual void go(ResultEntry *entry);
|
||||
friend SetupResultUnorientableShapeFace& getSetupResultUnorientableShapeFaceObject();
|
||||
};
|
||||
SetupResultUnorientableShapeFace& getSetupResultUnorientableShapeFaceObject();
|
||||
|
||||
typedef boost::tuple<TopAbs_ShapeEnum, BRepCheck_Status, SetupResultBase*> FunctionMapType;
|
||||
|
||||
class ResultModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResultModel(QObject *parent = 0);
|
||||
~ResultModel();
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||
QModelIndex parent(const QModelIndex &child) const;
|
||||
virtual int rowCount(const QModelIndex &parent) const;
|
||||
virtual int columnCount(const QModelIndex &parent) const;
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
// virtual Qt::ItemFlags flags (const QModelIndex &index) const;
|
||||
|
||||
void setResults(ResultEntry *resultsIn);
|
||||
ResultEntry* getEntry(const QModelIndex &index);
|
||||
private:
|
||||
ResultEntry* nodeFromIndex(const QModelIndex &index) const;
|
||||
ResultEntry *root;
|
||||
};
|
||||
|
||||
class TaskCheckGeometryResults : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TaskCheckGeometryResults(QWidget *parent = 0);
|
||||
~TaskCheckGeometryResults();
|
||||
|
||||
private slots:
|
||||
void currentRowChanged (const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
private:
|
||||
void setupInterface();
|
||||
void goCheck();
|
||||
void recursiveCheck(const BRepCheck_Analyzer &shapeCheck, const TopoDS_Shape &shape,
|
||||
ResultEntry *parent);
|
||||
void checkSub(const BRepCheck_Analyzer &shapeCheck, const TopoDS_Shape &shape,
|
||||
const TopAbs_ShapeEnum subType, ResultEntry *parent);
|
||||
void dispatchError(ResultEntry *entry, const BRepCheck_Status &stat);
|
||||
bool split(QString &input, QString &doc, QString &object, QString &sub);
|
||||
void setupFunctionMap();
|
||||
ResultModel *model;
|
||||
QTreeView *treeView;
|
||||
QLabel *message;
|
||||
TopTools_MapOfShape checkedMap;
|
||||
Gui::ViewProvider *currentProvider;
|
||||
std::vector<FunctionMapType> functionMap;
|
||||
};
|
||||
|
||||
class TaskCheckGeometryDialog : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TaskCheckGeometryDialog();
|
||||
~TaskCheckGeometryDialog();
|
||||
|
||||
virtual QDialogButtonBox::StandardButtons getStandardButtons() const
|
||||
{return QDialogButtonBox::Close;}
|
||||
virtual bool isAllowedAlterDocument(void) const
|
||||
{return false;}
|
||||
virtual bool needsFullSpace() const {return true;}
|
||||
|
||||
private:
|
||||
TaskCheckGeometryResults* widget;
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TASKCHECKGEOMETRY_H
|
|
@ -69,7 +69,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
*part << "Part_Import" << "Part_Export" << "Separator";
|
||||
*part << prim << "Part_Primitives" << "Part_Builder" << "Separator"
|
||||
<< "Part_ShapeFromMesh" << "Part_MakeSolid" << "Part_ReverseShape"
|
||||
<< "Part_SimpleCopy" << "Part_RefineShape" << "Separator"
|
||||
<< "Part_SimpleCopy" << "Part_RefineShape" << "Part_CheckGeometry" << "Separator"
|
||||
<< "Part_Boolean" << "Part_CrossSections" << "Part_Extrude"
|
||||
<< "Part_Revolve" << "Part_Mirror" << "Part_Fillet" << "Part_Chamfer"
|
||||
<< "Part_RuledSurface" << "Part_Loft" << "Part_Sweep";
|
||||
|
@ -94,7 +94,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
Gui::ToolBarItem* boolop = new Gui::ToolBarItem(root);
|
||||
boolop->setCommand("Boolean");
|
||||
*boolop << "Part_Boolean" << "Part_Cut" << "Part_Fuse" << "Part_Common"
|
||||
<< "Part_Section" << "Part_CrossSections";
|
||||
<< "Part_CheckGeometry" << "Part_Section" << "Part_CrossSections";
|
||||
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -404,6 +404,7 @@ bool CmdPartDesignGroove::isActive(void)
|
|||
{
|
||||
return hasActiveDocument();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// PartDesign_Fillet
|
||||
//===========================================================================
|
||||
|
@ -418,7 +419,7 @@ CmdPartDesignFillet::CmdPartDesignFillet()
|
|||
sToolTipText = QT_TR_NOOP("Make a fillet on an edge, face or body");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Part_Fillet";
|
||||
sPixmap = "PartDesign_Fillet";
|
||||
}
|
||||
|
||||
void CmdPartDesignFillet::activated(int iMsg)
|
||||
|
@ -564,7 +565,7 @@ CmdPartDesignChamfer::CmdPartDesignChamfer()
|
|||
sToolTipText = QT_TR_NOOP("Chamfer the selected edges of a shape");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Part_Chamfer";
|
||||
sPixmap = "PartDesign_Chamfer";
|
||||
}
|
||||
|
||||
void CmdPartDesignChamfer::activated(int iMsg)
|
||||
|
|
|
@ -37,6 +37,8 @@ EXTRA_DIST = \
|
|||
translations/PartDesign_uk.ts \
|
||||
translations/PartDesign_zh.qm \
|
||||
translations/PartDesign_zh.ts \
|
||||
icons/PartDesign_Chamfer.svg \
|
||||
icons/PartDesign_Fillet.svg \
|
||||
icons/PartDesign_Groove.svg \
|
||||
icons/PartDesign_Pad.svg \
|
||||
icons/PartDesign_Pocket.svg \
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/PartDesign_Chamfer.svg</file>
|
||||
<file>icons/PartDesign_Fillet.svg</file>
|
||||
<file>icons/PartDesign_Groove.svg</file>
|
||||
<file>icons/PartDesign_Pad.svg</file>
|
||||
<file>icons/PartDesign_Pocket.svg</file>
|
||||
|
|
197
src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Chamfer.svg
Normal file
197
src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Chamfer.svg
Normal file
|
@ -0,0 +1,197 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg3364"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="PartDesign_Chamfer_v3.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs3366">
|
||||
<linearGradient
|
||||
id="linearGradient3835">
|
||||
<stop
|
||||
id="stop3837"
|
||||
offset="0"
|
||||
style="stop-color:#637dca;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3839"
|
||||
offset="1"
|
||||
style="stop-color:#9eaede;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3827">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3829" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3831" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3864">
|
||||
<stop
|
||||
id="stop3866"
|
||||
offset="0"
|
||||
style="stop-color:#840000;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3868"
|
||||
offset="1"
|
||||
style="stop-color:#d82b1e;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3593">
|
||||
<stop
|
||||
style="stop-color:#00aff9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3595" />
|
||||
<stop
|
||||
style="stop-color:#001ccc;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3597" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="-24.909091 : 16.545455 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="116.36364 : 23.818182 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective3372" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3864"
|
||||
id="radialGradient2998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.6696601,0.63911498,-0.09121381,0.31244488,-540.88725,-258.46199)"
|
||||
cx="342.58258"
|
||||
cy="27.256668"
|
||||
fx="342.58258"
|
||||
fy="27.256668"
|
||||
r="19.571428" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3593-0"
|
||||
id="radialGradient3004-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-320.59978,-6.63068)"
|
||||
cx="330.63791"
|
||||
cy="39.962704"
|
||||
fx="330.63791"
|
||||
fy="39.962704"
|
||||
r="19.571428" />
|
||||
<linearGradient
|
||||
id="linearGradient3593-0">
|
||||
<stop
|
||||
style="stop-color:#c8e0f9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3595-2" />
|
||||
<stop
|
||||
style="stop-color:#637dca;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3597-1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="19.571428"
|
||||
fy="39.962704"
|
||||
fx="330.63791"
|
||||
cy="39.962704"
|
||||
cx="330.63791"
|
||||
gradientTransform="matrix(-0.93227784,0,0,1.3554421,396.33347,-27.208207)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3036"
|
||||
xlink:href="#linearGradient3593-0"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3593"
|
||||
id="linearGradient3799"
|
||||
x1="5.3636365"
|
||||
y1="34"
|
||||
x2="57"
|
||||
y2="34"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2844364,0,0,1.2700541,-1.1984108,-15.131825)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3864"
|
||||
id="linearGradient5146"
|
||||
x1="55.545452"
|
||||
y1="25.818182"
|
||||
x2="20.636362"
|
||||
y2="24.181818"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="pad" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.4999999"
|
||||
inkscape:cx="36.157676"
|
||||
inkscape:cy="24.078612"
|
||||
inkscape:current-layer="g3780"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="988"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3369">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3780"
|
||||
transform="matrix(0.82780005,0,0,0.83717425,-0.2499405,9.0601524)">
|
||||
<path
|
||||
style="fill:url(#linearGradient3799);fill-opacity:1;stroke:#000137;stroke-width:2.55445003999999987;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 6.9752755,17.88958 8.3764789,43.983419 38.969419,59.685905 68.861758,45.599851 70.730028,5.6508767 37.801749,-3.5858797 17.484301,2.4180125 z"
|
||||
id="path3783"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000137;stroke-width:2.55445003999999987;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 38.735885,59.224067 37.801749,17.196823 70.496495,5.8817966"
|
||||
id="path3801"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:url(#linearGradient5146);fill-opacity:1;stroke:#ff0000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 5.4545455,24.181818 25.9999995,12 8.727273,-15.818182 -25.818182,-9.636363 z"
|
||||
id="path3841"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(1.2080212,0,0,1.1944945,0.30193342,-10.822302)"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.4 KiB |
196
src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Fillet.svg
Normal file
196
src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Fillet.svg
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg3364"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="PartDesign_Fillet_v3.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1">
|
||||
<defs
|
||||
id="defs3366">
|
||||
<linearGradient
|
||||
id="linearGradient3776">
|
||||
<stop
|
||||
style="stop-color:#f82b39;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3778" />
|
||||
<stop
|
||||
style="stop-color:#660001;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3780" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3835">
|
||||
<stop
|
||||
id="stop3837"
|
||||
offset="0"
|
||||
style="stop-color:#637dca;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3839"
|
||||
offset="1"
|
||||
style="stop-color:#9eaede;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3827">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3829" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3831" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3864">
|
||||
<stop
|
||||
id="stop3866"
|
||||
offset="0"
|
||||
style="stop-color:#f82b39;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3868"
|
||||
offset="1"
|
||||
style="stop-color:#520001;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3593">
|
||||
<stop
|
||||
style="stop-color:#00aff9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3595" />
|
||||
<stop
|
||||
style="stop-color:#001ccc;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3597" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="-24.909091 : 16.545455 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="116.36364 : 23.818182 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective3372" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3593-0"
|
||||
id="radialGradient3004-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-320.59978,-6.63068)"
|
||||
cx="330.63791"
|
||||
cy="39.962704"
|
||||
fx="330.63791"
|
||||
fy="39.962704"
|
||||
r="19.571428" />
|
||||
<linearGradient
|
||||
id="linearGradient3593-0">
|
||||
<stop
|
||||
style="stop-color:#c8e0f9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3595-2" />
|
||||
<stop
|
||||
style="stop-color:#637dca;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3597-1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="19.571428"
|
||||
fy="39.962704"
|
||||
fx="330.63791"
|
||||
cy="39.962704"
|
||||
cx="330.63791"
|
||||
gradientTransform="matrix(-0.93227784,0,0,1.3554421,396.33347,-27.208207)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3036"
|
||||
xlink:href="#linearGradient3593-0"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3593"
|
||||
id="linearGradient3799"
|
||||
x1="5.3636365"
|
||||
y1="34"
|
||||
x2="57"
|
||||
y2="34"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2844364,0,0,1.2700541,-1.1984108,-15.131825)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3776"
|
||||
id="linearGradient3784"
|
||||
x1="26.214075"
|
||||
y1="12.623135"
|
||||
x2="15.684641"
|
||||
y2="38.033287"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
spreadMethod="reflect" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.5"
|
||||
inkscape:cx="1.4601396"
|
||||
inkscape:cy="24.078612"
|
||||
inkscape:current-layer="g3780"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="930"
|
||||
inkscape:window-height="1027"
|
||||
inkscape:window-x="60"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3369">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3780"
|
||||
transform="matrix(0.82780005,0,0,0.83717425,-0.2499405,9.0601524)">
|
||||
<path
|
||||
style="fill:url(#linearGradient3799);fill-opacity:1;stroke:#000137;stroke-width:2.55503488999999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 6.9752755,17.88958 8.3764789,43.983419 38.969419,59.685905 68.861758,45.599851 70.730028,5.6508767 37.801749,-3.5858797 17.484301,2.4180125 z"
|
||||
id="path3783"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000137;stroke-width:2.55445003999999987;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 38.735885,59.224067 37.801749,17.196823 70.496495,5.8817966"
|
||||
id="path3801"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
d="m 6.8196091,17.551454 c 8.8443999,3.52214 18.0369189,7.471809 31.3431519,12.85307 0.181545,-8.107212 0.984392,-13.535061 9.69838,-16.653218 C 38.602551,10.633148 26.373215,5.4479914 17.477681,2.2258944 11.216238,4.3625208 6.261769,7.3536988 6.8196091,17.551454 z"
|
||||
style="fill:url(#linearGradient3784);fill-opacity:1.0;fill-rule:evenodd;stroke:#ff0000;stroke-width:2.41762400000000000;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
|
||||
id="path3347"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.6 KiB |
Loading…
Reference in New Issue
Block a user