From 5dbc66ae849056968f494c44386bb09aea13e76e Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Fri, 29 Mar 2013 20:07:26 +0430 Subject: [PATCH] Integrated PartDesign::Pad into Body feature workflow --- src/Mod/PartDesign/App/Body.cpp | 52 +- src/Mod/PartDesign/App/Body.h | 11 + src/Mod/PartDesign/App/Feature.cpp | 17 +- src/Mod/PartDesign/App/Feature.h | 9 +- src/Mod/PartDesign/App/FeaturePad.cpp | 19 +- src/Mod/PartDesign/Gui/Command.cpp | 2762 +++++++++---------- src/Mod/PartDesign/Gui/Command.cpp.orig | 1993 ++++++++----- src/Mod/PartDesign/Gui/ViewProviderBody.cpp | 14 +- 8 files changed, 2781 insertions(+), 2096 deletions(-) diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index 0af02620e..c255f8715 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -31,6 +31,8 @@ #include "Body.h" #include "BodyPy.h" +#include + using namespace PartDesign; @@ -51,18 +53,54 @@ short Body::mustExecute() const return 0; } -App::DocumentObjectExecReturn *Body::execute(void) +const Part::TopoShape Body::getTipShape() { // TODO right selection for Body App::DocumentObject* link = Tip.getValue(); if (!link) - //return new App::DocumentObjectExecReturn("No object!"); - return App::DocumentObject::StdReturn; + return Part::TopoShape(); + //Base::Console().Error("Body tip: %s\n", link->getNameInDocument()); if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - return new App::DocumentObjectExecReturn("Linked object is not a PartDesign object"); - //return App::DocumentObject::StdReturn; + //return new App::DocumentObjectExecReturn("Linked object is not a PartDesign object"); + return Part::TopoShape(); // get the shape of the tip - const Part::TopoShape& TipShape = static_cast(link)->Shape.getShape(); + return static_cast(link)->Shape.getShape(); +} + +const Part::TopoShape Body::getPreviousSolid(const PartDesign::Feature* f) +{ + std::vector features = Model.getValues(); + std::vector::const_iterator it = std::find(features.begin(), features.end(), f); + if ((it == features.end()) || (it == features.begin())) + // Wrong body or there is no previous feature + return Part::TopoShape(); + // move to previous feature + it--; + // Skip sketches + while (!(*it)->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId())) { + if (it == features.begin()) + return Part::TopoShape(); + it--; + } + + return static_cast(*it)->Shape.getShape(); +} + +const bool Body::hasFeature(const PartDesign::Feature* f) +{ + std::vector features = Model.getValues(); + return std::find(features.begin(), features.end(), f) != features.end(); +} + +App::DocumentObjectExecReturn *Body::execute(void) +{ + std::vector children = Model.getValues(); + //Base::Console().Error("Body exec children:\n"); + //for (std::vector::const_iterator o = children.begin(); o != children.end(); o++) + // Base::Console().Error("%s\n", (*o)->getNameInDocument()); + + const Part::TopoShape& TipShape = getTipShape(); + if (TipShape._Shape.IsNull()) //return new App::DocumentObjectExecReturn("empty shape"); return App::DocumentObject::StdReturn; @@ -82,4 +120,4 @@ PyObject *Body::getPyObject(void) return Py::new_reference_to(PythonObject); } -} \ No newline at end of file +} diff --git a/src/Mod/PartDesign/App/Body.h b/src/Mod/PartDesign/App/Body.h index ecf001f84..ffc46a517 100644 --- a/src/Mod/PartDesign/App/Body.h +++ b/src/Mod/PartDesign/App/Body.h @@ -31,6 +31,8 @@ namespace PartDesign { +class Feature; + class Body : public Part::BodyBase { PROPERTY_HEADER(PartDesign::Body); @@ -49,6 +51,15 @@ public: } //@} + /// Get the tip shape + const Part::TopoShape getTipShape(); + + /// Return the shape of the feature preceding this feature + const Part::TopoShape getPreviousSolid(const PartDesign::Feature* f); + + /// Return true if the feature belongs to this body + const bool hasFeature(const PartDesign::Feature* f); + PyObject *getPyObject(void); }; diff --git a/src/Mod/PartDesign/App/Feature.cpp b/src/Mod/PartDesign/App/Feature.cpp index 9fa351f04..3c08112d5 100644 --- a/src/Mod/PartDesign/App/Feature.cpp +++ b/src/Mod/PartDesign/App/Feature.cpp @@ -28,11 +28,13 @@ # include # include # include -# include +# include #endif #include +#include "App/Document.h" +#include "Body.h" #include "Feature.h" @@ -59,6 +61,17 @@ TopoDS_Shape Feature::getSolid(const TopoDS_Shape& shape) return TopoDS_Shape(); } +PartDesign::Body* Feature::getBody() +{ + std::vector bodies = this->getDocument()->getObjectsOfType(PartDesign::Body::getClassTypeId()); + for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) { + PartDesign::Body* body = static_cast(*b); + if (body->hasFeature(this)) + return body; + } + return NULL; +} + const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) { if (!f.Infinite()) { @@ -73,5 +86,5 @@ const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) // Or get a "corner" point if the face is limited? throw Base::Exception("getPointFromFace(): Not implemented yet for this case"); } - + } diff --git a/src/Mod/PartDesign/App/Feature.h b/src/Mod/PartDesign/App/Feature.h index 42c9a3173..43e1be04c 100644 --- a/src/Mod/PartDesign/App/Feature.h +++ b/src/Mod/PartDesign/App/Feature.h @@ -34,6 +34,8 @@ class gp_Pnt; namespace PartDesign { +class Body; + /** PartDesign feature * Base class of all PartDesign features. * This kind of features only produce solids or fail. @@ -46,11 +48,14 @@ public: Feature(); protected: + /// Get the body feature which this feature belongs to + Body* getBody(); + /** * Get a solid of the given shape. If no solid is found an exception is raised. */ - static TopoDS_Shape getSolid(const TopoDS_Shape&); - + static TopoDS_Shape getSolid(const TopoDS_Shape&); + /// Grab any point from the given face static const gp_Pnt getPointFromFace(const TopoDS_Face& f); diff --git a/src/Mod/PartDesign/App/FeaturePad.cpp b/src/Mod/PartDesign/App/FeaturePad.cpp index ca291fd2c..c8df8364b 100644 --- a/src/Mod/PartDesign/App/FeaturePad.cpp +++ b/src/Mod/PartDesign/App/FeaturePad.cpp @@ -47,6 +47,7 @@ #include #include +#include "Body.h" #include "FeaturePad.h" @@ -95,13 +96,23 @@ App::DocumentObjectExecReturn *Pad::execute(void) return new App::DocumentObjectExecReturn(e.what()); } + // Find active Body feature and get the shape of the feature preceding this one for fusing + PartDesign::Body* body = getBody(); + if (body == NULL) { + return new App::DocumentObjectExecReturn( + "In order to use PartDesign you need an active Body object in the document. " + "Please make one active or create one. If you have a legacy document " + "with PartDesign objects without Body, use the transfer function in " + "PartDesign to put them into a Body." + ); + } + const Part::TopoShape& prevShape = body->getPreviousSolid(this); TopoDS_Shape support; - try { - support = getSupportShape(); - } catch (const Base::Exception&) { + if (prevShape.isNull()) // ignore, because support isn't mandatory support = TopoDS_Shape(); - } + else + support = prevShape._Shape; // get the Sketch plane Base::Placement SketchPos = sketch->Placement.getValue(); diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 868229ea5..4d26f1473 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -1,1439 +1,1323 @@ -/*************************************************************************** - * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * - * * - * 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" -#ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "FeaturePickDialog.h" - -using namespace std; - -extern PartDesign::Body *ActivePartObject; - -namespace Gui { -//=========================================================================== -// Common utility functions -//=========================================================================== - -// Take a list of Part2DObjects and erase those which are not eligible for creating a -// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define -// a Subtractive feature -void validateSketches(std::vector& sketches, const bool supportRequired) -{ - std::vector::iterator s = sketches.begin(); - - while (s != sketches.end()) { - // sketch is allways part of the body first. - //// Check whether this sketch is already being used by another feature - //std::vector ref = (*s)->getInList(); - //std::vector::iterator r = ref.begin(); - //while (r != ref.end()) { - // if (!(*r)->getTypeId().isDerivedFrom(PartDesign::SketchBased().getClassTypeId())) { - // r = ref.erase(r); - // continue; - // } - // ++r; - //} - //if (!ref.empty()) { - // // TODO: Display some information message that this sketch was removed? - // s = sketches.erase(s); - // continue; - //} - - // Check whether the sketch shape is valid - Part::Part2DObject* sketch = static_cast(*s); - const TopoDS_Shape& shape = sketch->Shape.getValue(); - if (shape.IsNull()) { - s = sketches.erase(s); - continue; - // TODO: Display some information message that this sketch was removed? - } - - // count free wires - int ctWires=0; - TopExp_Explorer ex; - for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { - ctWires++; - } - if (ctWires == 0) { - s = sketches.erase(s); - continue; - // TODO: Display some information message that this sketch was removed? - } - - // Check for support - if (supportRequired) { - App::DocumentObject* support = sketch->Support.getValue(); - if (support == NULL) { - s = sketches.erase(s); - continue; - // TODO: Display some information message that this sketch was removed? - } - } - - // All checks passed - go on to next candidate - s++; - } -} -} // namespace Gui - -//=========================================================================== -// Helper for Body -//=========================================================================== - -PartDesign::Body *getBody(void) -{ - if(!ActivePartObject){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"), - QObject::tr("To do PartDesign you need a active Body object in the documnt. Please make one active or create one. If you have a document with PartDesign objects without Body, use the transfer methode in PartDesign to put it into a Body.")); - } - return ActivePartObject; - -} - - -//=========================================================================== -// Part_Pad -//=========================================================================== - -/* Sketch commands =======================================================*/ -DEF_STD_CMD_A(CmdPartDesignNewSketch); - -CmdPartDesignNewSketch::CmdPartDesignNewSketch() - :Command("PartDesign_NewSketch") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Create sketch"); - sToolTipText = QT_TR_NOOP("Create a new sketch"); - sWhatsThis = sToolTipText; - sStatusTip = sToolTipText; - sPixmap = "Sketcher_NewSketch"; -} - - -void CmdPartDesignNewSketch::activated(int iMsg) -{ - PartDesign::Body *pcActiveBody = getBody(); - - // No PartDesign feature without Body past FreeCAD 0.13 - if(!pcActiveBody) return; - - Gui::SelectionFilter SketchFilter("SELECT Sketcher::SketchObject COUNT 1"); - Gui::SelectionFilter FaceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1"); - - if (SketchFilter.match()) { - Sketcher::SketchObject *Sketch = static_cast(SketchFilter.Result[0][0].getObject()); - openCommand("Edit Sketch"); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",Sketch->getNameInDocument()); - } - else if (FaceFilter.match()) { - // get the selected object - Part::Feature *part = static_cast(FaceFilter.Result[0][0].getObject()); - Base::Placement ObjectPos = part->Placement.getValue(); - const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); - if (sub.size() > 1){ - // No assert for wrong user input! - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Several sub-elements selected"), - QObject::tr("You have to select a single face as support for a sketch!")); - return; - } - // get the selected sub shape (a Face) - const Part::TopoShape &shape = part->Shape.getValue(); - TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); - const TopoDS_Face& face = TopoDS::Face(sh); - if (face.IsNull()){ - // No assert for wrong user input! - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No support face selected"), - QObject::tr("You have to select a face as support for a sketch!")); - return; - } - - BRepAdaptor_Surface adapt(face); - if (adapt.GetType() != GeomAbs_Plane){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No planar support"), - QObject::tr("You need a planar face as support for a sketch!")); - return; - } - - std::string supportString = FaceFilter.Result[0][0].getAsPropertyLinkSubString(); - - // create Sketch on Face - std::string FeatName = getUniqueObjectName("Sketch"); - - openCommand("Create a Sketch on Face"); - doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Gui,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); - doCommand(Gui,"App.activeDocument().recompute()"); // recompute the sketch placement based on its support - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - else { - // ask user for orientation - SketcherGui::SketchOrientationDialog Dlg; - - if (Dlg.exec() != QDialog::Accepted) - return; // canceled - Base::Vector3d p = Dlg.Pos.getPosition(); - Base::Rotation r = Dlg.Pos.getRotation(); - - // do the right view direction - std::string camstring; - switch(Dlg.DirType){ - case 0: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 87 \\n orientation 0 0 1 0 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; - break; - case 1: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 -87 \\n orientation -1 0 0 3.1415927 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; - break; - case 2: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 -87 0 \\n orientation -1 0 0 4.712389\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; - break; - case 3: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 87 0 \\n orientation 0 0.70710683 0.70710683 3.1415927\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; - break; - case 4: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 87 0 0 \\n orientation 0.57735026 0.57735026 0.57735026 2.0943952 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; - break; - case 5: - camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position -87 0 0 \\n orientation -0.57735026 0.57735026 0.57735026 4.1887903 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; - break; - } - std::string FeatName = getUniqueObjectName("Sketch"); - - openCommand("Create a new Sketch"); - doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))",FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]); - doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",camstring.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - } - -} - -bool CmdPartDesignNewSketch::isActive(void) -{ - if (getActiveGuiDocument()) - return true; - else - return false; -} - -//=========================================================================== -// PartDesign_Pad -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPad); - -CmdPartDesignPad::CmdPartDesignPad() - : Command("PartDesign_Pad") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Pad"); - sToolTipText = QT_TR_NOOP("Pad a selected sketch"); - sWhatsThis = "PartDesign_Pad"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Pad"; -} - -void CmdPartDesignPad::activated(int iMsg) -{ - PartDesign::Body *pcActiveBody = getBody(); - - bool bNoSketchWasSelected = false; - // Get a valid sketch from the user - // First check selections - std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (sketches.size() == 0) {//no sketches were selected. Let user pick an object from valid ones available in document - sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); - bNoSketchWasSelected = true; - } - Gui::validateSketches(sketches, false); - if (sketches.size() == 0) { - if (bNoSketchWasSelected) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), - QObject::tr("Please create a sketch or 2D object first.")); - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches selected"), - QObject::tr("None of selected sketches/2D objects is valid for padding. Please select a valid sketch or 2D object that is not used by any other feature.")); - } - return; - } - - // If there is more than one selection/possibility, show dialog and let user pick sketch - if (sketches.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } - - Part::Part2DObject* sketch = static_cast(sketches.front()); - App::DocumentObject* support = sketch->Support.getValue(); - std::string FeatName = getUniqueObjectName("Pad"); - - openCommand("Make Pad"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pad\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - updateActive(); - if (isActiveObjectValid()) { - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - if (support) - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - // #0001721: use '0' as edit value to avoid switching off selection in - // ViewProviderGeometryObject::setEditViewer - doCommand(Gui,"Gui.activeDocument().setEdit('%s',0)",FeatName.c_str()); - - //commitCommand(); - adjustCameraPosition(); - - if (support) { - copyVisual(FeatName.c_str(), "ShapeColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); - } -} - -bool CmdPartDesignPad::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Pocket -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPocket); - -CmdPartDesignPocket::CmdPartDesignPocket() - : Command("PartDesign_Pocket") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Pocket"); - sToolTipText = QT_TR_NOOP("Create a pocket with the selected sketch"); - sWhatsThis = "PartDesign_Pocket"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Pocket"; -} - -void CmdPartDesignPocket::activated(int iMsg) -{ - PartDesign::Body *pcActiveBody = getBody(); - - // Get a valid sketch from the user - // First check selections - std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Gui::validateSketches(sketches, true); - // Next let the user choose from a list of all eligible objects - if (sketches.size() == 0) { - sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Gui::validateSketches(sketches, true); - if (sketches.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), - QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid.")); - return; - } - } - // If there is more than one selection/possibility, show dialog and let user pick sketch - if (sketches.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } - - Part::Part2DObject* sketch = static_cast(sketches.front()); - App::DocumentObject* support = sketch->Support.getValue(); - std::string FeatName = getUniqueObjectName("Pocket"); - - openCommand("Make Pocket"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Pocket\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - updateActive(); - if (isActiveObjectValid()) { - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - copyVisual(FeatName.c_str(), "ShapeColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); -} - -bool CmdPartDesignPocket::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Revolution -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignRevolution); - -CmdPartDesignRevolution::CmdPartDesignRevolution() - : Command("PartDesign_Revolution") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Revolution"); - sToolTipText = QT_TR_NOOP("Revolve a selected sketch"); - sWhatsThis = "PartDesign_Revolution"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Revolution"; -} - -void CmdPartDesignRevolution::activated(int iMsg) -{ - PartDesign::Body *pcActiveBody = getBody(); - - bool bNoSketchWasSelected = false; - // Get a valid sketch from the user - // First check selections - std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - if (sketches.size() == 0) {//no sketches were selected. Let user pick an object from valid ones available in document - sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); - bNoSketchWasSelected = true; - } - Gui::validateSketches(sketches, false); - if (sketches.size() == 0) { - if (bNoSketchWasSelected) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), - QObject::tr("Please create a sketch or 2D object first.")); - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches selected"), - QObject::tr("None of selected sketches/2D objects is valid for revolving. Please select a valid sketch or 2D object that is not used by any other feature.")); - } - return; - } - - // If there is more than one selection/possibility, show dialog and let user pick sketch - if (sketches.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } - - Part::Part2DObject* sketch = static_cast(sketches.front()); - App::DocumentObject* support = sketch->Support.getValue(); - std::string FeatName = getUniqueObjectName("Revolution"); - - openCommand("Make Revolution"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Revolution\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Revolution* pcRevolution = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcRevolution && pcRevolution->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - updateActive(); - if (isActiveObjectValid()) { - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - if (support) - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - if (support) { - copyVisual(FeatName.c_str(), "ShapeColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); - } -} - -bool CmdPartDesignRevolution::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Groove -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignGroove); - -CmdPartDesignGroove::CmdPartDesignGroove() - : Command("PartDesign_Groove") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Groove"); - sToolTipText = QT_TR_NOOP("Groove a selected sketch"); - sWhatsThis = "PartDesign_Groove"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Groove"; -} - -void CmdPartDesignGroove::activated(int iMsg) -{ -// // Get a valid sketch from the user -// // First check selections -// std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); -// Gui::validateSketches(sketches, true); -// // Next let the user choose from a list of all eligible objects -// if (sketches.size() == 0) { -// sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); -// Gui::validateSketches(sketches, true); -// if (sketches.size() == 0) { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), -// QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid.")); -// return; -// } -// } -// // If there is more than one selection/possibility, show dialog and let user pick sketch -// if (sketches.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(sketches); -// if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } -// -// Part::Part2DObject* sketch = static_cast(sketches.front()); -// App::DocumentObject* support = sketch->Support.getValue(); -// std::string FeatName = getUniqueObjectName("Groove"); -// -// openCommand("Make Groove"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Groove\",\"%s\")",FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); -// doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", -// FeatName.c_str(), sketch->getNameInDocument()); -// doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); -// PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); -// if (pcGroove && pcGroove->suggestReversed()) -// doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); -// App::DocumentObjectGroup* grp = sketch->getGroup(); -// if (grp) { -// doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),sketch->getNameInDocument()); -// } -// updateActive(); -// if (isActiveObjectValid()) { -// doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); -// if (support) -// doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); -// } -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// -// if (support) { -// copyVisual(FeatName.c_str(), "ShapeColor", support->getNameInDocument()); -// copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); -// copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); -// } -} - -bool CmdPartDesignGroove::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Fillet -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignFillet); - -CmdPartDesignFillet::CmdPartDesignFillet() - :Command("PartDesign_Fillet") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Fillet"); - sToolTipText = QT_TR_NOOP("Make a fillet on an edge, face or body"); - sWhatsThis = "PartDesign_Fillet"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Fillet"; -} - -void CmdPartDesignFillet::activated(int iMsg) -{ - std::vector selection = getSelection().getSelectionEx(); - - if (selection.size() != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body. Only one body is allowed.")); - return; - } - - if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("Fillet works only on parts.")); - return; - } - std::string SelString = selection[0].getAsPropertyLinkSubString(); - Part::Feature *base = static_cast(selection[0].getObject()); -// -// const Part::TopoShape& TopShape = base->Shape.getShape(); -// if (TopShape._Shape.IsNull()){ -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected part is empty.")); -// return; -// } -// -// TopTools_IndexedMapOfShape mapOfEdges; -// TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; -// TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); -// TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); -// -// std::vector SubNames = std::vector(selection[0].getSubNames()); -// -// unsigned int i = 0; -// -// while(i < SubNames.size()) -// { -// std::string aSubName = static_cast(SubNames.at(i)); -// -// if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { -// TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); -// const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); -// -// if(los.Extent() != 2) -// { -// SubNames.erase(SubNames.begin()+i); -// continue; -// } -// -// const TopoDS_Shape& face1 = los.First(); -// const TopoDS_Shape& face2 = los.Last(); -// GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), -// TopoDS::Face(face1), -// TopoDS::Face(face2)); -// if (cont != GeomAbs_C0) { -// SubNames.erase(SubNames.begin()+i); -// continue; -// } -// -// i++; -// } -// else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { -// TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); -// -// TopTools_IndexedMapOfShape mapOfFaces; -// TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); -// -// for(int j = 1; j <= mapOfFaces.Extent(); ++j) { -// TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); -// -// int id = mapOfEdges.FindIndex(edge); -// -// std::stringstream buf; -// buf << "Edge"; -// buf << id; -// -// if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) -// { -// SubNames.push_back(buf.str()); -// } -// -// } -// -// SubNames.erase(SubNames.begin()+i); -// } -// // empty name or any other sub-element -// else { -// SubNames.erase(SubNames.begin()+i); -// } -// } -// -// if (SubNames.size() == 0) { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No fillet possible on selected faces/edges.")); -// return; -// } -// -// std::string SelString; -// SelString += "(App."; -// SelString += "ActiveDocument";//getObject()->getDocument()->getName(); -// SelString += "."; -// SelString += selection[0].getFeatName(); -// SelString += ",["; -// for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ -// SelString += "\""; -// SelString += *it; -// SelString += "\""; -// if(it != --SubNames.end()) -// SelString += ","; -// } -// SelString += "])"; -// - std::string FeatName = getUniqueObjectName("Fillet"); - - openCommand("Make Fillet"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Fillet\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); - doCommand(Gui,"Gui.Selection.clearSelection()"); - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - App::DocumentObjectGroup* grp = base->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - } - - copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); -} - -bool CmdPartDesignFillet::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Chamfer -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignChamfer); - -CmdPartDesignChamfer::CmdPartDesignChamfer() - :Command("PartDesign_Chamfer") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Chamfer"); - sToolTipText = QT_TR_NOOP("Chamfer the selected edges of a shape"); - sWhatsThis = "PartDesign_Chamfer"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Chamfer"; -} - -void CmdPartDesignChamfer::activated(int iMsg) -{ - std::vector selection = getSelection().getSelectionEx(); - - if (selection.size() != 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select an edge, face or body. Only one body is allowed.")); - return; - } - - if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("Chamfer works only on parts.")); - return; - } - std::string SelString = selection[0].getAsPropertyLinkSubString(); - - Part::Feature *base = static_cast(selection[0].getObject()); -// -// const Part::TopoShape& TopShape = base->Shape.getShape(); -// -// if (TopShape._Shape.IsNull()){ -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected part is empty.")); -// return; -// } -// -// TopTools_IndexedMapOfShape mapOfEdges; -// TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; -// TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); -// TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); -// -// std::vector SubNames = std::vector(selection[0].getSubNames()); -// -// unsigned int i = 0; -// -// while(i < SubNames.size()) -// { -// std::string aSubName = static_cast(SubNames.at(i)); -// -// if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { -// TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); -// const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); -// -// if(los.Extent() != 2) -// { -// SubNames.erase(SubNames.begin()+i); -// continue; -// } -// -// const TopoDS_Shape& face1 = los.First(); -// const TopoDS_Shape& face2 = los.Last(); -// GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), -// TopoDS::Face(face1), -// TopoDS::Face(face2)); -// if (cont != GeomAbs_C0) { -// SubNames.erase(SubNames.begin()+i); -// continue; -// } -// -// i++; -// } -// else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { -// TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); -// -// TopTools_IndexedMapOfShape mapOfFaces; -// TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); -// -// for(int j = 1; j <= mapOfFaces.Extent(); ++j) { -// TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); -// -// int id = mapOfEdges.FindIndex(edge); -// -// std::stringstream buf; -// buf << "Edge"; -// buf << id; -// -// if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) -// { -// SubNames.push_back(buf.str()); -// } -// -// } -// -// SubNames.erase(SubNames.begin()+i); -// } -// // empty name or any other sub-element -// else { -// SubNames.erase(SubNames.begin()+i); -// } -// } -// -// if (SubNames.size() == 0) { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("No chamfer possible on selected faces/edges.")); -// return; -// } -// -// std::string SelString; -// SelString += "(App."; -// SelString += "ActiveDocument";//getObject()->getDocument()->getName(); -// SelString += "."; -// SelString += selection[0].getFeatName(); -// SelString += ",["; -// for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ -// SelString += "\""; -// SelString += *it; -// SelString += "\""; -// if(it != --SubNames.end()) -// SelString += ","; -// } -// SelString += "])"; -// - std::string FeatName = getUniqueObjectName("Chamfer"); - - openCommand("Make Chamfer"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); - doCommand(Gui,"Gui.Selection.clearSelection()"); - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - App::DocumentObjectGroup* grp = base->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - } - - copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); -} - -bool CmdPartDesignChamfer::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Draft -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignDraft); - -CmdPartDesignDraft::CmdPartDesignDraft() - :Command("PartDesign_Draft") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Draft"); - sToolTipText = QT_TR_NOOP("Make a draft on a face"); - sWhatsThis = "PartDesign_Draft"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Draft"; -} - -void CmdPartDesignDraft::activated(int iMsg) -{ -// std::vector selection = getSelection().getSelectionEx(); -// -// if (selection.size() < 1) { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("Select one or more faces.")); -// return; -// } -// -// if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), -// QObject::tr("Draft works only on parts.")); -// return; -// } -// -// Part::Feature *base = static_cast(selection[0].getObject()); -// -// const Part::TopoShape& TopShape = base->Shape.getShape(); -// if (TopShape._Shape.IsNull()){ -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("Shape of selected Part is empty.")); -// return; -// } -// -// std::vector SubNames = std::vector(selection[0].getSubNames()); -// unsigned int i = 0; -// -// while(i < SubNames.size()) -// { -// std::string aSubName = static_cast(SubNames.at(i)); -// -// if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { -// // Check for valid face types -// TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); -// BRepAdaptor_Surface sf(face); -// if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone)) -// SubNames.erase(SubNames.begin()+i); -// } else { -// // empty name or any other sub-element -// SubNames.erase(SubNames.begin()+i); -// } -// -// i++; -// } -// -// if (SubNames.size() == 0) { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("No draft possible on selected faces.")); -// return; -// } -// -// std::string SelString; -// SelString += "(App."; -// SelString += "ActiveDocument"; -// SelString += "."; -// SelString += selection[0].getFeatName(); -// SelString += ",["; -// for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ -// SelString += "\""; -// SelString += *it; -// SelString += "\""; -// if(it != --SubNames.end()) -// SelString += ","; -// } -// SelString += "])"; -// -// std::string FeatName = getUniqueObjectName("Draft"); -// -// // We don't create any defaults for neutral plane and pull direction, but Draft::execute() -// // will choose them. -// // Note: When the body feature is there, the best thing would be to get pull direction and -// // neutral plane from the preceding feature in the tree. Or even store them as default in -// // the Body feature itself -// openCommand("Make Draft"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Draft\",\"%s\")",FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Angle = %f",FeatName.c_str(), 1.5); -// updateActive(); -// if (isActiveObjectValid()) { -// doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); -// } -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// App::DocumentObjectGroup* grp = base->getGroup(); -// if (grp) { -// doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),FeatName.c_str()); -// } -// -// copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); -// copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); -// copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); -} - -bool CmdPartDesignDraft::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Mirrored -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignMirrored); - -CmdPartDesignMirrored::CmdPartDesignMirrored() - : Command("PartDesign_Mirrored") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Mirrored"); - sToolTipText = QT_TR_NOOP("Create a mirrored feature"); - sWhatsThis = "PartDesign_Mirrored"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Mirrored"; -} - -void CmdPartDesignMirrored::activated(int iMsg) -{ -// // Get a valid original from the user -// // First check selections -// std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // Next create a list of all eligible objects -// if (features.size() == 0) { -// features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // If there is more than one selected or eligible object, show dialog and let user pick one -// if (features.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(features); -// if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } else { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first.")); -// return; -// } -// } -// -// std::string FeatName = getUniqueObjectName("Mirrored"); -// -// std::stringstream str; -// std::vector tempSelNames; -// str << "App.activeDocument()." << FeatName << ".Originals = ["; -// for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ -// str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; -// tempSelNames.push_back((*it)->getNameInDocument()); -// } -// str << "]"; -// -// openCommand("Mirrored"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",FeatName.c_str()); -// // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like -// // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' -// updateActive(); // Helps to ensure that the object already exists when the next command comes up -// doCommand(Doc,str.str().c_str()); -// Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); -// if (sketch) -// doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", -// FeatName.c_str(), sketch->getNameInDocument()); -// for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) -// doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); -// -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// -// copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); -// copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -} - -bool CmdPartDesignMirrored::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_LinearPattern -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignLinearPattern); - -CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() - : Command("PartDesign_LinearPattern") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("LinearPattern"); - sToolTipText = QT_TR_NOOP("Create a linear pattern feature"); - sWhatsThis = "PartDesign_LinearPattern"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_LinearPattern"; -} - -void CmdPartDesignLinearPattern::activated(int iMsg) -{ -// // Get a valid original from the user -// // First check selections -// std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // Next create a list of all eligible objects -// if (features.size() == 0) { -// features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // If there is more than one selected or eligible object, show dialog and let user pick one -// if (features.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(features); -// if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } else { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please.")); -// return; -// } -// } -// -// std::string FeatName = getUniqueObjectName("LinearPattern"); -// -// std::stringstream str; -// std::vector tempSelNames; -// str << "App.activeDocument()." << FeatName << ".Originals = ["; -// for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ -// str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; -// tempSelNames.push_back((*it)->getNameInDocument()); -// } -// str << "]"; -// -// openCommand("LinearPattern"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str()); -// updateActive(); -// doCommand(Doc,str.str().c_str()); -// Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); -// if (sketch) -// doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", -// FeatName.c_str(), sketch->getNameInDocument()); -// doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); -// for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) -// doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); -// -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// App::DocumentObjectGroup* grp = sketch->getGroup(); -// if (grp) { -// doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),sketch->getNameInDocument()); -// } -// -// copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); -// copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -} - -bool CmdPartDesignLinearPattern::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_PolarPattern -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignPolarPattern); - -CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() - : Command("PartDesign_PolarPattern") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("PolarPattern"); - sToolTipText = QT_TR_NOOP("Create a polar pattern feature"); - sWhatsThis = "PartDesign_PolarPattern"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_PolarPattern"; -} - -void CmdPartDesignPolarPattern::activated(int iMsg) -{ -// // Get a valid original from the user -// // First check selections -// std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // Next create a list of all eligible objects -// if (features.size() == 0) { -// features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // If there is more than one selected or eligible object, show dialog and let user pick one -// if (features.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(features); -// if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } else { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please.")); -// return; -// } -// } -// -// std::string FeatName = getUniqueObjectName("PolarPattern"); -// -// std::stringstream str; -// std::vector tempSelNames; -// str << "App.activeDocument()." << FeatName << ".Originals = ["; -// for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ -// str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; -// tempSelNames.push_back((*it)->getNameInDocument()); -// } -// str << "]"; -// -// openCommand("PolarPattern"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str()); -// updateActive(); -// doCommand(Doc,str.str().c_str()); -// Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); -// if (sketch) -// doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", -// FeatName.c_str(), sketch->getNameInDocument()); -// doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); -// for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) -// doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); -// -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// App::DocumentObjectGroup* grp = sketch->getGroup(); -// if (grp) { -// doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" -// ,grp->getNameInDocument(),sketch->getNameInDocument()); -// } -// -// copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); -// copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -} - -bool CmdPartDesignPolarPattern::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_Scaled -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignScaled); - -CmdPartDesignScaled::CmdPartDesignScaled() - : Command("PartDesign_Scaled") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("Scaled"); - sToolTipText = QT_TR_NOOP("Create a scaled feature"); - sWhatsThis = "PartDesign_Scaled"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_Scaled"; -} - -void CmdPartDesignScaled::activated(int iMsg) -{ -// // Get a valid original from the user -// // First check selections -// std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // Next create a list of all eligible objects -// if (features.size() == 0) { -// features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // If there is more than one selected or eligible object, show dialog and let user pick one -// if (features.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(features); -// if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } else { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please.")); -// return; -// } -// } -// -// std::string FeatName = getUniqueObjectName("Scaled"); -// -// std::stringstream str; -// std::vector tempSelNames; -// str << "App.activeDocument()." << FeatName << ".Originals = ["; -// for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ -// str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; -// tempSelNames.push_back((*it)->getNameInDocument()); -// } -// str << "]"; -// -// openCommand("Scaled"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",FeatName.c_str()); -// updateActive(); -// doCommand(Doc,str.str().c_str()); -// doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); -// for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) -// doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); -// -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// -// copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); -// copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -} - -bool CmdPartDesignScaled::isActive(void) -{ - return hasActiveDocument(); -} - -//=========================================================================== -// PartDesign_MultiTransform -//=========================================================================== -DEF_STD_CMD_A(CmdPartDesignMultiTransform); - -CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() - : Command("PartDesign_MultiTransform") -{ - sAppModule = "PartDesign"; - sGroup = QT_TR_NOOP("PartDesign"); - sMenuText = QT_TR_NOOP("MultiTransform"); - sToolTipText = QT_TR_NOOP("Create a multitransform feature"); - sWhatsThis = "PartDesign_MultiTransform"; - sStatusTip = sToolTipText; - sPixmap = "PartDesign_MultiTransform"; -} - -void CmdPartDesignMultiTransform::activated(int iMsg) -{ -// // Get a valid original from the user -// // First check selections -// std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // Next create a list of all eligible objects -// if (features.size() == 0) { -// features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); -// subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); -// features.insert(features.end(), subtractive.begin(), subtractive.end()); -// // If there is more than one selected or eligible object, show dialog and let user pick one -// if (features.size() > 1) { -// PartDesignGui::FeaturePickDialog Dlg(features); -// if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) -// return; // Cancelled or nothing selected -// } else { -// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please.")); -// return; -// } -// } -// -// std::string FeatName = getUniqueObjectName("MultiTransform"); -// -// std::stringstream str; -// std::vector tempSelNames; -// str << "App.activeDocument()." << FeatName << ".Originals = ["; -// for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ -// str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; -// tempSelNames.push_back((*it)->getNameInDocument()); -// } -// str << "]"; -// -// openCommand("MultiTransform"); -// doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")",FeatName.c_str()); -// updateActive(); -// doCommand(Doc,str.str().c_str()); -// -// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); -// -// copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); -// copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -} - -bool CmdPartDesignMultiTransform::isActive(void) -{ - return hasActiveDocument(); -} - - -//=========================================================================== -// Initialization -//=========================================================================== - -void CreatePartDesignCommands(void) -{ - Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); - - rcCmdMgr.addCommand(new CmdPartDesignPad()); - rcCmdMgr.addCommand(new CmdPartDesignPocket()); - rcCmdMgr.addCommand(new CmdPartDesignRevolution()); -// rcCmdMgr.addCommand(new CmdPartDesignGroove()); - rcCmdMgr.addCommand(new CmdPartDesignFillet()); -// rcCmdMgr.addCommand(new CmdPartDesignDraft()); - rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); - rcCmdMgr.addCommand(new CmdPartDesignChamfer()); -// rcCmdMgr.addCommand(new CmdPartDesignMirrored()); -// rcCmdMgr.addCommand(new CmdPartDesignLinearPattern()); -// rcCmdMgr.addCommand(new CmdPartDesignPolarPattern()); -// //rcCmdMgr.addCommand(new CmdPartDesignScaled()); -// rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); - } +/*************************************************************************** + * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * + * * + * 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" +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "FeaturePickDialog.h" + +using namespace std; + +extern PartDesign::Body *ActivePartObject; + + +//=========================================================================== +// Helper for Body +//=========================================================================== + +PartDesign::Body *getBody(void) +{ + if(!ActivePartObject){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"), + QObject::tr("In order to use PartDesign you need an active Body object in the document. " + "Please make one active or create one. If you have a legacy document " + "with PartDesign objects without Body, use the transfer function in " + "PartDesign to put them into a Body." + )); + } + return ActivePartObject; + +} + + +//=========================================================================== +// PartDesign_Sketch +//=========================================================================== + +/* Sketch commands =======================================================*/ +DEF_STD_CMD_A(CmdPartDesignNewSketch); + +CmdPartDesignNewSketch::CmdPartDesignNewSketch() + :Command("PartDesign_NewSketch") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Create sketch"); + sToolTipText = QT_TR_NOOP("Create a new sketch"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_NewSketch"; +} + + +void CmdPartDesignNewSketch::activated(int iMsg) +{ + PartDesign::Body *pcActiveBody = getBody(); + + // No PartDesign feature without Body past FreeCAD 0.13 + if(!pcActiveBody) return; + + Gui::SelectionFilter SketchFilter("SELECT Sketcher::SketchObject COUNT 1"); + Gui::SelectionFilter FaceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1"); + + if (SketchFilter.match()) { + Sketcher::SketchObject *Sketch = static_cast(SketchFilter.Result[0][0].getObject()); + openCommand("Edit Sketch"); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",Sketch->getNameInDocument()); + } + else if (FaceFilter.match()) { + // get the selected object + Part::Feature *part = static_cast(FaceFilter.Result[0][0].getObject()); + Base::Placement ObjectPos = part->Placement.getValue(); + const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); + if (sub.size() > 1){ + // No assert for wrong user input! + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Several sub-elements selected"), + QObject::tr("You have to select a single face as support for a sketch!")); + return; + } + // get the selected sub shape (a Face) + const Part::TopoShape &shape = part->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); + const TopoDS_Face& face = TopoDS::Face(sh); + if (face.IsNull()){ + // No assert for wrong user input! + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No support face selected"), + QObject::tr("You have to select a face as support for a sketch!")); + return; + } + + BRepAdaptor_Surface adapt(face); + if (adapt.GetType() != GeomAbs_Plane){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No planar support"), + QObject::tr("You need a planar face as support for a sketch!")); + return; + } + + std::string supportString = FaceFilter.Result[0][0].getAsPropertyLinkSubString(); + + // create Sketch on Face + std::string FeatName = getUniqueObjectName("Sketch"); + + openCommand("Create a Sketch on Face"); + doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Gui,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); + doCommand(Gui,"App.activeDocument().recompute()"); // recompute the sketch placement based on its support + //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + else { + // ask user for orientation + SketcherGui::SketchOrientationDialog Dlg; + + if (Dlg.exec() != QDialog::Accepted) + return; // canceled + Base::Vector3d p = Dlg.Pos.getPosition(); + Base::Rotation r = Dlg.Pos.getRotation(); + + // do the right view direction + std::string camstring; + switch(Dlg.DirType){ + case 0: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 87 \\n orientation 0 0 1 0 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; + break; + case 1: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 -87 \\n orientation -1 0 0 3.1415927 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; + break; + case 2: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 -87 0 \\n orientation -1 0 0 4.712389\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 3: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 87 0 \\n orientation 0 0.70710683 0.70710683 3.1415927\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 4: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 87 0 0 \\n orientation 0.57735026 0.57735026 0.57735026 2.0943952 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 5: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position -87 0 0 \\n orientation -0.57735026 0.57735026 0.57735026 4.1887903 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + } + std::string FeatName = getUniqueObjectName("Sketch"); + + openCommand("Create a new Sketch"); + doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))",FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]); + doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",camstring.c_str()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + +} + +bool CmdPartDesignNewSketch::isActive(void) +{ + if (getActiveGuiDocument()) + return true; + else + return false; +} + +//=========================================================================== +// Common utility functions for SketchBased features +//=========================================================================== + +// Take a list of Part2DObjects and erase those which are not eligible for creating a +// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define +// a Subtractive feature +void validateSketches(std::vector& sketches, const bool supportRequired) +{ + std::vector::iterator s = sketches.begin(); + + while (s != sketches.end()) { + // sketch is always part of the body first. + //// Check whether this sketch is already being used by another feature + //std::vector ref = (*s)->getInList(); + //std::vector::iterator r = ref.begin(); + //while (r != ref.end()) { + // if (!(*r)->getTypeId().isDerivedFrom(PartDesign::SketchBased().getClassTypeId())) { + // r = ref.erase(r); + // continue; + // } + // ++r; + //} + //if (!ref.empty()) { + // // TODO: Display some information message that this sketch was removed? + // s = sketches.erase(s); + // continue; + //} + + // Check whether the sketch shape is valid + Part::Part2DObject* sketch = static_cast(*s); + const TopoDS_Shape& shape = sketch->Shape.getValue(); + if (shape.IsNull()) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // count free wires + int ctWires=0; + TopExp_Explorer ex; + for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { + ctWires++; + } + if (ctWires == 0) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // Check for support + if (supportRequired) { + App::DocumentObject* support = sketch->Support.getValue(); + if (support == NULL) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + } + + // All checks passed - go on to next candidate + s++; + } +} + +void prepareSketchBased(Gui::Command* cmd, const std::string& which, + Part::Part2DObject*& sketch, std::string& FeatName) +{ + PartDesign::Body *pcActiveBody = getBody(); + if (!pcActiveBody) return; + + bool bNoSketchWasSelected = false; + // Get a valid sketch from the user + // First check selections + std::vector sketches = cmd->getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = cmd->getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + bNoSketchWasSelected = true; + } + if (sketches.size() == 0) { + if (bNoSketchWasSelected) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first.")); + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches selected"), + QObject::tr("None of selected sketches/2D objects is valid for padding. Please select a valid sketch or 2D object that is not used by any other feature.")); + } + return; + } + + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } + + sketch = static_cast(sketches.front()); + FeatName = cmd->getUniqueObjectName(which.c_str()); + + cmd->openCommand((std::string("Make ") + which).c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); +} + +void finishSketchBased(const Gui::Command* cmd, const Part::Part2DObject* sketch, const std::string& FeatName) +{ + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + cmd->updateActive(); + if (cmd->isActiveObjectValid()) { + cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", sketch->getNameInDocument()); + } + // #0001721: use '0' as edit value to avoid switching off selection in + // ViewProviderGeometryObject::setEditViewer + cmd->doCommand(cmd->Gui,"Gui.activeDocument().setEdit('%s', 0)", FeatName.c_str()); + + /* + PartDesign::Body *pcActiveBody = getBody(); + if (pcActiveBody) { + cmd->copyVisual(FeatName.c_str(), "ShapeColor", pcActiveBody->getNameInDocument()); + cmd->copyVisual(FeatName.c_str(), "LineColor", pcActiveBody->getNameInDocument()); + cmd->copyVisual(FeatName.c_str(), "PointColor", pcActiveBody->getNameInDocument()); + }*/ +} + +//=========================================================================== +// PartDesign_Pad +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPad); + +CmdPartDesignPad::CmdPartDesignPad() + : Command("PartDesign_Pad") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Pad"); + sToolTipText = QT_TR_NOOP("Pad a selected sketch"); + sWhatsThis = "PartDesign_Pad"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Pad"; +} + +void CmdPartDesignPad::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Pad", sketch, FeatName); + + // specific parameters for Pad + doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignPad::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Pocket +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPocket); + +CmdPartDesignPocket::CmdPartDesignPocket() + : Command("PartDesign_Pocket") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Pocket"); + sToolTipText = QT_TR_NOOP("Create a pocket with the selected sketch"); + sWhatsThis = "PartDesign_Pocket"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Pocket"; +} + +void CmdPartDesignPocket::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Pocket", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignPocket::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Revolution +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignRevolution); + +CmdPartDesignRevolution::CmdPartDesignRevolution() + : Command("PartDesign_Revolution") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Revolution"); + sToolTipText = QT_TR_NOOP("Revolve a selected sketch"); + sWhatsThis = "PartDesign_Revolution"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Revolution"; +} + +void CmdPartDesignRevolution::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Revolution", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Revolution* pcRevolution = static_cast(getDocument()->getObject(FeatName.c_str())); + if (pcRevolution && pcRevolution->suggestReversed()) + doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignRevolution::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Groove +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignGroove); + +CmdPartDesignGroove::CmdPartDesignGroove() + : Command("PartDesign_Groove") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Groove"); + sToolTipText = QT_TR_NOOP("Groove a selected sketch"); + sWhatsThis = "PartDesign_Groove"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Groove"; +} + +void CmdPartDesignGroove::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Groove", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); + if (pcGroove && pcGroove->suggestReversed()) + doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignGroove::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Fillet +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignFillet); + +CmdPartDesignFillet::CmdPartDesignFillet() + :Command("PartDesign_Fillet") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Fillet"); + sToolTipText = QT_TR_NOOP("Make a fillet on an edge, face or body"); + sWhatsThis = "PartDesign_Fillet"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Fillet"; +} + +void CmdPartDesignFillet::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Fillet works only on parts.")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected part is empty.")); + return; + } + + TopTools_IndexedMapOfShape mapOfEdges; + TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; + TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); + + std::vector SubNames = std::vector(selection[0].getSubNames()); + + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { + TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); + const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); + + if(los.Extent() != 2) + { + SubNames.erase(SubNames.begin()+i); + continue; + } + + const TopoDS_Shape& face1 = los.First(); + const TopoDS_Shape& face2 = los.Last(); + GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), + TopoDS::Face(face1), + TopoDS::Face(face2)); + if (cont != GeomAbs_C0) { + SubNames.erase(SubNames.begin()+i); + continue; + } + + i++; + } + else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + + TopTools_IndexedMapOfShape mapOfFaces; + TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); + + for(int j = 1; j <= mapOfFaces.Extent(); ++j) { + TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); + + int id = mapOfEdges.FindIndex(edge); + + std::stringstream buf; + buf << "Edge"; + buf << id; + + if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) + { + SubNames.push_back(buf.str()); + } + + } + + SubNames.erase(SubNames.begin()+i); + } + // empty name or any other sub-element + else { + SubNames.erase(SubNames.begin()+i); + } + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No fillet possible on selected faces/edges.")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument";//getObject()->getDocument()->getName(); + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Fillet"); + + openCommand("Make Fillet"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Fillet\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Gui,"Gui.Selection.clearSelection()"); + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignFillet::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Chamfer +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignChamfer); + +CmdPartDesignChamfer::CmdPartDesignChamfer() + :Command("PartDesign_Chamfer") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Chamfer"); + sToolTipText = QT_TR_NOOP("Chamfer the selected edges of a shape"); + sWhatsThis = "PartDesign_Chamfer"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Chamfer"; +} + +void CmdPartDesignChamfer::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Chamfer works only on parts.")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected part is empty.")); + return; + } + + TopTools_IndexedMapOfShape mapOfEdges; + TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; + TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); + + std::vector SubNames = std::vector(selection[0].getSubNames()); + + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { + TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); + const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); + + if(los.Extent() != 2) + { + SubNames.erase(SubNames.begin()+i); + continue; + } + + const TopoDS_Shape& face1 = los.First(); + const TopoDS_Shape& face2 = los.Last(); + GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), + TopoDS::Face(face1), + TopoDS::Face(face2)); + if (cont != GeomAbs_C0) { + SubNames.erase(SubNames.begin()+i); + continue; + } + + i++; + } + else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + + TopTools_IndexedMapOfShape mapOfFaces; + TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); + + for(int j = 1; j <= mapOfFaces.Extent(); ++j) { + TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); + + int id = mapOfEdges.FindIndex(edge); + + std::stringstream buf; + buf << "Edge"; + buf << id; + + if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) + { + SubNames.push_back(buf.str()); + } + + } + + SubNames.erase(SubNames.begin()+i); + } + // empty name or any other sub-element + else { + SubNames.erase(SubNames.begin()+i); + } + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No chamfer possible on selected faces/edges.")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument";//getObject()->getDocument()->getName(); + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Chamfer"); + + openCommand("Make Chamfer"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Gui,"Gui.Selection.clearSelection()"); + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignChamfer::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Draft +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignDraft); + +CmdPartDesignDraft::CmdPartDesignDraft() + :Command("PartDesign_Draft") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Draft"); + sToolTipText = QT_TR_NOOP("Make a draft on a face"); + sWhatsThis = "PartDesign_Draft"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Draft"; +} + +void CmdPartDesignDraft::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() < 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select one or more faces.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Draft works only on parts.")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected Part is empty.")); + return; + } + + std::vector SubNames = std::vector(selection[0].getSubNames()); + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + // Check for valid face types + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + BRepAdaptor_Surface sf(face); + if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone)) + SubNames.erase(SubNames.begin()+i); + } else { + // empty name or any other sub-element + SubNames.erase(SubNames.begin()+i); + } + + i++; + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No draft possible on selected faces.")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument"; + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Draft"); + + // We don't create any defaults for neutral plane and pull direction, but Draft::execute() + // will choose them. + // Note: When the body feature is there, the best thing would be to get pull direction and + // neutral plane from the preceding feature in the tree. Or even store them as default in + // the Body feature itself + openCommand("Make Draft"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Draft\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Doc,"App.activeDocument().%s.Angle = %f",FeatName.c_str(), 1.5); + updateActive(); + if (isActiveObjectValid()) { + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + } + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignDraft::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Mirrored +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignMirrored); + +CmdPartDesignMirrored::CmdPartDesignMirrored() + : Command("PartDesign_Mirrored") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Mirrored"); + sToolTipText = QT_TR_NOOP("Create a mirrored feature"); + sWhatsThis = "PartDesign_Mirrored"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Mirrored"; +} + +void CmdPartDesignMirrored::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first.")); + return; + } + } + + std::string FeatName = getUniqueObjectName("Mirrored"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("Mirrored"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",FeatName.c_str()); + // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like + // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' + updateActive(); // Helps to ensure that the object already exists when the next command comes up + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignMirrored::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_LinearPattern +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignLinearPattern); + +CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() + : Command("PartDesign_LinearPattern") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("LinearPattern"); + sToolTipText = QT_TR_NOOP("Create a linear pattern feature"); + sWhatsThis = "PartDesign_LinearPattern"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_LinearPattern"; +} + +void CmdPartDesignLinearPattern::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please.")); + return; + } + } + + std::string FeatName = getUniqueObjectName("LinearPattern"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("LinearPattern"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignLinearPattern::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_PolarPattern +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPolarPattern); + +CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() + : Command("PartDesign_PolarPattern") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("PolarPattern"); + sToolTipText = QT_TR_NOOP("Create a polar pattern feature"); + sWhatsThis = "PartDesign_PolarPattern"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_PolarPattern"; +} + +void CmdPartDesignPolarPattern::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please.")); + return; + } + } + + std::string FeatName = getUniqueObjectName("PolarPattern"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("PolarPattern"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignPolarPattern::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Scaled +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignScaled); + +CmdPartDesignScaled::CmdPartDesignScaled() + : Command("PartDesign_Scaled") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Scaled"); + sToolTipText = QT_TR_NOOP("Create a scaled feature"); + sWhatsThis = "PartDesign_Scaled"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Scaled"; +} + +void CmdPartDesignScaled::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please.")); + return; + } + } + + std::string FeatName = getUniqueObjectName("Scaled"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("Scaled"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignScaled::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_MultiTransform +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignMultiTransform); + +CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() + : Command("PartDesign_MultiTransform") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("MultiTransform"); + sToolTipText = QT_TR_NOOP("Create a multitransform feature"); + sWhatsThis = "PartDesign_MultiTransform"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_MultiTransform"; +} + +void CmdPartDesignMultiTransform::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please.")); + return; + } + } + + std::string FeatName = getUniqueObjectName("MultiTransform"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("MultiTransform"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignMultiTransform::isActive(void) +{ + return hasActiveDocument(); +} + + +//=========================================================================== +// Initialization +//=========================================================================== + +void CreatePartDesignCommands(void) +{ + Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); + + rcCmdMgr.addCommand(new CmdPartDesignPad()); + rcCmdMgr.addCommand(new CmdPartDesignPocket()); + rcCmdMgr.addCommand(new CmdPartDesignRevolution()); + rcCmdMgr.addCommand(new CmdPartDesignGroove()); + rcCmdMgr.addCommand(new CmdPartDesignFillet()); + rcCmdMgr.addCommand(new CmdPartDesignDraft()); + rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); + rcCmdMgr.addCommand(new CmdPartDesignChamfer()); + rcCmdMgr.addCommand(new CmdPartDesignMirrored()); + rcCmdMgr.addCommand(new CmdPartDesignLinearPattern()); + rcCmdMgr.addCommand(new CmdPartDesignPolarPattern()); + //rcCmdMgr.addCommand(new CmdPartDesignScaled()); + rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); + } diff --git a/src/Mod/PartDesign/Gui/Command.cpp.orig b/src/Mod/PartDesign/Gui/Command.cpp.orig index d5e5fa667..f89af8a92 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp.orig +++ b/src/Mod/PartDesign/Gui/Command.cpp.orig @@ -1,3 +1,4 @@ +<<<<<<< ac24729340fa24c813f627f5e72fa487a8b4e5f9 /*************************************************************************** * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * * @@ -75,21 +76,22 @@ void validateSketches(std::vector& sketches, const bool su std::vector::iterator s = sketches.begin(); while (s != sketches.end()) { - // Check whether this sketch is already being used by another feature - std::vector ref = (*s)->getInList(); - std::vector::iterator r = ref.begin(); - while (r != ref.end()) { - if (!(*r)->getTypeId().isDerivedFrom(PartDesign::SketchBased().getClassTypeId())) { - r = ref.erase(r); - continue; - } - ++r; - } - if (!ref.empty()) { - // TODO: Display some information message that this sketch was removed? - s = sketches.erase(s); - continue; - } + // sketch is allways part of the body first. + //// Check whether this sketch is already being used by another feature + //std::vector ref = (*s)->getInList(); + //std::vector::iterator r = ref.begin(); + //while (r != ref.end()) { + // if (!(*r)->getTypeId().isDerivedFrom(PartDesign::SketchBased().getClassTypeId())) { + // r = ref.erase(r); + // continue; + // } + // ++r; + //} + //if (!ref.empty()) { + // // TODO: Display some information message that this sketch was removed? + // s = sketches.erase(s); + // continue; + //} // Check whether the sketch shape is valid Part::Part2DObject* sketch = static_cast(*s); @@ -548,62 +550,6 @@ CmdPartDesignGroove::CmdPartDesignGroove() void CmdPartDesignGroove::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid sketch from the user - // First check selections - std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Gui::validateSketches(sketches, true); - // Next let the user choose from a list of all eligible objects - if (sketches.size() == 0) { - sketches = getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); - Gui::validateSketches(sketches, true); - if (sketches.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), - QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid.")); - return; - } - } - // If there is more than one selection/possibility, show dialog and let user pick sketch - if (sketches.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } - - Part::Part2DObject* sketch = static_cast(sketches.front()); - App::DocumentObject* support = sketch->Support.getValue(); - std::string FeatName = getUniqueObjectName("Groove"); - - openCommand("Make Groove"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Groove\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcGroove && pcGroove->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - updateActive(); - if (isActiveObjectValid()) { - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",sketch->getNameInDocument()); - if (support) - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",support->getNameInDocument()); - } - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - if (support) { - copyVisual(FeatName.c_str(), "ShapeColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); - copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); - } -======= // // Get a valid sketch from the user // // First check selections // std::vector sketches = getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); @@ -614,7 +560,7 @@ void CmdPartDesignGroove::activated(int iMsg) // Gui::validateSketches(sketches, true); // if (sketches.size() == 0) { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), -// QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid")); +// QObject::tr("Please create a sketch or 2D object first. It must have a support face on a solid.")); // return; // } // } @@ -658,7 +604,6 @@ void CmdPartDesignGroove::activated(int iMsg) // copyVisual(FeatName.c_str(), "LineColor", support->getNameInDocument()); // copyVisual(FeatName.c_str(), "PointColor", support->getNameInDocument()); // } ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignGroove::isActive(void) @@ -700,107 +645,11 @@ void CmdPartDesignFillet::activated(int iMsg) } std::string SelString = selection[0].getAsPropertyLinkSubString(); Part::Feature *base = static_cast(selection[0].getObject()); -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - - const Part::TopoShape& TopShape = base->Shape.getShape(); - if (TopShape._Shape.IsNull()){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected part is empty.")); - return; - } - - TopTools_IndexedMapOfShape mapOfEdges; - TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); - - std::vector SubNames = std::vector(selection[0].getSubNames()); - - unsigned int i = 0; - - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { - TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); - const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); - - if(los.Extent() != 2) - { - SubNames.erase(SubNames.begin()+i); - continue; - } - - const TopoDS_Shape& face1 = los.First(); - const TopoDS_Shape& face2 = los.Last(); - GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), - TopoDS::Face(face1), - TopoDS::Face(face2)); - if (cont != GeomAbs_C0) { - SubNames.erase(SubNames.begin()+i); - continue; - } - - i++; - } - else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - - TopTools_IndexedMapOfShape mapOfFaces; - TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); - - for(int j = 1; j <= mapOfFaces.Extent(); ++j) { - TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); - - int id = mapOfEdges.FindIndex(edge); - - std::stringstream buf; - buf << "Edge"; - buf << id; - - if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) - { - SubNames.push_back(buf.str()); - } - - } - - SubNames.erase(SubNames.begin()+i); - } - // empty name or any other sub-element - else { - SubNames.erase(SubNames.begin()+i); - } - } - - if (SubNames.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No fillet possible on selected faces/edges.")); - return; - } - - std::string SelString; - SelString += "(App."; - SelString += "ActiveDocument";//getObject()->getDocument()->getName(); - SelString += "."; - SelString += selection[0].getFeatName(); - SelString += ",["; - for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ - SelString += "\""; - SelString += *it; - SelString += "\""; - if(it != --SubNames.end()) - SelString += ","; - } - SelString += "])"; - -======= // // const Part::TopoShape& TopShape = base->Shape.getShape(); // if (TopShape._Shape.IsNull()){ // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("Shape of selected part is empty")); + QObject::tr("Shape of selected part is empty.")); // return; // } // @@ -871,7 +720,7 @@ void CmdPartDesignFillet::activated(int iMsg) // // if (SubNames.size() == 0) { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("No fillet possible on selected faces/edges")); + QObject::tr("No fillet possible on selected faces/edges.")); // return; // } // @@ -890,7 +739,6 @@ void CmdPartDesignFillet::activated(int iMsg) // } // SelString += "])"; // ->>>>>>> switch PartDesign to Bodies std::string FeatName = getUniqueObjectName("Fillet"); openCommand("Make Fillet"); @@ -950,109 +798,12 @@ void CmdPartDesignChamfer::activated(int iMsg) std::string SelString = selection[0].getAsPropertyLinkSubString(); Part::Feature *base = static_cast(selection[0].getObject()); -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - - const Part::TopoShape& TopShape = base->Shape.getShape(); - - if (TopShape._Shape.IsNull()){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected part is empty.")); - return; - } - - TopTools_IndexedMapOfShape mapOfEdges; - TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); - - std::vector SubNames = std::vector(selection[0].getSubNames()); - - unsigned int i = 0; - - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { - TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); - const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); - - if(los.Extent() != 2) - { - SubNames.erase(SubNames.begin()+i); - continue; - } - - const TopoDS_Shape& face1 = los.First(); - const TopoDS_Shape& face2 = los.Last(); - GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), - TopoDS::Face(face1), - TopoDS::Face(face2)); - if (cont != GeomAbs_C0) { - SubNames.erase(SubNames.begin()+i); - continue; - } - - i++; - } - else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - - TopTools_IndexedMapOfShape mapOfFaces; - TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); - - for(int j = 1; j <= mapOfFaces.Extent(); ++j) { - TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); - - int id = mapOfEdges.FindIndex(edge); - - std::stringstream buf; - buf << "Edge"; - buf << id; - - if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) - { - SubNames.push_back(buf.str()); - } - - } - - SubNames.erase(SubNames.begin()+i); - } - // empty name or any other sub-element - else { - SubNames.erase(SubNames.begin()+i); - } - } - - if (SubNames.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No chamfer possible on selected faces/edges.")); - return; - } - - std::string SelString; - SelString += "(App."; - SelString += "ActiveDocument";//getObject()->getDocument()->getName(); - SelString += "."; - SelString += selection[0].getFeatName(); - SelString += ",["; - for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ - SelString += "\""; - SelString += *it; - SelString += "\""; - if(it != --SubNames.end()) - SelString += ","; - } - SelString += "])"; - -======= // // const Part::TopoShape& TopShape = base->Shape.getShape(); // // if (TopShape._Shape.IsNull()){ // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("Shape of selected part is empty")); + QObject::tr("Shape of selected part is empty.")); // return; // } // @@ -1123,7 +874,7 @@ void CmdPartDesignChamfer::activated(int iMsg) // // if (SubNames.size() == 0) { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("No chamfer possible on selected faces/edges")); +// QObject::tr("No chamfer possible on selected faces/edges.")); // return; // } // @@ -1142,7 +893,6 @@ void CmdPartDesignChamfer::activated(int iMsg) // } // SelString += "])"; // ->>>>>>> switch PartDesign to Bodies std::string FeatName = getUniqueObjectName("Chamfer"); openCommand("Make Chamfer"); @@ -1186,98 +936,6 @@ CmdPartDesignDraft::CmdPartDesignDraft() void CmdPartDesignDraft::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - std::vector selection = getSelection().getSelectionEx(); - - if (selection.size() < 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Select one or more faces.")); - return; - } - - if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), - QObject::tr("Draft works only on parts.")); - return; - } - - Part::Feature *base = static_cast(selection[0].getObject()); - - const Part::TopoShape& TopShape = base->Shape.getShape(); - if (TopShape._Shape.IsNull()){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected Part is empty.")); - return; - } - - std::vector SubNames = std::vector(selection[0].getSubNames()); - unsigned int i = 0; - - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - // Check for valid face types - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - BRepAdaptor_Surface sf(face); - if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone)) - SubNames.erase(SubNames.begin()+i); - } else { - // empty name or any other sub-element - SubNames.erase(SubNames.begin()+i); - } - - i++; - } - - if (SubNames.size() == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No draft possible on selected faces.")); - return; - } - - std::string SelString; - SelString += "(App."; - SelString += "ActiveDocument"; - SelString += "."; - SelString += selection[0].getFeatName(); - SelString += ",["; - for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ - SelString += "\""; - SelString += *it; - SelString += "\""; - if(it != --SubNames.end()) - SelString += ","; - } - SelString += "])"; - - std::string FeatName = getUniqueObjectName("Draft"); - - // We don't create any defaults for neutral plane and pull direction, but Draft::execute() - // will choose them. - // Note: When the body feature is there, the best thing would be to get pull direction and - // neutral plane from the preceding feature in the tree. Or even store them as default in - // the Body feature itself - openCommand("Make Draft"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Draft\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); - doCommand(Doc,"App.activeDocument().%s.Angle = %f",FeatName.c_str(), 1.5); - updateActive(); - if (isActiveObjectValid()) { - doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); - } - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - App::DocumentObjectGroup* grp = base->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - } - - copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); - copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); -======= // std::vector selection = getSelection().getSelectionEx(); // // if (selection.size() < 1) { @@ -1288,7 +946,7 @@ void CmdPartDesignDraft::activated(int iMsg) // // if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), -// QObject::tr("Draft works only on parts")); +// QObject::tr("Draft works only on parts.")); // return; // } // @@ -1297,7 +955,7 @@ void CmdPartDesignDraft::activated(int iMsg) // const Part::TopoShape& TopShape = base->Shape.getShape(); // if (TopShape._Shape.IsNull()){ // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("Shape of selected Part is empty")); +// QObject::tr("Shape of selected Part is empty.")); // return; // } // @@ -1324,7 +982,7 @@ void CmdPartDesignDraft::activated(int iMsg) // // if (SubNames.size() == 0) { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), -// QObject::tr("No draft possible on selected faces")); +// QObject::tr("No draft possible on selected faces.")); // return; // } // @@ -1368,7 +1026,6 @@ void CmdPartDesignDraft::activated(int iMsg) // copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); // copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); // copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignDraft::isActive(void) @@ -1395,58 +1052,6 @@ CmdPartDesignMirrored::CmdPartDesignMirrored() void CmdPartDesignMirrored::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid original from the user - // First check selections - std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(features); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - - std::string FeatName = getUniqueObjectName("Mirrored"); - - std::stringstream str; - std::vector tempSelNames; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - tempSelNames.push_back((*it)->getNameInDocument()); - } - str << "]"; - - openCommand("Mirrored"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",FeatName.c_str()); - // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like - // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' - updateActive(); // Helps to ensure that the object already exists when the next command comes up - doCommand(Doc,str.str().c_str()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) - doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); - copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -======= // // Get a valid original from the user // // First check selections // std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); @@ -1464,7 +1069,7 @@ void CmdPartDesignMirrored::activated(int iMsg) // return; // Cancelled or nothing selected // } else { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first")); +// QObject::tr("Please create a subtractive or additive feature first.")); // return; // } // } @@ -1497,7 +1102,6 @@ void CmdPartDesignMirrored::activated(int iMsg) // // copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); // copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignMirrored::isActive(void) @@ -1524,65 +1128,6 @@ CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() void CmdPartDesignLinearPattern::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid original from the user - // First check selections - std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(features); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - - std::string FeatName = getUniqueObjectName("LinearPattern"); - - std::stringstream str; - std::vector tempSelNames; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - tempSelNames.push_back((*it)->getNameInDocument()); - } - str << "]"; - - openCommand("LinearPattern"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str()); - updateActive(); - doCommand(Doc,str.str().c_str()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) - doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - - copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); - copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -======= // // Get a valid original from the user // // First check selections // std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); @@ -1600,7 +1145,7 @@ void CmdPartDesignLinearPattern::activated(int iMsg) // return; // Cancelled or nothing selected // } else { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please")); +// QObject::tr("Please create a subtractive or additive feature first, please.")); // return; // } // } @@ -1640,7 +1185,6 @@ void CmdPartDesignLinearPattern::activated(int iMsg) // // copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); // copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignLinearPattern::isActive(void) @@ -1667,65 +1211,6 @@ CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() void CmdPartDesignPolarPattern::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid original from the user - // First check selections - std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(features); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - - std::string FeatName = getUniqueObjectName("PolarPattern"); - - std::stringstream str; - std::vector tempSelNames; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - tempSelNames.push_back((*it)->getNameInDocument()); - } - str << "]"; - - openCommand("PolarPattern"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str()); - updateActive(); - doCommand(Doc,str.str().c_str()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) - doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - App::DocumentObjectGroup* grp = sketch->getGroup(); - if (grp) { - doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" - ,grp->getNameInDocument(),sketch->getNameInDocument()); - } - - copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); - copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -======= // // Get a valid original from the user // // First check selections // std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); @@ -1743,7 +1228,7 @@ void CmdPartDesignPolarPattern::activated(int iMsg) // return; // Cancelled or nothing selected // } else { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please")); +// QObject::tr("Please create a subtractive or additive feature first, please.")); // return; // } // } @@ -1783,7 +1268,6 @@ void CmdPartDesignPolarPattern::activated(int iMsg) // // copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); // copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignPolarPattern::isActive(void) @@ -1810,54 +1294,6 @@ CmdPartDesignScaled::CmdPartDesignScaled() void CmdPartDesignScaled::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid original from the user - // First check selections - std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(features); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - - std::string FeatName = getUniqueObjectName("Scaled"); - - std::stringstream str; - std::vector tempSelNames; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - tempSelNames.push_back((*it)->getNameInDocument()); - } - str << "]"; - - openCommand("Scaled"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",FeatName.c_str()); - updateActive(); - doCommand(Doc,str.str().c_str()); - doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) - doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); - copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -======= // // Get a valid original from the user // // First check selections // std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); @@ -1875,7 +1311,7 @@ void CmdPartDesignScaled::activated(int iMsg) // return; // Cancelled or nothing selected // } else { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please")); +// QObject::tr("Please create a subtractive or additive feature first, please.")); // return; // } // } @@ -1904,7 +1340,6 @@ void CmdPartDesignScaled::activated(int iMsg) // // copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); // copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignScaled::isActive(void) @@ -1931,50 +1366,6 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() void CmdPartDesignMultiTransform::activated(int iMsg) { -<<<<<<< 692dcf6d1e4f4c50cdecebc0c5c53e05014f57e0 - // Get a valid original from the user - // First check selections - std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // Next create a list of all eligible objects - if (features.size() == 0) { - features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); - // If there is more than one selected or eligible object, show dialog and let user pick one - if (features.size() > 1) { - PartDesignGui::FeaturePickDialog Dlg(features); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - } else { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), - QObject::tr("Please create a subtractive or additive feature first.")); - return; - } - } - - std::string FeatName = getUniqueObjectName("MultiTransform"); - - std::stringstream str; - std::vector tempSelNames; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - tempSelNames.push_back((*it)->getNameInDocument()); - } - str << "]"; - - openCommand("MultiTransform"); - doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")",FeatName.c_str()); - updateActive(); - doCommand(Doc,str.str().c_str()); - - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); - - copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); - copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); -======= // // Get a valid original from the user // // First check selections // std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); @@ -1992,7 +1383,7 @@ void CmdPartDesignMultiTransform::activated(int iMsg) // return; // Cancelled or nothing selected // } else { // QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), -// QObject::tr("Please create a subtractive or additive feature first, please")); +// QObject::tr("Please create a subtractive or additive feature first, please.")); // return; // } // } @@ -2017,7 +1408,6 @@ void CmdPartDesignMultiTransform::activated(int iMsg) // // copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); // copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); ->>>>>>> switch PartDesign to Bodies } bool CmdPartDesignMultiTransform::isActive(void) @@ -2048,3 +1438,1326 @@ void CreatePartDesignCommands(void) // //rcCmdMgr.addCommand(new CmdPartDesignScaled()); // rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); } +======= +/*************************************************************************** + * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * + * * + * 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" +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "FeaturePickDialog.h" + +using namespace std; + +extern PartDesign::Body *ActivePartObject; + + +//=========================================================================== +// Helper for Body +//=========================================================================== + +PartDesign::Body *getBody(void) +{ + if(!ActivePartObject){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"), + QObject::tr("In order to use PartDesign you need an active Body object in the document. " + "Please make one active or create one. If you have a legacy document " + "with PartDesign objects without Body, use the transfer function in " + "PartDesign to put them into a Body." + )); + } + return ActivePartObject; + +} + + +//=========================================================================== +// PartDesign_Sketch +//=========================================================================== + +/* Sketch commands =======================================================*/ +DEF_STD_CMD_A(CmdPartDesignNewSketch); + +CmdPartDesignNewSketch::CmdPartDesignNewSketch() + :Command("PartDesign_NewSketch") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Create sketch"); + sToolTipText = QT_TR_NOOP("Create a new sketch"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_NewSketch"; +} + + +void CmdPartDesignNewSketch::activated(int iMsg) +{ + PartDesign::Body *pcActiveBody = getBody(); + + // No PartDesign feature without Body past FreeCAD 0.13 + if(!pcActiveBody) return; + + Gui::SelectionFilter SketchFilter("SELECT Sketcher::SketchObject COUNT 1"); + Gui::SelectionFilter FaceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1"); + + if (SketchFilter.match()) { + Sketcher::SketchObject *Sketch = static_cast(SketchFilter.Result[0][0].getObject()); + openCommand("Edit Sketch"); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",Sketch->getNameInDocument()); + } + else if (FaceFilter.match()) { + // get the selected object + Part::Feature *part = static_cast(FaceFilter.Result[0][0].getObject()); + Base::Placement ObjectPos = part->Placement.getValue(); + const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); + if (sub.size() > 1){ + // No assert for wrong user input! + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Several sub-elements selected"), + QObject::tr("You have to select a single face as support for a sketch!")); + return; + } + // get the selected sub shape (a Face) + const Part::TopoShape &shape = part->Shape.getValue(); + TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); + const TopoDS_Face& face = TopoDS::Face(sh); + if (face.IsNull()){ + // No assert for wrong user input! + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No support face selected"), + QObject::tr("You have to select a face as support for a sketch!")); + return; + } + + BRepAdaptor_Surface adapt(face); + if (adapt.GetType() != GeomAbs_Plane){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No planar support"), + QObject::tr("You need a planar face as support for a sketch!")); + return; + } + + std::string supportString = FaceFilter.Result[0][0].getAsPropertyLinkSubString(); + + // create Sketch on Face + std::string FeatName = getUniqueObjectName("Sketch"); + + openCommand("Create a Sketch on Face"); + doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Gui,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); + doCommand(Gui,"App.activeDocument().recompute()"); // recompute the sketch placement based on its support + //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + else { + // ask user for orientation + SketcherGui::SketchOrientationDialog Dlg; + + if (Dlg.exec() != QDialog::Accepted) + return; // canceled + Base::Vector3d p = Dlg.Pos.getPosition(); + Base::Rotation r = Dlg.Pos.getRotation(); + + // do the right view direction + std::string camstring; + switch(Dlg.DirType){ + case 0: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 87 \\n orientation 0 0 1 0 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; + break; + case 1: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA \\n position 0 0 -87 \\n orientation -1 0 0 3.1415927 \\n nearDistance -112.88701 \\n farDistance 287.28702 \\n aspectRatio 1 \\n focalDistance 87 \\n height 143.52005 }"; + break; + case 2: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 -87 0 \\n orientation -1 0 0 4.712389\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 3: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 0 87 0 \\n orientation 0 0.70710683 0.70710683 3.1415927\\n nearDistance -112.88701\\n farDistance 287.28702\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 4: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position 87 0 0 \\n orientation 0.57735026 0.57735026 0.57735026 2.0943952 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + case 5: + camstring = "#Inventor V2.1 ascii \\n OrthographicCamera {\\n viewportMapping ADJUST_CAMERA\\n position -87 0 0 \\n orientation -0.57735026 0.57735026 0.57735026 4.1887903 \\n nearDistance -112.887\\n farDistance 287.28699\\n aspectRatio 1\\n focalDistance 87\\n height 143.52005\\n\\n}"; + break; + } + std::string FeatName = getUniqueObjectName("Sketch"); + + openCommand("Create a new Sketch"); + doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))",FeatName.c_str(),p.x,p.y,p.z,r[0],r[1],r[2],r[3]); + doCommand(Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",camstring.c_str()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + +} + +bool CmdPartDesignNewSketch::isActive(void) +{ + if (getActiveGuiDocument()) + return true; + else + return false; +} + +//=========================================================================== +// Common utility functions for SketchBased features +//=========================================================================== + +// Take a list of Part2DObjects and erase those which are not eligible for creating a +// SketchBased feature. If supportRequired is true, also erase those that cannot be used to define +// a Subtractive feature +void validateSketches(std::vector& sketches, const bool supportRequired) +{ + std::vector::iterator s = sketches.begin(); + + while (s != sketches.end()) { + // sketch is always part of the body first. + //// Check whether this sketch is already being used by another feature + //std::vector ref = (*s)->getInList(); + //std::vector::iterator r = ref.begin(); + //while (r != ref.end()) { + // if (!(*r)->getTypeId().isDerivedFrom(PartDesign::SketchBased().getClassTypeId())) { + // r = ref.erase(r); + // continue; + // } + // ++r; + //} + //if (!ref.empty()) { + // // TODO: Display some information message that this sketch was removed? + // s = sketches.erase(s); + // continue; + //} + + // Check whether the sketch shape is valid + Part::Part2DObject* sketch = static_cast(*s); + const TopoDS_Shape& shape = sketch->Shape.getValue(); + if (shape.IsNull()) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // count free wires + int ctWires=0; + TopExp_Explorer ex; + for (ex.Init(shape, TopAbs_WIRE); ex.More(); ex.Next()) { + ctWires++; + } + if (ctWires == 0) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + + // Check for support + if (supportRequired) { + App::DocumentObject* support = sketch->Support.getValue(); + if (support == NULL) { + s = sketches.erase(s); + continue; + // TODO: Display some information message that this sketch was removed? + } + } + + // All checks passed - go on to next candidate + s++; + } +} + +void prepareSketchBased(Gui::Command* cmd, const std::string& which, + Part::Part2DObject*& sketch, std::string& FeatName) +{ + PartDesign::Body *pcActiveBody = getBody(); + if (!pcActiveBody) return; + + bool bNoSketchWasSelected = false; + // Get a valid sketch from the user + // First check selections + std::vector sketches = cmd->getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); + validateSketches(sketches, false); + // Next let the user choose from a list of all eligible objects + if (sketches.size() == 0) { + sketches = cmd->getDocument()->getObjectsOfType(Part::Part2DObject::getClassTypeId()); + bNoSketchWasSelected = true; + } + if (sketches.size() == 0) { + if (bNoSketchWasSelected) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches in this document"), + QObject::tr("Please create a sketch or 2D object first")); + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid sketches selected"), + QObject::tr("None of selected sketches/2D objects is valid for padding. Please select a valid sketch or 2D object that is not used by any other feature.")); + } + return; + } + + // If there is more than one selection/possibility, show dialog and let user pick sketch + if (sketches.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(sketches); + if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } + + sketch = static_cast(sketches.front()); + FeatName = cmd->getUniqueObjectName(which.c_str()); + + cmd->openCommand((std::string("Make ") + which).c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Model = App.activeDocument().%s.Model + [App.activeDocument().%s]",pcActiveBody->getNameInDocument(),pcActiveBody->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",pcActiveBody->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument()); +} + +void finishSketchBased(const Gui::Command* cmd, const Part::Part2DObject* sketch, const std::string& FeatName) +{ + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + cmd->doCommand(cmd->Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + cmd->updateActive(); + if (cmd->isActiveObjectValid()) { + cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", sketch->getNameInDocument()); + } + // #0001721: use '0' as edit value to avoid switching off selection in + // ViewProviderGeometryObject::setEditViewer + cmd->doCommand(cmd->Gui,"Gui.activeDocument().setEdit('%s', 0)", FeatName.c_str()); + + /* + PartDesign::Body *pcActiveBody = getBody(); + if (pcActiveBody) { + cmd->copyVisual(FeatName.c_str(), "ShapeColor", pcActiveBody->getNameInDocument()); + cmd->copyVisual(FeatName.c_str(), "LineColor", pcActiveBody->getNameInDocument()); + cmd->copyVisual(FeatName.c_str(), "PointColor", pcActiveBody->getNameInDocument()); + }*/ +} + +//=========================================================================== +// PartDesign_Pad +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPad); + +CmdPartDesignPad::CmdPartDesignPad() + : Command("PartDesign_Pad") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Pad"); + sToolTipText = QT_TR_NOOP("Pad a selected sketch"); + sWhatsThis = "PartDesign_Pad"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Pad"; +} + +void CmdPartDesignPad::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Pad", sketch, FeatName); + + // specific parameters for Pad + doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignPad::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Pocket +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPocket); + +CmdPartDesignPocket::CmdPartDesignPocket() + : Command("PartDesign_Pocket") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Pocket"); + sToolTipText = QT_TR_NOOP("create a pocket with the selected sketch"); + sWhatsThis = "PartDesign_Pocket"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Pocket"; +} + +void CmdPartDesignPocket::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Pocket", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignPocket::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Revolution +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignRevolution); + +CmdPartDesignRevolution::CmdPartDesignRevolution() + : Command("PartDesign_Revolution") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Revolution"); + sToolTipText = QT_TR_NOOP("Revolve a selected sketch"); + sWhatsThis = "PartDesign_Revolution"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Revolution"; +} + +void CmdPartDesignRevolution::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Revolution", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Revolution* pcRevolution = static_cast(getDocument()->getObject(FeatName.c_str())); + if (pcRevolution && pcRevolution->suggestReversed()) + doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignRevolution::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Groove +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignGroove); + +CmdPartDesignGroove::CmdPartDesignGroove() + : Command("PartDesign_Groove") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Groove"); + sToolTipText = QT_TR_NOOP("Groove a selected sketch"); + sWhatsThis = "PartDesign_Groove"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Groove"; +} + +void CmdPartDesignGroove::activated(int iMsg) +{ + Part::Part2DObject* sketch; + std::string FeatName; + prepareSketchBased(this, "Groove", sketch, FeatName); + + doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); + if (pcGroove && pcGroove->suggestReversed()) + doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(this, sketch, FeatName); + adjustCameraPosition(); +} + +bool CmdPartDesignGroove::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Fillet +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignFillet); + +CmdPartDesignFillet::CmdPartDesignFillet() + :Command("PartDesign_Fillet") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Fillet"); + sToolTipText = QT_TR_NOOP("Make a fillet on an edge, face or body"); + sWhatsThis = "PartDesign_Fillet"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Fillet"; +} + +void CmdPartDesignFillet::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Fillet works only on parts")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected part is empty")); + return; + } + + TopTools_IndexedMapOfShape mapOfEdges; + TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; + TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); + + std::vector SubNames = std::vector(selection[0].getSubNames()); + + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { + TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); + const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); + + if(los.Extent() != 2) + { + SubNames.erase(SubNames.begin()+i); + continue; + } + + const TopoDS_Shape& face1 = los.First(); + const TopoDS_Shape& face2 = los.Last(); + GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), + TopoDS::Face(face1), + TopoDS::Face(face2)); + if (cont != GeomAbs_C0) { + SubNames.erase(SubNames.begin()+i); + continue; + } + + i++; + } + else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + + TopTools_IndexedMapOfShape mapOfFaces; + TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); + + for(int j = 1; j <= mapOfFaces.Extent(); ++j) { + TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); + + int id = mapOfEdges.FindIndex(edge); + + std::stringstream buf; + buf << "Edge"; + buf << id; + + if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) + { + SubNames.push_back(buf.str()); + } + + } + + SubNames.erase(SubNames.begin()+i); + } + // empty name or any other sub-element + else { + SubNames.erase(SubNames.begin()+i); + } + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No fillet possible on selected faces/edges")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument";//getObject()->getDocument()->getName(); + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Fillet"); + + openCommand("Make Fillet"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Fillet\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignFillet::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Chamfer +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignChamfer); + +CmdPartDesignChamfer::CmdPartDesignChamfer() + :Command("PartDesign_Chamfer") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Chamfer"); + sToolTipText = QT_TR_NOOP("Chamfer the selected edges of a shape"); + sWhatsThis = "PartDesign_Chamfer"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Chamfer"; +} + +void CmdPartDesignChamfer::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select an edge, face or body. Only one body is allowed.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Chamfer works only on parts")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected part is empty")); + return; + } + + TopTools_IndexedMapOfShape mapOfEdges; + TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; + TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); + + std::vector SubNames = std::vector(selection[0].getSubNames()); + + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { + TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); + const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); + + if(los.Extent() != 2) + { + SubNames.erase(SubNames.begin()+i); + continue; + } + + const TopoDS_Shape& face1 = los.First(); + const TopoDS_Shape& face2 = los.Last(); + GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), + TopoDS::Face(face1), + TopoDS::Face(face2)); + if (cont != GeomAbs_C0) { + SubNames.erase(SubNames.begin()+i); + continue; + } + + i++; + } + else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + + TopTools_IndexedMapOfShape mapOfFaces; + TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); + + for(int j = 1; j <= mapOfFaces.Extent(); ++j) { + TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); + + int id = mapOfEdges.FindIndex(edge); + + std::stringstream buf; + buf << "Edge"; + buf << id; + + if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) + { + SubNames.push_back(buf.str()); + } + + } + + SubNames.erase(SubNames.begin()+i); + } + // empty name or any other sub-element + else { + SubNames.erase(SubNames.begin()+i); + } + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No chamfer possible on selected faces/edges")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument";//getObject()->getDocument()->getName(); + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Chamfer"); + + openCommand("Make Chamfer"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Chamfer\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignChamfer::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Draft +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignDraft); + +CmdPartDesignDraft::CmdPartDesignDraft() + :Command("PartDesign_Draft") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Draft"); + sToolTipText = QT_TR_NOOP("Make a draft on a face"); + sWhatsThis = "PartDesign_Draft"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Draft"; +} + +void CmdPartDesignDraft::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(); + + if (selection.size() < 1) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select one or more faces.")); + return; + } + + if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), + QObject::tr("Draft works only on parts")); + return; + } + + Part::Feature *base = static_cast(selection[0].getObject()); + + const Part::TopoShape& TopShape = base->Shape.getShape(); + if (TopShape._Shape.IsNull()){ + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Shape of selected Part is empty")); + return; + } + + std::vector SubNames = std::vector(selection[0].getSubNames()); + unsigned int i = 0; + + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + // Check for valid face types + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + BRepAdaptor_Surface sf(face); + if ((sf.GetType() != GeomAbs_Plane) && (sf.GetType() != GeomAbs_Cylinder) && (sf.GetType() != GeomAbs_Cone)) + SubNames.erase(SubNames.begin()+i); + } else { + // empty name or any other sub-element + SubNames.erase(SubNames.begin()+i); + } + + i++; + } + + if (SubNames.size() == 0) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("No draft possible on selected faces")); + return; + } + + std::string SelString; + SelString += "(App."; + SelString += "ActiveDocument"; + SelString += "."; + SelString += selection[0].getFeatName(); + SelString += ",["; + for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + SelString += "\""; + SelString += *it; + SelString += "\""; + if(it != --SubNames.end()) + SelString += ","; + } + SelString += "])"; + + std::string FeatName = getUniqueObjectName("Draft"); + + // We don't create any defaults for neutral plane and pull direction, but Draft::execute() + // will choose them. + // Note: When the body feature is there, the best thing would be to get pull direction and + // neutral plane from the preceding feature in the tree. Or even store them as default in + // the Body feature itself + openCommand("Make Draft"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Draft\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Base = %s",FeatName.c_str(),SelString.c_str()); + doCommand(Doc,"App.activeDocument().%s.Angle = %f",FeatName.c_str(), 1.5); + updateActive(); + if (isActiveObjectValid()) { + doCommand(Gui,"Gui.activeDocument().hide(\"%s\")",selection[0].getFeatName()); + } + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = base->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "LineColor", selection[0].getFeatName()); + copyVisual(FeatName.c_str(), "PointColor", selection[0].getFeatName()); +} + +bool CmdPartDesignDraft::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Mirrored +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignMirrored); + +CmdPartDesignMirrored::CmdPartDesignMirrored() + : Command("PartDesign_Mirrored") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Mirrored"); + sToolTipText = QT_TR_NOOP("create a mirrored feature"); + sWhatsThis = "PartDesign_Mirrored"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Mirrored"; +} + +void CmdPartDesignMirrored::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first")); + return; + } + } + + std::string FeatName = getUniqueObjectName("Mirrored"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("Mirrored"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",FeatName.c_str()); + // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like + // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' + updateActive(); // Helps to ensure that the object already exists when the next command comes up + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignMirrored::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_LinearPattern +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignLinearPattern); + +CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() + : Command("PartDesign_LinearPattern") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("LinearPattern"); + sToolTipText = QT_TR_NOOP("create a linear pattern feature"); + sWhatsThis = "PartDesign_LinearPattern"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_LinearPattern"; +} + +void CmdPartDesignLinearPattern::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please")); + return; + } + } + + std::string FeatName = getUniqueObjectName("LinearPattern"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("LinearPattern"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignLinearPattern::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_PolarPattern +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignPolarPattern); + +CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() + : Command("PartDesign_PolarPattern") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("PolarPattern"); + sToolTipText = QT_TR_NOOP("create a polar pattern feature"); + sWhatsThis = "PartDesign_PolarPattern"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_PolarPattern"; +} + +void CmdPartDesignPolarPattern::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please")); + return; + } + } + + std::string FeatName = getUniqueObjectName("PolarPattern"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("PolarPattern"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignPolarPattern::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_Scaled +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignScaled); + +CmdPartDesignScaled::CmdPartDesignScaled() + : Command("PartDesign_Scaled") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("Scaled"); + sToolTipText = QT_TR_NOOP("create a scaled feature"); + sWhatsThis = "PartDesign_Scaled"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_Scaled"; +} + +void CmdPartDesignScaled::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please")); + return; + } + } + + std::string FeatName = getUniqueObjectName("Scaled"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("Scaled"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + for (std::vector::iterator it = tempSelNames.begin(); it != tempSelNames.end(); ++it) + doCommand(Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignScaled::isActive(void) +{ + return hasActiveDocument(); +} + +//=========================================================================== +// PartDesign_MultiTransform +//=========================================================================== +DEF_STD_CMD_A(CmdPartDesignMultiTransform); + +CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() + : Command("PartDesign_MultiTransform") +{ + sAppModule = "PartDesign"; + sGroup = QT_TR_NOOP("PartDesign"); + sMenuText = QT_TR_NOOP("MultiTransform"); + sToolTipText = QT_TR_NOOP("create a multitransform feature"); + sWhatsThis = "PartDesign_MultiTransform"; + sStatusTip = sToolTipText; + sPixmap = "PartDesign_MultiTransform"; +} + +void CmdPartDesignMultiTransform::activated(int iMsg) +{ + // Get a valid original from the user + // First check selections + std::vector features = getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); + std::vector subtractive = getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // Next create a list of all eligible objects + if (features.size() == 0) { + features = getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); + subtractive = getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); + features.insert(features.end(), subtractive.begin(), subtractive.end()); + // If there is more than one selected or eligible object, show dialog and let user pick one + if (features.size() > 1) { + PartDesignGui::FeaturePickDialog Dlg(features); + if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) + return; // Cancelled or nothing selected + } else { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), + QObject::tr("Please create a subtractive or additive feature first, please")); + return; + } + } + + std::string FeatName = getUniqueObjectName("MultiTransform"); + + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + tempSelNames.push_back((*it)->getNameInDocument()); + } + str << "]"; + + openCommand("MultiTransform"); + doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")",FeatName.c_str()); + updateActive(); + doCommand(Doc,str.str().c_str()); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + + copyVisual(FeatName.c_str(), "ShapeColor", tempSelNames.front().c_str()); + copyVisual(FeatName.c_str(), "DisplayMode", tempSelNames.front().c_str()); +} + +bool CmdPartDesignMultiTransform::isActive(void) +{ + return hasActiveDocument(); +} + + +//=========================================================================== +// Initialization +//=========================================================================== + +void CreatePartDesignCommands(void) +{ + Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); + + rcCmdMgr.addCommand(new CmdPartDesignPad()); + rcCmdMgr.addCommand(new CmdPartDesignPocket()); + rcCmdMgr.addCommand(new CmdPartDesignRevolution()); + rcCmdMgr.addCommand(new CmdPartDesignGroove()); + rcCmdMgr.addCommand(new CmdPartDesignFillet()); + rcCmdMgr.addCommand(new CmdPartDesignDraft()); + rcCmdMgr.addCommand(new CmdPartDesignNewSketch()); + rcCmdMgr.addCommand(new CmdPartDesignChamfer()); + rcCmdMgr.addCommand(new CmdPartDesignMirrored()); + rcCmdMgr.addCommand(new CmdPartDesignLinearPattern()); + rcCmdMgr.addCommand(new CmdPartDesignPolarPattern()); + //rcCmdMgr.addCommand(new CmdPartDesignScaled()); + rcCmdMgr.addCommand(new CmdPartDesignMultiTransform()); + } +>>>>>>> Integrated PartDesign::Pad into Body feature workflow diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 1374d2639..8942fe356 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -33,6 +33,8 @@ #include #include +#include "Base/Console.h" + using namespace PartDesignGui; PROPERTY_SOURCE(PartDesignGui::ViewProviderBody,PartGui::ViewProviderPart) @@ -109,7 +111,9 @@ std::vector ViewProviderBody::claimChildren(void)const for(std::vector::const_iterator it = Model.begin();it!=Model.end();++it){ // sketches of SketchBased features get claimed under the feature so has to be removed from the Body if ((*it)->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())){ - OutSet.insert(static_cast(*it)->Sketch.getValue()); + App::DocumentObject* sketch = static_cast(*it)->Sketch.getValue(); + if (sketch != NULL) + OutSet.insert(sketch); } } @@ -118,6 +122,9 @@ std::vector ViewProviderBody::claimChildren(void)const sort (Model.begin(), Model.end()); std::vector::iterator it = set_difference (Model.begin(), Model.end(), OutSet.begin(),OutSet.end(), Result.begin()); + //Base::Console().Error("Body claimed children:\n"); + //for (std::vector::const_iterator o = Result.begin(); o != it; o++) + // Base::Console().Error("%s\n", (*o)->getNameInDocument()); // return the rest as claim set of the Body return std::vector(Result.begin(),it); } @@ -125,7 +132,10 @@ std::vector ViewProviderBody::claimChildren(void)const std::vector ViewProviderBody::claimChildren3D(void)const { - + std::vector children = static_cast(getObject())->Model.getValues(); + //Base::Console().Error("Body 3D claimed children:\n"); + //for (std::vector::const_iterator o = children.begin(); o != children.end(); o++) + // Base::Console().Error("%s\n", (*o)->getNameInDocument()); return static_cast(getObject())->Model.getValues(); }