From a81639afe17801ca9942eb578ccde5bff3920100 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 13 Jul 2013 15:05:13 +0200 Subject: [PATCH] Add a parametric compound command --- src/Mod/Part/App/AppPart.cpp | 2 + src/Mod/Part/App/CMakeLists.txt | 2 + src/Mod/Part/App/FeatureCompound.cpp | 99 +++++++++++++++++++++++ src/Mod/Part/App/FeatureCompound.h | 59 ++++++++++++++ src/Mod/Part/Gui/AppPartGui.cpp | 2 + src/Mod/Part/Gui/CMakeLists.txt | 2 + src/Mod/Part/Gui/Command.cpp | 50 ++++++++++++ src/Mod/Part/Gui/ViewProviderCompound.cpp | 91 +++++++++++++++++++++ src/Mod/Part/Gui/ViewProviderCompound.h | 49 +++++++++++ src/Mod/Part/Gui/Workbench.cpp | 9 ++- 10 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 src/Mod/Part/App/FeatureCompound.cpp create mode 100644 src/Mod/Part/App/FeatureCompound.h create mode 100644 src/Mod/Part/Gui/ViewProviderCompound.cpp create mode 100644 src/Mod/Part/Gui/ViewProviderCompound.h diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index 3244d0b43..cd3bb4149 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -40,6 +40,7 @@ #include "FeaturePartPolygon.h" #include "FeatureGeometrySet.h" #include "FeatureChamfer.h" +#include "FeatureCompound.h" #include "FeatureExtrusion.h" #include "FeatureFillet.h" #include "FeatureMirroring.h" @@ -173,6 +174,7 @@ void PartExport initPart() Part::FilletBase ::init(); Part::Fillet ::init(); Part::Chamfer ::init(); + Part::Compound ::init(); Part::Extrusion ::init(); Part::Revolution ::init(); Part::Mirroring ::init(); diff --git a/src/Mod/Part/App/CMakeLists.txt b/src/Mod/Part/App/CMakeLists.txt index 391bb6023..31eb00219 100644 --- a/src/Mod/Part/App/CMakeLists.txt +++ b/src/Mod/Part/App/CMakeLists.txt @@ -102,6 +102,8 @@ SET(Features_SRCS FeaturePartSection.h FeatureChamfer.cpp FeatureChamfer.h + FeatureCompound.cpp + FeatureCompound.h FeatureExtrusion.cpp FeatureExtrusion.h FeatureFillet.cpp diff --git a/src/Mod/Part/App/FeatureCompound.cpp b/src/Mod/Part/App/FeatureCompound.cpp new file mode 100644 index 000000000..7715b5fb5 --- /dev/null +++ b/src/Mod/Part/App/FeatureCompound.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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 +#endif + + +#include "FeatureCompound.h" + + +using namespace Part; + + +PROPERTY_SOURCE(Part::Compound, Part::Feature) + +Compound::Compound() +{ + ADD_PROPERTY(Links,(0)); + Links.setSize(0); +} + +Compound::~Compound() +{ +} + +short Compound::mustExecute() const +{ + if (Links.isTouched()) + return 1; + return 0; +} + +App::DocumentObjectExecReturn *Compound::execute(void) +{ + try { + std::vector history; + int countFaces = 0; + + BRep_Builder builder; + TopoDS_Compound comp; + builder.MakeCompound(comp); + + const std::vector& links = Links.getValues(); + for (std::vector::const_iterator it = links.begin(); it != links.end(); ++it) { + if (*it && (*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* fea = static_cast(*it); + const TopoDS_Shape& sh = fea->Shape.getValue(); + if (!sh.IsNull()) { + builder.Add(comp, sh); + TopTools_IndexedMapOfShape faceMap; + TopExp::MapShapes(sh, TopAbs_FACE, faceMap); + ShapeHistory hist; + hist.type = TopAbs_FACE; + for (int i=1; i<=faceMap.Extent(); i++) { + hist.shapeMap[i-1].push_back(countFaces++); + } + history.push_back(hist); + } + } + } + + this->Shape.setValue(comp); + PropertyShapeHistory prop; + prop.setContainer(this); + prop.setValues(history); + return App::DocumentObject::StdReturn; + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + return new App::DocumentObjectExecReturn(e->GetMessageString()); + } +} + diff --git a/src/Mod/Part/App/FeatureCompound.h b/src/Mod/Part/App/FeatureCompound.h new file mode 100644 index 000000000..1caaeabc9 --- /dev/null +++ b/src/Mod/Part/App/FeatureCompound.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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 PART_FEATURECOMPOUND_H +#define PART_FEATURECOMPOUND_H + +#include +#include "PartFeature.h" + +namespace Part +{ + +class Compound : public Part::Feature +{ + PROPERTY_HEADER(Part::Compound); + +public: + Compound(); + virtual ~Compound(); + + App::PropertyLinkList Links; + + /** @name methods override feature */ + //@{ + short mustExecute() const; + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "PartGui::ViewProviderCompound"; + } + //@} +}; + +} //namespace Part + + +#endif // PART_FEATURECOMPOUND_H + diff --git a/src/Mod/Part/Gui/AppPartGui.cpp b/src/Mod/Part/Gui/AppPartGui.cpp index 8cef48308..6c2c04ed3 100644 --- a/src/Mod/Part/Gui/AppPartGui.cpp +++ b/src/Mod/Part/Gui/AppPartGui.cpp @@ -37,6 +37,7 @@ #include "ViewProvider2DObject.h" #include "ViewProviderMirror.h" #include "ViewProviderBoolean.h" +#include "ViewProviderCompound.h" #include "ViewProviderCircleParametric.h" #include "ViewProviderLineParametric.h" #include "ViewProviderPointParametric.h" @@ -125,6 +126,7 @@ void PartGuiExport initPartGui() PartGui::ViewProviderBoolean ::init(); PartGui::ViewProviderMultiFuse ::init(); PartGui::ViewProviderMultiCommon ::init(); + PartGui::ViewProviderCompound ::init(); PartGui::ViewProviderCircleParametric ::init(); PartGui::ViewProviderLineParametric ::init(); PartGui::ViewProviderPointParametric ::init(); diff --git a/src/Mod/Part/Gui/CMakeLists.txt b/src/Mod/Part/Gui/CMakeLists.txt index 5da5d56f7..ef5922aa6 100644 --- a/src/Mod/Part/Gui/CMakeLists.txt +++ b/src/Mod/Part/Gui/CMakeLists.txt @@ -143,6 +143,8 @@ SET(PartGui_SRCS ViewProviderReference.h ViewProviderBox.cpp ViewProviderBox.h + ViewProviderCompound.cpp + ViewProviderCompound.h ViewProviderCircleParametric.cpp ViewProviderCircleParametric.h ViewProviderLineParametric.cpp diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index b23bca966..7b33b1be8 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -379,6 +379,55 @@ bool CmdPartFuse::isActive(void) return getSelection().countObjectsOfType(Part::Feature::getClassTypeId())>=2; } +//=========================================================================== +// Part_Compound +//=========================================================================== +DEF_STD_CMD_A(CmdPartCompound); + +CmdPartCompound::CmdPartCompound() + :Command("Part_Compound") +{ + sAppModule = "Part"; + sGroup = QT_TR_NOOP("Part"); + sMenuText = QT_TR_NOOP("Make compound"); + sToolTipText = QT_TR_NOOP("Make a compound of several shapes"); + sWhatsThis = "Part_Compound"; + sStatusTip = sToolTipText; +} + +void CmdPartCompound::activated(int iMsg) +{ + unsigned int n = getSelection().countObjectsOfType(Part::Feature::getClassTypeId()); + if (n < 2) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), + QObject::tr("Select two shapes or more, please.")); + return; + } + + std::string FeatName = getUniqueObjectName("Compound"); + + std::vector Sel = getSelection().getSelection(); + std::stringstream str; + std::vector tempSelNames; + str << "App.activeDocument()." << FeatName << ".Links = ["; + for (std::vector::iterator it = Sel.begin(); it != Sel.end(); ++it){ + str << "App.activeDocument()." << it->FeatName << ","; + tempSelNames.push_back(it->FeatName); + } + str << "]"; + + openCommand("Compound"); + doCommand(Doc,"App.activeDocument().addObject(\"Part::Compound\",\"%s\")",FeatName.c_str()); + runCommand(Doc,str.str().c_str()); + updateActive(); + commitCommand(); +} + +bool CmdPartCompound::isActive(void) +{ + return getSelection().countObjectsOfType(Part::Feature::getClassTypeId())>=2; +} + //=========================================================================== // Part_Section //=========================================================================== @@ -1416,6 +1465,7 @@ void CreatePartCommands(void) rcCmdMgr.addCommand(new CmdPartCommon()); rcCmdMgr.addCommand(new CmdPartCut()); rcCmdMgr.addCommand(new CmdPartFuse()); + rcCmdMgr.addCommand(new CmdPartCompound()); rcCmdMgr.addCommand(new CmdPartSection()); //rcCmdMgr.addCommand(new CmdPartBox2()); //rcCmdMgr.addCommand(new CmdPartBox3()); diff --git a/src/Mod/Part/Gui/ViewProviderCompound.cpp b/src/Mod/Part/Gui/ViewProviderCompound.cpp new file mode 100644 index 000000000..a9bc1727c --- /dev/null +++ b/src/Mod/Part/Gui/ViewProviderCompound.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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 "ViewProviderCompound.h" +#include +#include + + +using namespace PartGui; + +PROPERTY_SOURCE(PartGui::ViewProviderCompound,PartGui::ViewProviderPart) + +ViewProviderCompound::ViewProviderCompound() +{ +} + +ViewProviderCompound::~ViewProviderCompound() +{ +} + +void ViewProviderCompound::updateData(const App::Property* prop) +{ + PartGui::ViewProviderPart::updateData(prop); + if (prop->getTypeId() == Part::PropertyShapeHistory::getClassTypeId()) { + const std::vector& hist = static_cast + (prop)->getValues(); + Part::Compound* objComp = dynamic_cast(getObject()); + std::vector sources = objComp->Links.getValues(); + if (hist.size() != sources.size()) + return; + + const TopoDS_Shape& compShape = objComp->Shape.getValue(); + TopTools_IndexedMapOfShape compMap; + TopExp::MapShapes(compShape, TopAbs_FACE, compMap); + + std::vector compCol; + compCol.resize(compMap.Extent(), this->ShapeColor.getValue()); + + bool setColor=false; + int index=0; + for (std::vector::iterator it = sources.begin(); it != sources.end(); ++it, ++index) { + Part::Feature* objBase = dynamic_cast(*it); + const TopoDS_Shape& baseShape = objBase->Shape.getValue(); + + TopTools_IndexedMapOfShape baseMap; + TopExp::MapShapes(baseShape, TopAbs_FACE, baseMap); + + Gui::ViewProvider* vpBase = Gui::Application::Instance->getViewProvider(objBase); + std::vector baseCol = static_cast(vpBase)->DiffuseColor.getValues(); + if (baseCol.size() == baseMap.Extent()) { + applyColor(hist[index], baseCol, compCol); + setColor = true; + } + else if (!baseCol.empty() && baseCol[0] != this->ShapeColor.getValue()) { + baseCol.resize(baseMap.Extent(), baseCol[0]); + applyColor(hist[index], baseCol, compCol); + setColor = true; + } + } + + if (setColor) + this->DiffuseColor.setValues(compCol); + } +} diff --git a/src/Mod/Part/Gui/ViewProviderCompound.h b/src/Mod/Part/Gui/ViewProviderCompound.h new file mode 100644 index 000000000..d648f9864 --- /dev/null +++ b/src/Mod/Part/Gui/ViewProviderCompound.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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_VIEWPROVIDERCOMPOUND_H +#define PARTGUI_VIEWPROVIDERCOMPOUND_H + +#include "ViewProvider.h" + + +namespace PartGui { + +class PartGuiExport ViewProviderCompound : public ViewProviderPart +{ + PROPERTY_HEADER(PartGui::ViewProviderCompound); + +public: + /// constructor + ViewProviderCompound(); + /// destructor + virtual ~ViewProviderCompound(); + +protected: + void updateData(const App::Property*); +}; + +} // namespace PartGui + + +#endif // PARTGUI_VIEWPROVIDERCOMPOUND_H diff --git a/src/Mod/Part/Gui/Workbench.cpp b/src/Mod/Part/Gui/Workbench.cpp index 9d95ac40a..e827fe420 100644 --- a/src/Mod/Part/Gui/Workbench.cpp +++ b/src/Mod/Part/Gui/Workbench.cpp @@ -63,14 +63,19 @@ Gui::MenuItem* Workbench::setupMenuBar() const *prim << "Part_Box" << "Part_Cylinder" << "Part_Sphere" << "Part_Cone" << "Part_Torus"; + Gui::MenuItem* bop = new Gui::MenuItem; + bop->setCommand("Boolean"); + *bop << "Part_Boolean" << "Part_Cut" << "Part_Fuse" << "Part_Common"; + Gui::MenuItem* part = new Gui::MenuItem; root->insertItem(item, part); part->setCommand("&Part"); *part << "Part_Import" << "Part_Export" << "Separator"; *part << prim << "Part_Primitives" << "Part_Builder" << "Separator" << "Part_ShapeFromMesh" << "Part_MakeSolid" << "Part_ReverseShape" - << "Part_SimpleCopy" << "Part_RefineShape" << "Part_CheckGeometry" << "Separator" - << "Part_Boolean" << "Part_CrossSections" << "Part_Extrude" + << "Part_SimpleCopy" << "Part_RefineShape" << "Part_CheckGeometry" + << "Separator" << bop << "Separator" + << "Part_CrossSections" << "Part_Compound" << "Part_Extrude" << "Part_Revolve" << "Part_Mirror" << "Part_Fillet" << "Part_Chamfer" << "Part_RuledSurface" << "Part_Loft" << "Part_Sweep" << "Part_Offset" << "Part_Thickness";