diff --git a/src/Gui/TaskView/TaskView.cpp b/src/Gui/TaskView/TaskView.cpp index b311de8d2f..e9551fb5f0 100644 --- a/src/Gui/TaskView/TaskView.cpp +++ b/src/Gui/TaskView/TaskView.cpp @@ -132,6 +132,9 @@ public: const QString &title, QWidget *parent = 0) : iisIconLabel(icon, title, parent) { + // do not allow to get the focus because when hiding the task box + // it could cause to activate another MDI view. + setFocusPolicy(Qt::NoFocus); } void setTitle(const QString &text) { myText = text; diff --git a/src/Mod/Draft/DraftSnap.py b/src/Mod/Draft/DraftSnap.py index 5a36e70ffb..6b01699fc9 100644 --- a/src/Mod/Draft/DraftSnap.py +++ b/src/Mod/Draft/DraftSnap.py @@ -288,8 +288,8 @@ class Snapper: origin = Vector(self.snapInfo['x'],self.snapInfo['y'],self.snapInfo['z']) winner = [Vector(0,0,0),None,Vector(0,0,0)] for snap in snaps: - if snap[0] == None: - print "debug: Snapper: snap point = ",snap + if (not snap) or (snap[0] == None): + print "debug: Snapper: invalid snap point: ",snaps else: delta = snap[0].sub(origin) if delta.Length < shortest: diff --git a/src/Mod/Draft/draftlibs/dxfReader.py b/src/Mod/Draft/draftlibs/dxfReader.py index 02628b81c9..e037775157 100644 --- a/src/Mod/Draft/draftlibs/dxfReader.py +++ b/src/Mod/Draft/draftlibs/dxfReader.py @@ -145,7 +145,10 @@ def convert(code, value): elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060: value = float(value) elif code == 105 or 309 < code < 380 or 389 < code < 400: - value = int(value, 16) # should be left as string? + try: + value = int(value, 16) # should be left as string? + except: + pass else: # it's already a string so do nothing pass return value diff --git a/src/Mod/Part/Gui/SoBrepShape.cpp b/src/Mod/Part/Gui/SoBrepShape.cpp index 0f8dacbab0..39658d0734 100644 --- a/src/Mod/Part/Gui/SoBrepShape.cpp +++ b/src/Mod/Part/Gui/SoBrepShape.cpp @@ -35,6 +35,7 @@ # include # include # include +# include # include # include # include @@ -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(); diff --git a/src/Mod/Part/Gui/SoBrepShape.h b/src/Mod/Part/Gui/SoBrepShape.h index 273bb370cf..4be3b7e8ee 100644 --- a/src/Mod/Part/Gui/SoBrepShape.h +++ b/src/Mod/Part/Gui/SoBrepShape.h @@ -63,6 +63,7 @@ protected: const SoPrimitiveVertex * v2, const SoPrimitiveVertex * v3, SoPickedPoint * pp); + virtual void generatePrimitives(SoAction * action); private: enum Binding { diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp index b066476ebf..b9ae984c28 100644 --- a/src/Mod/Part/Gui/ViewProviderExt.cpp +++ b/src/Mod/Part/Gui/ViewProviderExt.cpp @@ -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; itransparency.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; diff --git a/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Revolution.svg b/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Revolution.svg index 3571de30f1..c4f06e4416 100644 --- a/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Revolution.svg +++ b/src/Mod/PartDesign/Gui/Resources/icons/PartDesign_Revolution.svg @@ -14,33 +14,73 @@ height="64px" id="svg2901" sodipodi:version="0.32" - inkscape:version="0.47 r22583" + inkscape:version="0.48.3.1 r9886" sodipodi:docname="PartDesign_Revolution.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" - version="1.1"> + version="1.1" + inkscape:export-filename="/home/yorik/PartDesign_Groove.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + + + + + + + + + + + + + + style="stop-color:#c8e0f9;stop-opacity:1;" /> + style="stop-color:#f7f9fa;stop-opacity:0.09649123;" /> + style="stop-color:#c8e0f9;stop-opacity:1;" /> + style="stop-color:#002795;stop-opacity:1;" /> - - + gradientTransform="matrix(0.97680237,0,0,0.96003508,1.4694319,0.12765765)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:snap-global="true" + inkscape:snap-nodes="true" + inkscape:object-paths="true" + inkscape:object-nodes="true" + inkscape:snap-intersection-paths="true" /> @@ -116,6 +351,7 @@ image/svg+xml + @@ -124,19 +360,22 @@ inkscape:label="Layer 1" inkscape:groupmode="layer"> + style="color:#000000;fill:none;stroke:#ff0d00;stroke-width:7;stroke-linecap:round;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 59.390729,12.781229 3.9642025,50.409698" + id="path4129" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cc" /> + id="path3846-3" + style="color:#000000;fill:url(#linearGradient3890-3);fill-opacity:1;fill-rule:evenodd;stroke:#5e3800;stroke-width:2;stroke-linecap:round;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 4.1047954,21.403351 C 22.308745,26.235621 34.032006,47.721204 33.886251,58.545959 L 59.892734,38.757065 C 60.600604,22.451936 47.109374,9.749093 34.690963,7.799036 z" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + id="path3852-7" + style="color:#000000;fill:#ffc700;fill-opacity:1;fill-rule:evenodd;stroke:#5e3800;stroke-width:2;stroke-linecap:round;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 33.886251,58.545958 C 36.941097,43.812111 25.126927,21.417439 4.1047954,21.403351 L 6.548522,35.375603 c 6.982954,0.391945 13.792883,7.056272 14.23015,16.991322 z" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 40c1bf9880..9814cc5670 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -69,6 +69,17 @@ void Workbench::activated() //Watcher.push_back(new TaskWatcherRobot); + const char* Edge[] = { + "PartDesign_Fillet", + "PartDesign_Chamfer", + 0}; + Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( + "SELECT Part::Feature SUBELEMENT Edge COUNT 1..", + Edge, + "Edge tools", + "Part_Box" + )); + const char* Face[] = { "Sketcher_NewSketch", "PartDesign_Fillet", @@ -81,6 +92,17 @@ void Workbench::activated() "Part_Box" )); + const char* Faces[] = { + "PartDesign_Fillet", + "PartDesign_Chamfer", + 0}; + Watcher.push_back(new Gui::TaskView::TaskWatcherCommands( + "SELECT Part::Feature SUBELEMENT Face COUNT 2..", + Faces, + "Face tools", + "Part_Box" + )); + const char* Sketch[] = { "Sketcher_NewSketch", "PartDesign_Pad", diff --git a/src/Mod/Start/StartPage/StartPage.py b/src/Mod/Start/StartPage/StartPage.py index 978cae6b7b..03b4458600 100644 --- a/src/Mod/Start/StartPage/StartPage.py +++ b/src/Mod/Start/StartPage/StartPage.py @@ -70,6 +70,9 @@ text45 = translate("StartPage","This is the official user manual of FreeCAD, bui text46 = translate("StartPage","The tutorials section on the FreeCAD website") text47 = translate("StartPage","The section of the FreeCAd website dedicate dto python scripting, with examples, explanations, and API commands.") text48 = translate("StartPage","A blog dedicated to teaching FreeCAD, maintained by members of the FreeCAD community") +text49 = translate("StartPage","Getting started") +text50 = translate("StartPage","The FreeCAD interface is divided in workbenches, which are sets of tools suited for a specific task. You can start with one of the workbenches in this list, or with the complete workbench, which presents you with some of the most used tools gathered from other workbenches. Click to read more about workbenches on the FreeCAD website.") +text51 = translate("StartPage","http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=Workbench_Concept") # here is the html page skeleton @@ -342,7 +345,13 @@ def getLinks(): def getWorkbenches(): return """ -