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

This commit is contained in:
jrheinlaender 2012-09-14 19:49:34 +04:30
commit 91fb0bb643
9 changed files with 679 additions and 356 deletions

View File

@ -38,6 +38,7 @@
#include "PyTools.h"
#include "Exception.h"
#include "PyObjectBase.h"
#include <CXX/Extensions.hxx>
char format2[1024]; //Warning! Can't go over 512 characters!!!
@ -89,6 +90,36 @@ SystemExitException::SystemExitException(const SystemExitException &inst)
// ---------------------------------------------------------
// Fixes #0000831: python print causes File descriptor error on windows
class PythonStdOutput : public Py::PythonExtension<PythonStdOutput>
{
public:
static void init_type(void)
{
behaviors().name("PythonStdOutput");
behaviors().doc("Python standard output");
add_varargs_method("write",&PythonStdOutput::write,"write()");
add_varargs_method("flush",&PythonStdOutput::flush,"flush()");
}
PythonStdOutput()
{
}
~PythonStdOutput()
{
}
Py::Object write(const Py::Tuple&)
{
return Py::None();
}
Py::Object flush(const Py::Tuple&)
{
return Py::None();
}
};
// ---------------------------------------------------------
InterpreterSingleton::InterpreterSingleton()
{
@ -311,6 +342,10 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
PyEval_InitThreads();
Py_Initialize();
PySys_SetArgv(argc, argv);
PythonStdOutput::init_type();
PythonStdOutput* out = new PythonStdOutput();
PySys_SetObject("stdout", out);
PySys_SetObject("stderr", out);
this->_global = PyEval_SaveThread();
}

View File

@ -166,6 +166,9 @@ QStringList BitmapFactoryInst::findIconFiles() const
files << it->absoluteFilePath();
}
#if QT_VERSION >= 0x040500
files.removeDuplicates();
#endif
return files;
}

View File

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

View File

@ -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)
{ PyErr_SetInterrupt(); } //< send SIGINT to python
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 */

View File

@ -35,6 +35,7 @@
# include <float.h>
# include <algorithm>
# include <Inventor/SoPickedPoint.h>
# include <Inventor/SoPrimitiveVertex.h>
# include <Inventor/actions/SoCallbackAction.h>
# include <Inventor/actions/SoGetBoundingBoxAction.h>
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
@ -154,6 +155,9 @@ void SoBrepFaceSet::GLRender(SoGLRenderAction *action)
renderSelection(action);
if (this->highlightIndex.getValue() >= 0)
renderHighlight(action);
// When setting transparency shouldGLRender() handles the rendering and returns false.
// Therefore generatePrimitives() needs to be re-implemented to handle the materials
// correctly.
if (!this->shouldGLRender(action))
return;
@ -210,6 +214,276 @@ void SoBrepFaceSet::GLRenderBelowPath(SoGLRenderAction * action)
inherited::GLRenderBelowPath(action);
}
// this macro actually makes the code below more readable :-)
#define DO_VERTEX(idx) \
if (mbind == PER_VERTEX) { \
pointDetail.setMaterialIndex(matnr); \
vertex.setMaterialIndex(matnr++); \
} \
else if (mbind == PER_VERTEX_INDEXED) { \
pointDetail.setMaterialIndex(*mindices); \
vertex.setMaterialIndex(*mindices++); \
} \
if (nbind == PER_VERTEX) { \
pointDetail.setNormalIndex(normnr); \
currnormal = &normals[normnr++]; \
vertex.setNormal(*currnormal); \
} \
else if (nbind == PER_VERTEX_INDEXED) { \
pointDetail.setNormalIndex(*nindices); \
currnormal = &normals[*nindices++]; \
vertex.setNormal(*currnormal); \
} \
if (tb.isFunction()) { \
vertex.setTextureCoords(tb.get(coords->get3(idx), *currnormal)); \
if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++); \
} \
else if (tbind != NONE) { \
pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx); \
vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++)); \
} \
vertex.setPoint(coords->get3(idx)); \
pointDetail.setCoordinateIndex(idx); \
this->shapeVertex(&vertex);
void SoBrepFaceSet::generatePrimitives(SoAction * action)
{
//TODO
#if 0
inherited::generatePrimitives(action);
#else
//This is highly experimental!!!
if (this->coordIndex.getNum() < 3) return;
SoState * state = action->getState();
if (this->vertexProperty.getValue()) {
state->push();
this->vertexProperty.getValue()->doAction(action);
}
Binding mbind = this->findMaterialBinding(state);
Binding nbind = this->findNormalBinding(state);
const SoCoordinateElement * coords;
const SbVec3f * normals;
const int32_t * cindices;
int numindices;
const int32_t * nindices;
const int32_t * tindices;
const int32_t * mindices;
SbBool doTextures;
SbBool sendNormals;
SbBool normalCacheUsed;
sendNormals = TRUE; // always generate normals
this->getVertexData(state, coords, normals, cindices,
nindices, tindices, mindices, numindices,
sendNormals, normalCacheUsed);
SoTextureCoordinateBundle tb(action, FALSE, FALSE);
doTextures = tb.needCoordinates();
if (!sendNormals) nbind = OVERALL;
else if (normalCacheUsed && nbind == PER_VERTEX) {
nbind = PER_VERTEX_INDEXED;
}
else if (normalCacheUsed && nbind == PER_FACE_INDEXED) {
nbind = PER_FACE;
}
if (this->getNodeType() == SoNode::VRML1) {
// For VRML1, PER_VERTEX means per vertex in shape, not PER_VERTEX
// on the state.
if (mbind == PER_VERTEX) {
mbind = PER_VERTEX_INDEXED;
mindices = cindices;
}
if (nbind == PER_VERTEX) {
nbind = PER_VERTEX_INDEXED;
nindices = cindices;
}
}
Binding tbind = NONE;
if (doTextures) {
if (tb.isFunction() && !tb.needIndices()) {
tbind = NONE;
tindices = NULL;
}
// FIXME: just call inherited::areTexCoordsIndexed() instead of
// the if-check? 20020110 mortene.
else if (SoTextureCoordinateBindingElement::get(state) ==
SoTextureCoordinateBindingElement::PER_VERTEX) {
tbind = PER_VERTEX;
tindices = NULL;
}
else {
tbind = PER_VERTEX_INDEXED;
if (tindices == NULL) tindices = cindices;
}
}
if (nbind == PER_VERTEX_INDEXED && nindices == NULL) {
nindices = cindices;
}
if (mbind == PER_VERTEX_INDEXED && mindices == NULL) {
mindices = cindices;
}
int texidx = 0;
TriangleShape mode = POLYGON;
TriangleShape newmode;
const int32_t *viptr = cindices;
const int32_t *viendptr = viptr + numindices;
const int32_t *piptr = this->partIndex.getValues(0);
int num_partindices = this->partIndex.getNum();
const int32_t *piendptr = piptr + num_partindices;
int32_t v1, v2, v3, v4, v5 = 0, pi; // v5 init unnecessary, but kills a compiler warning.
SoPrimitiveVertex vertex;
SoPointDetail pointDetail;
SoFaceDetail faceDetail;
vertex.setDetail(&pointDetail);
SbVec3f dummynormal(0,0,1);
const SbVec3f *currnormal = &dummynormal;
if (normals) currnormal = normals;
vertex.setNormal(*currnormal);
int matnr = 0;
int normnr = 0;
int trinr = 0;
pi = piptr < piendptr ? *piptr++ : -1;
while (pi == 0) {
// It may happen that a part has no triangles
pi = piptr < piendptr ? *piptr++ : -1;
if (mbind == PER_PART)
matnr++;
else if (mbind == PER_PART_INDEXED)
mindices++;
}
while (viptr + 2 < viendptr) {
v1 = *viptr++;
v2 = *viptr++;
v3 = *viptr++;
if (v1 < 0 || v2 < 0 || v3 < 0) {
break;
}
v4 = viptr < viendptr ? *viptr++ : -1;
if (v4 < 0) newmode = TRIANGLES;
else {
v5 = viptr < viendptr ? *viptr++ : -1;
if (v5 < 0) newmode = QUADS;
else newmode = POLYGON;
}
if (newmode != mode) {
if (mode != POLYGON) this->endShape();
mode = newmode;
this->beginShape(action, mode, &faceDetail);
}
else if (mode == POLYGON) this->beginShape(action, POLYGON, &faceDetail);
// vertex 1 can't use DO_VERTEX
if (mbind == PER_PART) {
if (trinr == 0) {
pointDetail.setMaterialIndex(matnr);
vertex.setMaterialIndex(matnr++);
}
}
else if (mbind == PER_PART_INDEXED) {
if (trinr == 0) {
pointDetail.setMaterialIndex(*mindices);
vertex.setMaterialIndex(*mindices++);
}
}
else if (mbind == PER_VERTEX || mbind == PER_FACE) {
pointDetail.setMaterialIndex(matnr);
vertex.setMaterialIndex(matnr++);
}
else if (mbind == PER_VERTEX_INDEXED || mbind == PER_FACE_INDEXED) {
pointDetail.setMaterialIndex(*mindices);
vertex.setMaterialIndex(*mindices++);
}
if (nbind == PER_VERTEX || nbind == PER_FACE) {
pointDetail.setNormalIndex(normnr);
currnormal = &normals[normnr++];
vertex.setNormal(*currnormal);
}
else if (nbind == PER_FACE_INDEXED || nbind == PER_VERTEX_INDEXED) {
pointDetail.setNormalIndex(*nindices);
currnormal = &normals[*nindices++];
vertex.setNormal(*currnormal);
}
if (tb.isFunction()) {
vertex.setTextureCoords(tb.get(coords->get3(v1), *currnormal));
if (tb.needIndices()) pointDetail.setTextureCoordIndex(tindices ? *tindices++ : texidx++);
}
else if (tbind != NONE) {
pointDetail.setTextureCoordIndex(tindices ? *tindices : texidx);
vertex.setTextureCoords(tb.get(tindices ? *tindices++ : texidx++));
}
pointDetail.setCoordinateIndex(v1);
vertex.setPoint(coords->get3(v1));
this->shapeVertex(&vertex);
DO_VERTEX(v2);
DO_VERTEX(v3);
if (mode != TRIANGLES) {
DO_VERTEX(v4);
if (mode == POLYGON) {
DO_VERTEX(v5);
v1 = viptr < viendptr ? *viptr++ : -1;
while (v1 >= 0) {
DO_VERTEX(v1);
v1 = viptr < viendptr ? *viptr++ : -1;
}
this->endShape();
}
}
faceDetail.incFaceIndex();
if (mbind == PER_VERTEX_INDEXED) {
mindices++;
}
if (nbind == PER_VERTEX_INDEXED) {
nindices++;
}
if (tindices) tindices++;
trinr++;
if (pi == trinr) {
pi = piptr < piendptr ? *piptr++ : -1;
while (pi == 0) {
// It may happen that a part has no triangles
pi = piptr < piendptr ? *piptr++ : -1;
if (mbind == PER_PART)
matnr++;
else if (mbind == PER_PART_INDEXED)
mindices++;
}
trinr = 0;
}
}
if (mode != POLYGON) this->endShape();
if (normalCacheUsed) {
this->readUnlockNormalCache();
}
if (this->vertexProperty.getValue()) {
state->pop();
}
#endif
}
#undef DO_VERTEX
void SoBrepFaceSet::renderHighlight(SoGLRenderAction *action)
{
SoState * state = action->getState();

View File

@ -63,6 +63,7 @@ protected:
const SoPrimitiveVertex * v2,
const SoPrimitiveVertex * v3,
SoPickedPoint * pp);
virtual void generatePrimitives(SoAction * action);
private:
enum Binding {

View File

@ -281,6 +281,29 @@ void ViewProviderPartExt::onChanged(const App::Property* prop)
ViewProviderGeometryObject::onChanged(prop);
DiffuseColor.setValue(ShapeColor.getValue());
}
else if (prop == &Transparency) {
const App::Material& Mat = ShapeMaterial.getValue();
long value = (long)(100*Mat.transparency);
if (value != Transparency.getValue()) {
float trans = Transparency.getValue()/100.0f;
if (pcShapeBind->value.getValue() == SoMaterialBinding::PER_PART) {
int cnt = pcShapeMaterial->diffuseColor.getNum();
pcShapeMaterial->transparency.setNum(cnt);
float *t = pcShapeMaterial->transparency.startEditing();
for (int i=0; i<cnt; i++)
t[i] = trans;
pcShapeMaterial->transparency.finishEditing();
}
else {
pcShapeMaterial->transparency = trans;
}
App::PropertyContainer* parent = ShapeMaterial.getContainer();
ShapeMaterial.setContainer(0);
ShapeMaterial.setTransparency(trans);
ShapeMaterial.setContainer(parent);
}
}
else if (prop == &Lighting) {
if (Lighting.getValue() == 0)
pShapeHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING;

View File

@ -15,82 +15,11 @@
id="svg3364"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Part_Chamfer.svg"
sodipodi:docname="PartDesign_Chamfer.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs3366">
<linearGradient
id="linearGradient3864">
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3864"
id="radialGradient2571"
gradientUnits="userSpaceOnUse"
cx="342.58258"
cy="27.256668"
fx="342.58258"
fy="27.256668"
r="19.571428"
gradientTransform="matrix(1.6258409,0.5434973,-8.8819886e-2,0.2656996,-215.02413,-170.90186)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3352"
gradientUnits="userSpaceOnUse"
cx="345.28433"
cy="15.560534"
fx="345.28433"
fy="15.560534"
r="19.571428"
gradientTransform="translate(-0.1767767,-2.6516504)" />
<linearGradient
id="linearGradient3593">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
offset="0"
id="stop3595" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
offset="1"
id="stop3597" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3354"
gradientUnits="userSpaceOnUse"
cx="330.63791"
cy="39.962704"
fx="330.63791"
fy="39.962704"
r="19.571428"
gradientTransform="translate(-0.1767767,-2.6516504)" />
<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="perspective3372" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3835"
id="linearGradient3833"
x1="32.940414"
y1="36.053555"
x2="57.117523"
y2="36.053555"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3835">
<stop
@ -103,15 +32,109 @@
style="stop-color:#9eaede;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.010373,0,0,1,-0.52975227,-0.0535564)"
y2="36.053555"
x2="57.117523"
y1="36.053555"
x1="32.940414"
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:#ff2b1e;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"
id="linearGradient3026"
xlink:href="#linearGradient3835"
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="48.272724"
y1="25.636364"
x2="16.090908"
y2="24.181818"
gradientUnits="userSpaceOnUse"
spreadMethod="pad" />
</defs>
<sodipodi:namedview
id="base"
@ -120,10 +143,10 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="39.603136"
inkscape:cy="42.323714"
inkscape:current-layer="g3358"
inkscape:zoom="11"
inkscape:cx="33.74495"
inkscape:cy="31.251397"
inkscape:current-layer="g3780"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
@ -140,6 +163,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -147,40 +171,27 @@
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
inkscape:connector-curvature="0"
id="path3825"
d="m 32.846593,44.173611 c 0.02072,-10.842352 0.03276,-11.977309 0.134412,-12.679651 0.573203,-3.960178 2.084745,-6.419454 5.18667,-8.438706 1.244499,-0.810128 3.066269,-1.651916 4.760315,-2.199606 0.35722,-0.11549 0.693333,-0.246312 0.746916,-0.290714 0.05358,-0.0444 3.093207,-1.108099 6.754721,-2.363769 l 6.657297,-2.283037 0.01637,15.785594 c 0.009,8.682076 0.0068,15.795117 -0.0051,15.806759 -0.01176,0.01164 -5.323856,1.88822 -11.804655,4.170175 -6.480795,2.281955 -11.937733,4.205756 -12.126525,4.275113 l -0.343259,0.126103 0.02276,-11.908261 z"
style="fill:url(#linearGradient3026);fill-opacity:1;stroke:#4b4dba;stroke-width:0.14215295;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<g
id="g3358"
transform="translate(-320.42289,-3.9790318)">
<path
sodipodi:nodetypes="ccccc"
id="rect2568"
d="M 324.32322,28.84835 L 352.32322,37.59835 L 352.32322,61.84835 L 324.32322,53.09835 L 324.32322,28.84835 z"
style="opacity:1;fill:url(#radialGradient3354);fill-opacity:1;fill-rule:evenodd;stroke:#4b4dba;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="ccccc"
id="path2573"
d="M 352.69822,10.47335 L 379.32322,18.09835 L 363.82322,23.47335 L 335.82322,14.72335 L 352.69822,10.47335 z"
style="opacity:1;fill:url(#radialGradient3352);fill-opacity:1;fill-rule:evenodd;stroke:#4b4dba;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="ccccc"
d="M 363.82322,23.47335 L 352.32322,37.59835 L 324.32322,28.84835 L 335.82322,14.72335 L 363.82322,23.47335 z"
style="opacity:1;fill:url(#linearGradient3864);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3347" />
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.55445004;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 6.9752755,21.473063 8.3764789,43.983419 38.969419,59.685905 68.861758,45.599851 70.730028,5.6508767 37.801749,-3.5858797 21.877105,0.78915639 z"
id="path3783"
inkscape:connector-curvature="0"
id="path3055"
d="m 351.77942,61.818515 26.74149,-9.5138 0,-33.619713"
style="fill:none;stroke:#4b4dba;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
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:#000137;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 5.4545455,26.90909 31.181818,40 43.363637,19.363636 17.818182,9.6363636 z"
id="path3841"
inkscape:connector-curvature="0"
id="path3010"
d="m 352.03102,62.894161 27.58451,-9.811436 0,-4.818182 4.77522,1.620739 -0.004,9.383169 -7.13495,2.814275 z"
style="opacity:0.66000001;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccccccc" />
transform="matrix(1.2080212,0,0,1.1944945,0.30193342,-10.822302)"
sodipodi:nodetypes="ccccc" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -14,12 +14,23 @@
height="64px"
id="svg3364"
sodipodi:version="0.32"
inkscape:version="0.48.2 r9819"
sodipodi:docname="Part_Fillet_mod.svg"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="PartDesign_Fillet.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:#520001;stop-opacity:1;"
offset="1"
id="stop3780" />
</linearGradient>
<linearGradient
id="linearGradient3835">
<stop
@ -47,20 +58,20 @@
<stop
id="stop3866"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1;" />
style="stop-color:#f82b39;stop-opacity:1;" />
<stop
id="stop3868"
offset="1"
style="stop-color:#002795;stop-opacity:1;" />
style="stop-color:#520001;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3593">
<stop
style="stop-color:#c8e0f9;stop-opacity:1;"
style="stop-color:#00aff9;stop-opacity:1;"
offset="0"
id="stop3595" />
<stop
style="stop-color:#637dca;stop-opacity:1;"
style="stop-color:#001ccc;stop-opacity:1;"
offset="1"
id="stop3597" />
</linearGradient>
@ -71,39 +82,6 @@
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.62584,0.543497,-0.0888199,0.2657,-535.447,-174.88103)"
cx="342.58258"
cy="27.256668"
fx="342.58258"
fy="27.256668"
r="19.571428" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3001"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-320.59978,-6.63068)"
cx="345.28433"
cy="15.560534"
fx="345.28433"
fy="15.560534"
r="19.571428" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593"
id="radialGradient3004"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-320.59978,-6.63068)"
cx="330.63791"
cy="39.962704"
fx="330.63791"
fy="39.962704"
r="19.571428" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3593-0"
@ -139,12 +117,22 @@
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3835"
id="linearGradient3833"
x1="32.940414"
y1="36.053555"
x2="57.117523"
y2="36.053555"
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="24.566774"
y1="12.948906"
x2="17.990864"
y2="28.911695"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
@ -154,18 +142,18 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="44.746723"
inkscape:cy="9.5331574"
inkscape:current-layer="layer1"
inkscape:zoom="11"
inkscape:cx="23.911461"
inkscape:cy="32.751292"
inkscape:current-layer="g3780"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-width="930"
inkscape:window-height="1028"
inkscape:window-x="60"
inkscape:window-y="24"
inkscape:window-maximized="1" />
inkscape:window-maximized="0" />
<metadata
id="metadata3369">
<rdf:RDF>
@ -183,40 +171,25 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3780">
id="g3780"
transform="matrix(0.82780005,0,0,0.83717425,-0.2499405,9.0601524)">
<path
sodipodi:nodetypes="ccccc"
id="rect2568"
d="m 3.90022,24.86932 28,8.75 0,24.25 -28,-8.75 0,-24.25 z"
style="fill:url(#radialGradient3004);fill-opacity:1;fill-rule:evenodd;stroke:#4b4dba;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
style="fill:url(#linearGradient3799);fill-opacity:1;stroke:#000137;stroke-width:2.55503488;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 7.1949157,22.558967 8.3764789,43.983419 38.969419,59.685905 68.861758,45.599851 70.730028,5.6508767 37.801749,-3.5858797 19.900343,1.6578797 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"
id="path2573"
d="m 32.27522,6.49432 26.625,7.625 -15.5,5.375 -28,-8.75 16.875,-4.25 z"
style="fill:url(#radialGradient3001);fill-opacity:1;fill-rule:evenodd;stroke:#4b4dba;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
d="m 3.87385,24.966993 c 7.24785,2.209709 18.47316,5.568467 28.0191,8.57367 0.17678,-6.894292 3.0052,-11.313709 11.49049,-13.965359 -9.0156,-2.65165 -18.64993,-6.275572 -27.312,-9.015611 -9.28078,2.209708 -12.28598,4.949747 -12.19759,14.4073 z"
style="fill:url(#radialGradient2998);fill-opacity:1;fill-rule:evenodd;stroke:#000137;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:bevel;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 7.0392493,22.763793 38.602041,37.245719 C 38.454126,25.120662 41.892656,16.869463 51.814665,12.665402 L 20.442824,1.4657616 C 11.984979,3.4175083 6.4814092,11.476222 7.0392493,22.763793 z"
style="fill:url(#linearGradient3784);fill-opacity:1;fill-rule:evenodd;stroke:#000137;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" />
<path
inkscape:connector-curvature="0"
id="path3055"
d="m 31.43411,57.893169 26.741493,-9.5138 0,-33.619713"
style="fill:none;stroke:#4b4dba;stroke-width:2.20000004999999987;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path3825"
d="m 33.033685,44.227167 c 0.02051,-10.842352 0.03242,-11.977309 0.133032,-12.679651 0.567319,-3.960178 2.063342,-6.419453 5.133421,-8.438705 1.231723,-0.810128 3.034789,-1.651916 4.711443,-2.199606 0.353553,-0.11549 0.686215,-0.246312 0.739248,-0.290714 0.05303,-0.0444 3.061451,-1.108099 6.685373,-2.363769 l 6.58895,-2.283037 0.0162,15.785593 c 0.0089,8.682076 0.0067,15.795117 -0.005,15.806759 -0.01164,0.01164 -5.269199,1.88822 -11.683462,4.170175 -6.41426,2.281955 -11.815174,4.205756 -12.002028,4.275113 l -0.339735,0.126103 0.02253,-11.908261 z"
style="fill:url(#linearGradient3833);stroke:#4b4dba;stroke-width:0.14142136000000000;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1.0" />
<path
inkscape:connector-curvature="0"
id="path3010"
d="m 31.681818,58.954545 27.545454,-9.909091 0,-4.818182 17.454546,6.545455 -19.818182,7.272727 z"
style="opacity:0.66000001;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB