// SPDX-License-Identifier: LGPL-2.1-or-later /*************************************************************************** * Copyright (c) 2014 Yorik van Havre * * * * 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 #include #include #include #include #include #include #include #include // Path Area // ##################################################################################################### DEF_STD_CMD_A(CmdPathArea) CmdPathArea::CmdPathArea() : Command("CAM_Area") { sAppModule = "Path"; sGroup = QT_TR_NOOP("CAM"); sMenuText = QT_TR_NOOP("Area"); sToolTipText = QT_TR_NOOP("Creates a feature area from the selected objects"); sWhatsThis = "CAM_Area"; sStatusTip = sToolTipText; sPixmap = "CAM_Area"; } void CmdPathArea::activated(int iMsg) { Q_UNUSED(iMsg); std::list cmds; std::ostringstream sources; std::string areaName; bool addView = true; for (const Gui::SelectionObject& selObj : getSelection().getSelectionEx(nullptr, Part::Feature::getClassTypeId())) { const Part::Feature* pcObj = static_cast(selObj.getObject()); const std::vector& subnames = selObj.getSubNames(); if (addView && !areaName.empty()) { addView = false; } if (subnames.empty()) { if (addView && pcObj->isDerivedFrom()) { areaName = pcObj->getNameInDocument(); } sources << "FreeCAD.activeDocument()." << pcObj->getNameInDocument() << ","; continue; } for (const std::string& name : subnames) { if (name.compare(0, 4, "Face") && name.compare(0, 4, "Edge")) { Base::Console().error("Selected shape is not 2D\n"); return; } std::ostringstream subname; subname << pcObj->getNameInDocument() << '_' << name; std::string sub_fname = getUniqueObjectName(subname.str().c_str()); std::ostringstream cmd; cmd << "FreeCAD.activeDocument().addObject('Part::Feature','" << sub_fname << "').Shape = PathCommands.findShape(FreeCAD.activeDocument()." << pcObj->getNameInDocument() << ".Shape,'" << name << "'"; if (!name.compare(0, 4, "Edge")) { cmd << ",'Wires'"; } cmd << ')'; cmds.push_back(cmd.str()); sources << "FreeCAD.activeDocument()." << sub_fname << ","; } } if (addView && !areaName.empty()) { std::string FeatName = getUniqueObjectName("FeatureAreaView"); openCommand(QT_TRANSLATE_NOOP("Command", "Create Path Area View")); doCommand( Doc, "FreeCAD.activeDocument().addObject('Path::FeatureAreaView','%s')", FeatName.c_str() ); doCommand( Doc, "FreeCAD.activeDocument().%s.Source = FreeCAD.activeDocument().%s", FeatName.c_str(), areaName.c_str() ); commitCommand(); updateActive(); return; } std::string FeatName = getUniqueObjectName("FeatureArea"); openCommand(QT_TRANSLATE_NOOP("Command", "Create Path Area")); doCommand(Doc, "import PathCommands"); for (const std::string& cmd : cmds) { doCommand(Doc, "%s", cmd.c_str()); } doCommand(Doc, "FreeCAD.activeDocument().addObject('Path::FeatureArea','%s')", FeatName.c_str()); doCommand( Doc, "FreeCAD.activeDocument().%s.Sources = [ %s ]", FeatName.c_str(), sources.str().c_str() ); commitCommand(); updateActive(); } bool CmdPathArea::isActive() { return hasActiveDocument(); } DEF_STD_CMD_A(CmdPathAreaWorkplane) CmdPathAreaWorkplane::CmdPathAreaWorkplane() : Command("CAM_Area_Workplane") { sAppModule = "Path"; sGroup = QT_TR_NOOP("CAM"); sMenuText = QT_TR_NOOP("Area Workplane"); sToolTipText = QT_TR_NOOP("Selects a workplane for a feature area"); sWhatsThis = "CAM_Area_Workplane"; sStatusTip = sToolTipText; sPixmap = "CAM_Area_Workplane"; } void CmdPathAreaWorkplane::activated(int iMsg) { Q_UNUSED(iMsg); std::string areaName; std::string planeSubname; std::string planeName; for (Gui::SelectionObject& selObj : getSelection().getSelectionEx(nullptr, Part::Feature::getClassTypeId())) { const std::vector& subnames = selObj.getSubNames(); if (subnames.size() > 1) { Base::Console().error("Select one sub shape object for plane only\n"); return; } const Part::Feature* pcObj = static_cast(selObj.getObject()); if (subnames.empty()) { if (pcObj->isDerivedFrom()) { if (!areaName.empty()) { Base::Console().error("Select one feature area only\n"); return; } areaName = pcObj->getNameInDocument(); continue; } for (TopExp_Explorer it(pcObj->Shape.getShape().getShape(), TopAbs_SHELL); it.More(); it.Next()) { Base::Console().error("Selected shape is not 2D\n"); return; } } if (!planeName.empty()) { Base::Console().error("Select one shape object for plane only\n"); return; } else { planeSubname = planeName = pcObj->getNameInDocument(); planeSubname += ".Shape"; } for (const std::string& name : subnames) { if (name.compare(0, 4, "Face") && name.compare(0, 4, "Edge")) { Base::Console().error("Selected shape is not 2D\n"); return; } std::ostringstream subname; subname << planeSubname << ",'" << name << "','Wires'"; planeSubname = subname.str(); } } if (areaName.empty()) { Base::Console().error("Please select one FeatureArea\n"); return; } if (planeName.empty()) { Base::Console().error("Please select one shape object\n"); return; } openCommand(QT_TRANSLATE_NOOP("Command", "Select Workplane for Path Area")); doCommand(Doc, "import PathCommands"); doCommand( Doc, "FreeCAD.activeDocument().%s.WorkPlane = PathCommands.findShape(" "FreeCAD.activeDocument().%s)", areaName.c_str(), planeSubname.c_str() ); doCommand(Doc, "FreeCAD.activeDocument().%s.ViewObject.Visibility = True", areaName.c_str()); commitCommand(); updateActive(); } bool CmdPathAreaWorkplane::isActive() { return !getSelection().getSelectionEx(nullptr, Path::FeatureArea::getClassTypeId()).empty(); } // Path compound // ##################################################################################################### DEF_STD_CMD_A(CmdPathCompound) CmdPathCompound::CmdPathCompound() : Command("CAM_Compound") { sAppModule = "Path"; sGroup = QT_TR_NOOP("CAM"); sMenuText = QT_TR_NOOP("Compound"); sToolTipText = QT_TR_NOOP("Creates a compound from the selected toolpaths"); sWhatsThis = "CAM_Compound"; sStatusTip = sToolTipText; sPixmap = "CAM_Compound"; } void CmdPathCompound::activated(int iMsg) { Q_UNUSED(iMsg); std::vector Sel = getSelection().getSelection(); if (!Sel.empty()) { std::ostringstream cmd; cmd << "["; Path::Feature* pcPathObject; for (std::vector::const_iterator it = Sel.begin(); it != Sel.end(); ++it) { if ((*it).pObject->isDerivedFrom()) { pcPathObject = static_cast((*it).pObject); cmd << "FreeCAD.activeDocument()." << pcPathObject->getNameInDocument() << ","; } else { Base::Console().error( "Only path objects must be selected before running this command\n" ); return; } } cmd << "]"; std::string FeatName = getUniqueObjectName("PathCompound"); openCommand(QT_TRANSLATE_NOOP("Command", "Create Path Compound")); doCommand( Doc, "FreeCAD.activeDocument().addObject('Path::FeatureCompound','%s')", FeatName.c_str() ); doCommand(Doc, "FreeCAD.activeDocument().%s.Group = %s", FeatName.c_str(), cmd.str().c_str()); commitCommand(); updateActive(); } else { Base::Console().error("At least one path object must be selected\n"); return; } } bool CmdPathCompound::isActive() { return hasActiveDocument(); } // Path Shape // ##################################################################################################### DEF_STD_CMD_A(CmdPathShape) CmdPathShape::CmdPathShape() : Command("CAM_Shape") { sAppModule = "Path"; sGroup = QT_TR_NOOP("CAM"); sMenuText = QT_TR_NOOP("From Shape"); sToolTipText = QT_TR_NOOP("Creates a toolpath from a selected shape"); sWhatsThis = "CAM_Shape"; sStatusTip = sToolTipText; sPixmap = "CAM_Shape"; } void CmdPathShape::activated(int iMsg) { Q_UNUSED(iMsg); std::list cmds; std::ostringstream sources; for (const Gui::SelectionObject& selObj : getSelection().getSelectionEx(nullptr, Part::Feature::getClassTypeId())) { const Part::Feature* pcObj = static_cast(selObj.getObject()); const std::vector& subnames = selObj.getSubNames(); if (subnames.empty()) { sources << "FreeCAD.activeDocument()." << pcObj->getNameInDocument() << ","; continue; } for (const std::string& name : subnames) { if (name.compare(0, 4, "Face") && name.compare(0, 4, "Edge")) { Base::Console() .warning("Ignored shape %s %s\n", pcObj->getNameInDocument(), name.c_str()); continue; } std::ostringstream subname; subname << pcObj->getNameInDocument() << '_' << name; std::string sub_fname = getUniqueObjectName(subname.str().c_str()); std::ostringstream cmd; cmd << "FreeCAD.activeDocument().addObject('Part::Feature','" << sub_fname << "').Shape = PathCommands.findShape(FreeCAD.activeDocument()." << pcObj->getNameInDocument() << ".Shape,'" << name << "'"; if (!name.compare(0, 4, "Edge")) { cmd << ",'Wires'"; } cmd << ')'; cmds.push_back(cmd.str()); sources << "FreeCAD.activeDocument()." << sub_fname << ","; } } std::string FeatName = getUniqueObjectName("PathShape"); openCommand(QT_TRANSLATE_NOOP("Command", "Create Path Shape")); doCommand(Doc, "import PathCommands"); for (const std::string& cmd : cmds) { doCommand(Doc, "%s", cmd.c_str()); } doCommand(Doc, "FreeCAD.activeDocument().addObject('Path::FeatureShape','%s')", FeatName.c_str()); doCommand( Doc, "FreeCAD.activeDocument().%s.Sources = [ %s ]", FeatName.c_str(), sources.str().c_str() ); commitCommand(); updateActive(); } bool CmdPathShape::isActive() { return hasActiveDocument(); } void CreatePathCommands() { Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager(); rcCmdMgr.addCommand(new CmdPathCompound()); rcCmdMgr.addCommand(new CmdPathShape()); rcCmdMgr.addCommand(new CmdPathArea()); rcCmdMgr.addCommand(new CmdPathAreaWorkplane()); }