diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp b/src/Mod/PartDesign/App/AppPartDesign.cpp index 71dc825fe..cb3a4331f 100644 --- a/src/Mod/PartDesign/App/AppPartDesign.cpp +++ b/src/Mod/PartDesign/App/AppPartDesign.cpp @@ -28,7 +28,7 @@ #include #include - + #include "FeaturePad.h" #include "FeatureSolid.h" #include "FeaturePocket.h" @@ -56,6 +56,7 @@ #include "FeatureThickness.h" #include "FeaturePipe.h" #include "FeatureLoft.h" +#include "ShapeBinder.h" namespace PartDesign { extern PyObject* initModule(); @@ -81,7 +82,7 @@ PyMODINIT_FUNC init_PartDesign() // NOTE: To finish the initialization of our own type objects we must // call PyType_Ready, otherwise we run into a segmentation fault, later on. // This function is responsible for adding inherited slots from a type's base class. - + PartDesign::Feature ::init(); PartDesign::Solid ::init(); PartDesign::DressUp ::init(); @@ -109,6 +110,8 @@ PyMODINIT_FUNC init_PartDesign() PartDesign::Loft ::init(); PartDesign::AdditiveLoft ::init(); PartDesign::SubtractiveLoft ::init(); + PartDesign::ShapeBinder ::init(); + PartDesign::ShapeBinder2D ::init(); PartDesign::Plane ::init(); PartDesign::Line ::init(); PartDesign::Point ::init(); @@ -139,5 +142,4 @@ PyMODINIT_FUNC init_PartDesign() PartDesign::Wedge ::init(); PartDesign::AdditiveWedge ::init(); PartDesign::SubtractiveWedge ::init(); - } diff --git a/src/Mod/PartDesign/App/CMakeLists.txt b/src/Mod/PartDesign/App/CMakeLists.txt index cc5dd7f66..3bdc2152c 100644 --- a/src/Mod/PartDesign/App/CMakeLists.txt +++ b/src/Mod/PartDesign/App/CMakeLists.txt @@ -40,6 +40,8 @@ SET(Features_SRCS SOURCE_GROUP("Features" FILES ${Features_SRCS}) SET(DatumFeatures_SRCS + ShapeBinder.h + ShapeBinder.cpp DatumPlane.cpp DatumPlane.h DatumLine.cpp diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp new file mode 100644 index 000000000..fd9fd8144 --- /dev/null +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +#endif + +#include "ShapeBinder.h" +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +using namespace PartDesign; + +// ============================================================================ + +PROPERTY_SOURCE(PartDesign::ShapeBinder, Part::Feature) + +ShapeBinder::ShapeBinder() +{ + ADD_PROPERTY_TYPE(Support, (0,0), "",(App::PropertyType)(App::Prop_None),"Support of the geometry"); +} + +ShapeBinder::~ShapeBinder() +{ +} + +// TODO Move this to mustExecute/execute (2015-09-11, Fat-Zer) +void ShapeBinder::onChanged(const App::Property *prop) +{ + + if(! this->isRestoring()){ + + if(prop == &Support) { + + auto objs = Support.getValues(); + auto subs = Support.getSubValues(); + + Shape.setValue(buildShapeFromReferences(objs, subs)._Shape); + } + + } + Part::Feature::onChanged(prop); +} + +TopoShape ShapeBinder::buildShapeFromReferences(std::vector< App::DocumentObject* > objs, std::vector< std::string > subs) { + + if(objs.empty()) { + //kee the shape as it is, maybe we are just used as a copy + return TopoShape(); + } + + //we only allow part feature, so get the first one we find + Part::Feature* obj = nullptr; + int index = 0; + while(!objs[index]->isDerivedFrom(Part::Feature::getClassTypeId()) && index < objs.size()) + index++; + + //do we have any part feature? + if(index >= objs.size()) + return TopoShape(); + + obj = static_cast(objs[index]); + + //if we have no subshpape we use the whole shape + if(subs[index].empty()) { + return obj->Shape.getShape(); + } + + //if we use multiple subshapes we build a shape from them by fusing them together + index = 0; + TopoShape base; + std::vector operators; + for(std::string sub : subs) { + + //we only allow subshapes from a single Part::Feature + if(objs[index] != obj) + continue; + + //in this mode the full shape is allowed, as we already started the subshape + //prcessing + if(sub.empty()) + continue; + + if(base.isNull()) + base = obj->Shape.getShape(); + else + operators.push_back(obj->Shape.getShape().getSubShape(sub.c_str())); + } + + base.multiFuse(operators); + return base; +} + + +PROPERTY_SOURCE(PartDesign::ShapeBinder2D, Part::Part2DObject) + +ShapeBinder2D::ShapeBinder2D() { + +} + +ShapeBinder2D::~ShapeBinder2D() { + +} + +void ShapeBinder2D::onChanged(const App::Property* prop) { + + if(! this->isRestoring()){ + + if(prop == &Support) { + + auto objs = Support.getValues(); + auto subs = Support.getSubValues(); + + Shape.setValue(ShapeBinder::buildShapeFromReferences(objs, subs)._Shape); + } + + } + Part::Feature::onChanged(prop); +} diff --git a/src/Mod/PartDesign/App/ShapeBinder.h b/src/Mod/PartDesign/App/ShapeBinder.h new file mode 100644 index 000000000..0edcb9963 --- /dev/null +++ b/src/Mod/PartDesign/App/ShapeBinder.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef PARTDESIGN_DATUMSHAPE_H +#define PARTDESIGN_DATUMSHAPE_H + +#include +#include +#include +#include + +namespace PartDesign +{ + +/*Those two feature are not realy a classical datum. They are fully defined shapes and not + *infinit geometries likeplanes and lines. Also they are not calculated by references and hence + *are not "attaced" to anything. Furthermore real shapes must be visualized. This makes it hard + *to reuse the existing datum infrastructure and a special handling foor those two types is + *created. + */ +// TODO Add a better documentation (2015-09-11, Fat-Zer) + +class PartDesignExport ShapeBinder : public Part::Feature +{ + PROPERTY_HEADER(PartDesign::ShapeBinder); + +public: + ShapeBinder(); + virtual ~ShapeBinder(); + + App::PropertyLinkSubList Support; + + static TopoShape buildShapeFromReferences(std::vector objects, std::vector subobjects); + + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderShapeBinder"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +//this class is needed as long as sketch-based features can only work with Part2DObjects +class PartDesignExport ShapeBinder2D : public Part::Part2DObject +{ + PROPERTY_HEADER(PartDesign::ShapeBinder2D); + +public: + ShapeBinder2D(); + virtual ~ShapeBinder2D(); + + const char* getViewProviderName(void) const { + return "PartDesignGui::ViewProviderShapeBinder"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace PartDesign + + +#endif // PARTDESIGN_DATUMSHAPE_H diff --git a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp index a8fe9a7db..fbce447ff 100644 --- a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp +++ b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp @@ -60,6 +60,7 @@ #include "ViewProviderThickness.h" #include "ViewProviderPipe.h" #include "ViewProviderLoft.h" +#include "ViewProviderShapeBinder.h" // use a different name to CreateCommand() void CreatePartDesignCommands(void); @@ -144,6 +145,7 @@ PyMODINIT_FUNC initPartDesignGui() PartDesignGui::ViewProviderDatumLine ::init(); PartDesignGui::ViewProviderDatumPlane ::init(); PartDesignGui::ViewProviderDatumCoordinateSystem::init(); + PartDesignGui::ViewProviderShapeBinder ::init(); PartDesignGui::ViewProviderBoolean ::init(); PartDesignGui::ViewProviderAddSub ::init(); PartDesignGui::ViewProviderPrimitive ::init(); diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index b6869b2f0..b161b7603 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -133,6 +133,8 @@ SET(PartDesignGuiViewProvider_SRCS ViewProviderDatumPlane.h ViewProviderDatumCS.cpp ViewProviderDatumCS.h + ViewProviderShapeBinder.h + ViewProviderShapeBinder.cpp ViewProviderBoolean.cpp ViewProviderBoolean.h ViewProviderAddSub.cpp diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index aeb1bedf6..c6e28e435 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -667,7 +667,7 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, // If there is more than one selection/possibility, show dialog and let user pick sketch if ((bNoSketchWasSelected && validSketches > 1) || (!bNoSketchWasSelected && sketches.size() > 1) || - ext ) { + (!bNoSketchWasSelected && ext) ) { Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); @@ -689,7 +689,7 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, Gui::Selection().clearSelection(); pickDlg = new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker); - if(ext) + if(!bNoSketchWasSelected && ext) pickDlg->showExternal(true); Gui::Control().showDialog(pickDlg); diff --git a/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp index 0ad654aac..f49b1ff97 100644 --- a/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp +++ b/src/Mod/PartDesign/Gui/TaskFeaturePick.cpp @@ -45,6 +45,11 @@ #include "ui_TaskFeaturePick.h" #include "TaskFeaturePick.h" +#include +#include +#include +#include +#include using namespace PartDesignGui; @@ -266,50 +271,83 @@ std::vector TaskFeaturePick::buildFeatures() { } App::DocumentObject* TaskFeaturePick::makeCopy(App::DocumentObject* obj, bool independent) { + App::DocumentObject* copy = nullptr; + if(independent) { + + //we do know that the created instance is a document object, as obj is one. But we do not know which + //exact type + auto name = std::string("Copy") + std::string(obj->getNameInDocument()); + copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str()); - //we do know that the created instance is a document object, as obj is one. But we do not know which - //exact type - auto name = std::string("Copy") + std::string(obj->getNameInDocument()); - auto copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str()); - - if(copy) { //copy over all properties std::vector props; std::vector cprops; obj->getPropertyList(props); - copy->getPropertyList(cprops); - try{ - auto it = cprops.begin(); - for( App::Property* prop : props ) { - - //independent copys dont have links and are not attached - if(independent && ( - prop->getTypeId() == App::PropertyLink::getClassTypeId() || - prop->getTypeId() == App::PropertyLinkList::getClassTypeId() || - prop->getTypeId() == App::PropertyLinkSub::getClassTypeId() || - prop->getTypeId() == App::PropertyLinkSubList::getClassTypeId()|| - ( prop->getGroup() && strcmp(prop->getGroup(),"Attachment")==0) )) { - - ++it; - continue; - } - - App::Property* cprop = *it++; - - if( strcmp(prop->getName(), "Label") == 0 ) { - static_cast(cprop)->setValue("wuhahahahah"); - continue; - } - - cprop->Paste(*prop); - } - } - catch(const Base::Exception& e) { - - Base::Console().Message("Exception: %s\n", e.what()); + copy->getPropertyList(cprops); + + auto it = cprops.begin(); + for( App::Property* prop : props ) { + + //independent copys dont have links and are not attached + if(independent && ( + prop->getTypeId() == App::PropertyLink::getClassTypeId() || + prop->getTypeId() == App::PropertyLinkList::getClassTypeId() || + prop->getTypeId() == App::PropertyLinkSub::getClassTypeId() || + prop->getTypeId() == App::PropertyLinkSubList::getClassTypeId()|| + ( prop->getGroup() && strcmp(prop->getGroup(),"Attachment")==0) )) { + + ++it; + continue; + } + + App::Property* cprop = *it++; + + if( strcmp(prop->getName(), "Label") == 0 ) { + static_cast(cprop)->setValue(name.c_str()); + continue; + } + + cprop->Paste(*prop); } } - + else { + + auto name = std::string("Reference") + std::string(obj->getNameInDocument()); + + // TODO Replace it with commands (2015-09-11, Fat-Zer) + if(obj->isDerivedFrom(Part::Datum::getClassTypeId())) { + copy = App::GetApplication().getActiveDocument()->addObject( + obj->getClassTypeId().getName(), name.c_str() ); + + //we need to reference the individual datums and make again datums. This is important as + //datum adjust their size dependend on the part size, hence simply copying the shape is + //not enough + Part::Datum *datumCopy = static_cast(copy); + datumCopy->Support.setValue(obj, ""); + + if(obj->getTypeId() == PartDesign::Point::getClassTypeId()) { + datumCopy->MapMode.setValue(mm0Vertex); + } + else if(obj->getTypeId() == PartDesign::Line::getClassTypeId()) { + datumCopy->MapMode.setValue(mm1TwoPoints); + } + else if(obj->getTypeId() == PartDesign::Plane::getClassTypeId()) { + datumCopy->MapMode.setValue(mmFlatFace); + } + } + else if(obj->isDerivedFrom(Part::Part2DObject::getClassTypeId()) || + obj->getTypeId() == PartDesign::ShapeBinder2D::getClassTypeId()) { + copy = App::GetApplication().getActiveDocument()->addObject("PartDesign::ShapeBinder2D", name.c_str()); + static_cast(copy)->Support.setValue(obj, ""); + } + else if(obj->getTypeId() == PartDesign::ShapeBinder::getClassTypeId() || + obj->isDerivedFrom(Part::Feature::getClassTypeId())) { + + copy = App::GetApplication().getActiveDocument()->addObject("PartDesign::ShapeBinder", name.c_str()); + static_cast(copy)->Support.setValue(obj, ""); + } + } + return copy; } diff --git a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp new file mode 100644 index 000000000..3cf6b5a80 --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +#endif + +#include + +#include "ViewProviderShapeBinder.h" + +using namespace PartDesignGui; + +PROPERTY_SOURCE(PartDesignGui::ViewProviderShapeBinder,PartGui::ViewProviderPart) + +ViewProviderShapeBinder::ViewProviderShapeBinder() +{ + sPixmap = "PartDesign_ShapeBinder.svg"; +} + +ViewProviderShapeBinder::~ViewProviderShapeBinder() +{ + +} + +bool ViewProviderShapeBinder::setEdit(int ModNum) { + return true;//PartGui::ViewProviderPartExt::setEdit(ModNum); +} + +void ViewProviderShapeBinder::unsetEdit(int ModNum) { + return;//PartGui::ViewProviderPartExt::unsetEdit(ModNum); +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h new file mode 100644 index 000000000..c9ef9c31c --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef PARTGUI_ViewProviderShapeBinder_H +#define PARTGUI_ViewProviderShapeBinder_H + +#include + +namespace PartDesignGui { + +// TODO may be derive from something else e.g. ViewProviderGeometryObject (2015-09-11, Fat-Zer) +class PartDesignGuiExport ViewProviderShapeBinder : public PartGui::ViewProviderPart +{ + PROPERTY_HEADER(PartDesignGui::ViewProviderShapeBinder); + +public: + /// Constructor + ViewProviderShapeBinder(); + virtual ~ViewProviderShapeBinder(); + +protected: + virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); + +}; + +} // namespace PartDesignGui + + +#endif // PARTGUI_ViewProviderShapeBinder_H